6 #include "run-command.h"
7 #include "vcs-svn/svndump.h"
9 #include "argv-array.h"
11 static const char *url
;
12 static int dump_from_file
;
13 static const char *private_ref
;
14 static const char *remote_ref
= "refs/heads/master";
16 static int cmd_capabilities(const char *line
);
17 static int cmd_import(const char *line
);
18 static int cmd_list(const char *line
);
20 typedef int (*input_command_handler
)(const char *);
21 struct input_command_entry
{
23 input_command_handler fn
;
24 unsigned char batchable
; /* whether the command starts or is part of a batch */
27 static const struct input_command_entry input_command_list
[] = {
28 { "capabilities", cmd_capabilities
, 0 },
29 { "import", cmd_import
, 1 },
30 { "list", cmd_list
, 0 },
34 static int cmd_capabilities(const char *line
)
37 printf("bidi-import\n");
38 printf("refspec %s:%s\n\n", remote_ref
, private_ref
);
43 static void terminate_batch(void)
45 /* terminate a current batch's fast-import stream */
50 static int cmd_import(const char *line
)
54 unsigned int startrev
= 0;
55 struct argv_array svndump_argv
= ARGV_ARRAY_INIT
;
56 struct child_process svndump_proc
;
59 dumpin_fd
= open(url
, O_RDONLY
);
61 die_errno("Couldn't open svn dump file %s.", url
);
63 memset(&svndump_proc
, 0, sizeof(struct child_process
));
64 svndump_proc
.out
= -1;
65 argv_array_push(&svndump_argv
, "svnrdump");
66 argv_array_push(&svndump_argv
, "dump");
67 argv_array_push(&svndump_argv
, url
);
68 argv_array_pushf(&svndump_argv
, "-r%u:HEAD", startrev
);
69 svndump_proc
.argv
= svndump_argv
.argv
;
71 code
= start_command(&svndump_proc
);
73 die("Unable to start %s, code %d", svndump_proc
.argv
[0], code
);
74 dumpin_fd
= svndump_proc
.out
;
76 svndump_init_fd(dumpin_fd
, STDIN_FILENO
);
77 svndump_read(url
, private_ref
);
82 if (!dump_from_file
) {
83 code
= finish_command(&svndump_proc
);
85 warning("%s, returned %d", svndump_proc
.argv
[0], code
);
86 argv_array_clear(&svndump_argv
);
92 static int cmd_list(const char *line
)
94 printf("? %s\n\n", remote_ref
);
99 static int do_command(struct strbuf
*line
)
101 const struct input_command_entry
*p
= input_command_list
;
102 static struct string_list batchlines
= STRING_LIST_INIT_DUP
;
103 static const struct input_command_entry
*batch_cmd
;
105 * commands can be grouped together in a batch.
106 * Batches are ended by \n. If no batch is active the program ends.
107 * During a batch all lines are buffered and passed to the handler function
108 * when the batch is terminated.
110 if (line
->len
== 0) {
112 struct string_list_item
*item
;
113 for_each_string_list_item(item
, &batchlines
)
114 batch_cmd
->fn(item
->string
);
117 string_list_clear(&batchlines
, 0);
118 return 0; /* end of the batch, continue reading other commands. */
120 return 1; /* end of command stream, quit */
123 if (prefixcmp(batch_cmd
->name
, line
->buf
))
124 die("Active %s batch interrupted by %s", batch_cmd
->name
, line
->buf
);
125 /* buffer batch lines */
126 string_list_append(&batchlines
, line
->buf
);
130 for (p
= input_command_list
; p
->name
; p
++) {
131 if (!prefixcmp(line
->buf
, p
->name
) && (strlen(p
->name
) == line
->len
||
132 line
->buf
[strlen(p
->name
)] == ' ')) {
135 string_list_append(&batchlines
, line
->buf
);
138 return p
->fn(line
->buf
);
141 die("Unknown command '%s'\n", line
->buf
);
145 int main(int argc
, const char **argv
)
147 struct strbuf buf
= STRBUF_INIT
, url_sb
= STRBUF_INIT
,
148 private_ref_sb
= STRBUF_INIT
;
149 static struct remote
*remote
;
152 git_extract_argv0_path(argv
[0]);
153 setup_git_directory();
154 if (argc
< 2 || argc
> 3) {
155 usage("git-remote-svn <remote-name> [<url>]");
159 remote
= remote_get(argv
[1]);
160 url_in
= (argc
== 3) ? argv
[2] : remote
->url
[0];
162 if (!prefixcmp(url_in
, "file://")) {
164 url
= url_decode(url_in
+ sizeof("file://")-1);
167 end_url_with_slash(&url_sb
, url_in
);
171 strbuf_addf(&private_ref_sb
, "refs/svn/%s/master", remote
->name
);
172 private_ref
= private_ref_sb
.buf
;
175 if (strbuf_getline(&buf
, stdin
, '\n') == EOF
) {
177 die("Error reading command stream");
179 die("Unexpected end of command stream");
181 if (do_command(&buf
))
186 strbuf_release(&buf
);
187 strbuf_release(&url_sb
);
188 strbuf_release(&private_ref_sb
);