7 #include "run-command.h"
9 static struct remote
*remote
;
10 static const char *url
;
11 static struct walker
*walker
;
16 unsigned progress
: 1,
20 static struct options options
;
22 static void init_walker(void)
25 walker
= get_http_walker(url
, remote
);
28 static int set_option(const char *name
, const char *value
)
30 if (!strcmp(name
, "verbosity")) {
32 int v
= strtol(value
, &end
, 10);
33 if (value
== end
|| *end
)
35 options
.verbosity
= v
;
38 else if (!strcmp(name
, "progress")) {
39 if (!strcmp(value
, "true"))
41 else if (!strcmp(value
, "false"))
45 return 1 /* TODO implement later */;
47 else if (!strcmp(name
, "depth")) {
49 unsigned long v
= strtoul(value
, &end
, 10);
50 if (value
== end
|| *end
)
53 return 1 /* TODO implement later */;
55 else if (!strcmp(name
, "followtags")) {
56 if (!strcmp(value
, "true"))
57 options
.followtags
= 1;
58 else if (!strcmp(value
, "false"))
59 options
.followtags
= 0;
62 return 1 /* TODO implement later */;
64 else if (!strcmp(name
, "dry-run")) {
65 if (!strcmp(value
, "true"))
67 else if (!strcmp(value
, "false"))
74 return 1 /* unsupported */;
78 static struct ref
*get_refs(void)
80 struct strbuf buffer
= STRBUF_INIT
;
81 char *data
, *start
, *mid
;
87 struct ref
*refs
= NULL
;
88 struct ref
*ref
= NULL
;
89 struct ref
*last_ref
= NULL
;
91 refs_url
= xmalloc(strlen(url
) + 11);
92 sprintf(refs_url
, "%s/info/refs", url
);
95 http_ret
= http_get_strbuf(refs_url
, &buffer
, HTTP_NO_CACHE
);
99 case HTTP_MISSING_TARGET
:
100 die("%s not found: did you run git update-server-info on the"
101 " server?", refs_url
);
103 http_error(refs_url
, http_ret
);
104 die("HTTP request failed");
110 while (i
< buffer
.len
) {
116 if (data
[i
] == '\n') {
119 ref
= xmalloc(sizeof(struct ref
) +
120 strlen(ref_name
) + 1);
121 memset(ref
, 0, sizeof(struct ref
));
122 strcpy(ref
->name
, ref_name
);
123 get_sha1_hex(start
, ref
->old_sha1
);
127 last_ref
->next
= ref
;
134 strbuf_release(&buffer
);
136 ref
= alloc_ref("HEAD");
137 if (!walker
->fetch_ref(walker
, ref
) &&
138 !resolve_remote_symref(ref
, refs
)) {
145 strbuf_release(&buffer
);
150 static void output_refs(struct ref
*refs
)
153 for (posn
= refs
; posn
; posn
= posn
->next
) {
155 printf("@%s %s\n", posn
->symref
, posn
->name
);
157 printf("%s %s\n", sha1_to_hex(posn
->old_sha1
), posn
->name
);
164 static int fetch_dumb(int nr_heads
, struct ref
**to_fetch
)
166 char **targets
= xmalloc(nr_heads
* sizeof(char*));
169 for (i
= 0; i
< nr_heads
; i
++)
170 targets
[i
] = xstrdup(sha1_to_hex(to_fetch
[i
]->old_sha1
));
174 walker
->get_tree
= 1;
175 walker
->get_history
= 1;
176 walker
->get_verbosely
= options
.verbosity
>= 3;
177 walker
->get_recover
= 0;
178 ret
= walker_fetch(walker
, nr_heads
, targets
, NULL
, NULL
);
180 for (i
= 0; i
< nr_heads
; i
++)
184 return ret
? error("Fetch failed.") : 0;
187 static void parse_fetch(struct strbuf
*buf
)
189 struct ref
**to_fetch
= NULL
;
190 struct ref
*list_head
= NULL
;
191 struct ref
**list
= &list_head
;
192 int alloc_heads
= 0, nr_heads
= 0;
195 if (!prefixcmp(buf
->buf
, "fetch ")) {
196 char *p
= buf
->buf
+ strlen("fetch ");
199 unsigned char old_sha1
[20];
201 if (strlen(p
) < 40 || get_sha1_hex(p
, old_sha1
))
202 die("protocol error: expected sha/ref, got %s'", p
);
208 die("protocol error: expected sha/ref, got %s'", p
);
210 ref
= alloc_ref(name
);
211 hashcpy(ref
->old_sha1
, old_sha1
);
216 ALLOC_GROW(to_fetch
, nr_heads
+ 1, alloc_heads
);
217 to_fetch
[nr_heads
++] = ref
;
220 die("http transport does not support %s", buf
->buf
);
223 if (strbuf_getline(buf
, stdin
, '\n') == EOF
)
229 if (fetch_dumb(nr_heads
, to_fetch
))
230 exit(128); /* error already reported */
231 free_refs(list_head
);
239 static int push_dav(int nr_spec
, char **specs
)
241 const char **argv
= xmalloc((10 + nr_spec
) * sizeof(char*));
244 argv
[argc
++] = "http-push";
245 argv
[argc
++] = "--helper-status";
247 argv
[argc
++] = "--dry-run";
248 if (options
.verbosity
> 1)
249 argv
[argc
++] = "--verbose";
251 for (i
= 0; i
< nr_spec
; i
++)
252 argv
[argc
++] = specs
[i
];
255 if (run_command_v_opt(argv
, RUN_GIT_CMD
))
256 die("git-%s failed", argv
[0]);
261 static void parse_push(struct strbuf
*buf
)
264 int alloc_spec
= 0, nr_spec
= 0, i
;
267 if (!prefixcmp(buf
->buf
, "push ")) {
268 ALLOC_GROW(specs
, nr_spec
+ 1, alloc_spec
);
269 specs
[nr_spec
++] = xstrdup(buf
->buf
+ 5);
272 die("http transport does not support %s", buf
->buf
);
275 if (strbuf_getline(buf
, stdin
, '\n') == EOF
)
281 if (push_dav(nr_spec
, specs
))
282 exit(128); /* error already reported */
283 for (i
= 0; i
< nr_spec
; i
++)
291 int main(int argc
, const char **argv
)
293 struct strbuf buf
= STRBUF_INIT
;
295 git_extract_argv0_path(argv
[0]);
296 setup_git_directory();
298 fprintf(stderr
, "Remote needed\n");
302 options
.verbosity
= 1;
303 options
.progress
= !!isatty(2);
305 remote
= remote_get(argv
[1]);
310 url
= remote
->url
[0];
314 if (strbuf_getline(&buf
, stdin
, '\n') == EOF
)
316 if (!prefixcmp(buf
.buf
, "fetch ")) {
319 } else if (!strcmp(buf
.buf
, "list") || !prefixcmp(buf
.buf
, "list ")) {
320 output_refs(get_refs());
322 } else if (!prefixcmp(buf
.buf
, "push ")) {
325 } else if (!prefixcmp(buf
.buf
, "option ")) {
326 char *name
= buf
.buf
+ strlen("option ");
327 char *value
= strchr(name
, ' ');
335 result
= set_option(name
, value
);
339 printf("error invalid value\n");
341 printf("unsupported\n");
344 } else if (!strcmp(buf
.buf
, "capabilities")) {