git-svn: log command fixes
[alt-git.git] / fetch-pack.c
blobe8708aa802b8e09d8044bb99dbccb0fecdb14481
1 #include "cache.h"
2 #include "refs.h"
3 #include "pkt-line.h"
4 #include "commit.h"
5 #include "tag.h"
7 static int keep_pack;
8 static int quiet;
9 static int verbose;
10 static int fetch_all;
11 static const char fetch_pack_usage[] =
12 "git-fetch-pack [--all] [-q] [-v] [-k] [--thin] [--exec=upload-pack] [host:]directory <refs>...";
13 static const char *exec = "git-upload-pack";
15 #define COMPLETE (1U << 0)
16 #define COMMON (1U << 1)
17 #define COMMON_REF (1U << 2)
18 #define SEEN (1U << 3)
19 #define POPPED (1U << 4)
22 * After sending this many "have"s if we do not get any new ACK , we
23 * give up traversing our history.
25 #define MAX_IN_VAIN 256
27 static struct commit_list *rev_list;
28 static int non_common_revs, multi_ack, use_thin_pack, use_sideband;
30 static void rev_list_push(struct commit *commit, int mark)
32 if (!(commit->object.flags & mark)) {
33 commit->object.flags |= mark;
35 if (!(commit->object.parsed))
36 parse_commit(commit);
38 insert_by_date(commit, &rev_list);
40 if (!(commit->object.flags & COMMON))
41 non_common_revs++;
45 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
47 struct object *o = deref_tag(parse_object(sha1), path, 0);
49 if (o && o->type == OBJ_COMMIT)
50 rev_list_push((struct commit *)o, SEEN);
52 return 0;
56 This function marks a rev and its ancestors as common.
57 In some cases, it is desirable to mark only the ancestors (for example
58 when only the server does not yet know that they are common).
61 static void mark_common(struct commit *commit,
62 int ancestors_only, int dont_parse)
64 if (commit != NULL && !(commit->object.flags & COMMON)) {
65 struct object *o = (struct object *)commit;
67 if (!ancestors_only)
68 o->flags |= COMMON;
70 if (!(o->flags & SEEN))
71 rev_list_push(commit, SEEN);
72 else {
73 struct commit_list *parents;
75 if (!ancestors_only && !(o->flags & POPPED))
76 non_common_revs--;
77 if (!o->parsed && !dont_parse)
78 parse_commit(commit);
80 for (parents = commit->parents;
81 parents;
82 parents = parents->next)
83 mark_common(parents->item, 0, dont_parse);
89 Get the next rev to send, ignoring the common.
92 static const unsigned char* get_rev(void)
94 struct commit *commit = NULL;
96 while (commit == NULL) {
97 unsigned int mark;
98 struct commit_list* parents;
100 if (rev_list == NULL || non_common_revs == 0)
101 return NULL;
103 commit = rev_list->item;
104 if (!(commit->object.parsed))
105 parse_commit(commit);
106 commit->object.flags |= POPPED;
107 if (!(commit->object.flags & COMMON))
108 non_common_revs--;
110 parents = commit->parents;
112 if (commit->object.flags & COMMON) {
113 /* do not send "have", and ignore ancestors */
114 commit = NULL;
115 mark = COMMON | SEEN;
116 } else if (commit->object.flags & COMMON_REF)
117 /* send "have", and ignore ancestors */
118 mark = COMMON | SEEN;
119 else
120 /* send "have", also for its ancestors */
121 mark = SEEN;
123 while (parents) {
124 if (!(parents->item->object.flags & SEEN))
125 rev_list_push(parents->item, mark);
126 if (mark & COMMON)
127 mark_common(parents->item, 1, 0);
128 parents = parents->next;
131 rev_list = rev_list->next;
134 return commit->object.sha1;
137 static int find_common(int fd[2], unsigned char *result_sha1,
138 struct ref *refs)
140 int fetching;
141 int count = 0, flushes = 0, retval;
142 const unsigned char *sha1;
143 unsigned in_vain = 0;
144 int got_continue = 0;
146 for_each_ref(rev_list_insert_ref);
148 fetching = 0;
149 for ( ; refs ; refs = refs->next) {
150 unsigned char *remote = refs->old_sha1;
151 struct object *o;
154 * If that object is complete (i.e. it is an ancestor of a
155 * local ref), we tell them we have it but do not have to
156 * tell them about its ancestors, which they already know
157 * about.
159 * We use lookup_object here because we are only
160 * interested in the case we *know* the object is
161 * reachable and we have already scanned it.
163 if (((o = lookup_object(remote)) != NULL) &&
164 (o->flags & COMPLETE)) {
165 continue;
168 if (!fetching)
169 packet_write(fd[1], "want %s%s%s%s%s\n",
170 sha1_to_hex(remote),
171 (multi_ack ? " multi_ack" : ""),
172 (use_sideband == 2 ? " side-band-64k" : ""),
173 (use_sideband == 1 ? " side-band" : ""),
174 (use_thin_pack ? " thin-pack" : ""));
175 else
176 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
177 fetching++;
179 packet_flush(fd[1]);
180 if (!fetching)
181 return 1;
183 flushes = 0;
184 retval = -1;
185 while ((sha1 = get_rev())) {
186 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
187 if (verbose)
188 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
189 in_vain++;
190 if (!(31 & ++count)) {
191 int ack;
193 packet_flush(fd[1]);
194 flushes++;
197 * We keep one window "ahead" of the other side, and
198 * will wait for an ACK only on the next one
200 if (count == 32)
201 continue;
203 do {
204 ack = get_ack(fd[0], result_sha1);
205 if (verbose && ack)
206 fprintf(stderr, "got ack %d %s\n", ack,
207 sha1_to_hex(result_sha1));
208 if (ack == 1) {
209 flushes = 0;
210 multi_ack = 0;
211 retval = 0;
212 goto done;
213 } else if (ack == 2) {
214 struct commit *commit =
215 lookup_commit(result_sha1);
216 mark_common(commit, 0, 1);
217 retval = 0;
218 in_vain = 0;
219 got_continue = 1;
221 } while (ack);
222 flushes--;
223 if (got_continue && MAX_IN_VAIN < in_vain) {
224 if (verbose)
225 fprintf(stderr, "giving up\n");
226 break; /* give up */
230 done:
231 packet_write(fd[1], "done\n");
232 if (verbose)
233 fprintf(stderr, "done\n");
234 if (retval != 0) {
235 multi_ack = 0;
236 flushes++;
238 while (flushes || multi_ack) {
239 int ack = get_ack(fd[0], result_sha1);
240 if (ack) {
241 if (verbose)
242 fprintf(stderr, "got ack (%d) %s\n", ack,
243 sha1_to_hex(result_sha1));
244 if (ack == 1)
245 return 0;
246 multi_ack = 1;
247 continue;
249 flushes--;
251 return retval;
254 static struct commit_list *complete;
256 static int mark_complete(const char *path, const unsigned char *sha1)
258 struct object *o = parse_object(sha1);
260 while (o && o->type == OBJ_TAG) {
261 struct tag *t = (struct tag *) o;
262 if (!t->tagged)
263 break; /* broken repository */
264 o->flags |= COMPLETE;
265 o = parse_object(t->tagged->sha1);
267 if (o && o->type == OBJ_COMMIT) {
268 struct commit *commit = (struct commit *)o;
269 commit->object.flags |= COMPLETE;
270 insert_by_date(commit, &complete);
272 return 0;
275 static void mark_recent_complete_commits(unsigned long cutoff)
277 while (complete && cutoff <= complete->item->date) {
278 if (verbose)
279 fprintf(stderr, "Marking %s as complete\n",
280 sha1_to_hex(complete->item->object.sha1));
281 pop_most_recent_commit(&complete, COMPLETE);
285 static void filter_refs(struct ref **refs, int nr_match, char **match)
287 struct ref **return_refs;
288 struct ref *newlist = NULL;
289 struct ref **newtail = &newlist;
290 struct ref *ref, *next;
291 struct ref *fastarray[32];
293 if (nr_match && !fetch_all) {
294 if (ARRAY_SIZE(fastarray) < nr_match)
295 return_refs = xcalloc(nr_match, sizeof(struct ref *));
296 else {
297 return_refs = fastarray;
298 memset(return_refs, 0, sizeof(struct ref *) * nr_match);
301 else
302 return_refs = NULL;
304 for (ref = *refs; ref; ref = next) {
305 next = ref->next;
306 if (!memcmp(ref->name, "refs/", 5) &&
307 check_ref_format(ref->name + 5))
308 ; /* trash */
309 else if (fetch_all) {
310 *newtail = ref;
311 ref->next = NULL;
312 newtail = &ref->next;
313 continue;
315 else {
316 int order = path_match(ref->name, nr_match, match);
317 if (order) {
318 return_refs[order-1] = ref;
319 continue; /* we will link it later */
322 free(ref);
325 if (!fetch_all) {
326 int i;
327 for (i = 0; i < nr_match; i++) {
328 ref = return_refs[i];
329 if (ref) {
330 *newtail = ref;
331 ref->next = NULL;
332 newtail = &ref->next;
335 if (return_refs != fastarray)
336 free(return_refs);
338 *refs = newlist;
341 static int everything_local(struct ref **refs, int nr_match, char **match)
343 struct ref *ref;
344 int retval;
345 unsigned long cutoff = 0;
347 track_object_refs = 0;
348 save_commit_buffer = 0;
350 for (ref = *refs; ref; ref = ref->next) {
351 struct object *o;
353 o = parse_object(ref->old_sha1);
354 if (!o)
355 continue;
357 /* We already have it -- which may mean that we were
358 * in sync with the other side at some time after
359 * that (it is OK if we guess wrong here).
361 if (o->type == OBJ_COMMIT) {
362 struct commit *commit = (struct commit *)o;
363 if (!cutoff || cutoff < commit->date)
364 cutoff = commit->date;
368 for_each_ref(mark_complete);
369 if (cutoff)
370 mark_recent_complete_commits(cutoff);
373 * Mark all complete remote refs as common refs.
374 * Don't mark them common yet; the server has to be told so first.
376 for (ref = *refs; ref; ref = ref->next) {
377 struct object *o = deref_tag(lookup_object(ref->old_sha1),
378 NULL, 0);
380 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
381 continue;
383 if (!(o->flags & SEEN)) {
384 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
386 mark_common((struct commit *)o, 1, 1);
390 filter_refs(refs, nr_match, match);
392 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
393 const unsigned char *remote = ref->old_sha1;
394 unsigned char local[20];
395 struct object *o;
397 o = lookup_object(remote);
398 if (!o || !(o->flags & COMPLETE)) {
399 retval = 0;
400 if (!verbose)
401 continue;
402 fprintf(stderr,
403 "want %s (%s)\n", sha1_to_hex(remote),
404 ref->name);
405 continue;
408 hashcpy(ref->new_sha1, local);
409 if (!verbose)
410 continue;
411 fprintf(stderr,
412 "already have %s (%s)\n", sha1_to_hex(remote),
413 ref->name);
415 return retval;
418 static int fetch_pack(int fd[2], int nr_match, char **match)
420 struct ref *ref;
421 unsigned char sha1[20];
422 int status;
424 get_remote_heads(fd[0], &ref, 0, NULL, 0);
425 if (server_supports("multi_ack")) {
426 if (verbose)
427 fprintf(stderr, "Server supports multi_ack\n");
428 multi_ack = 1;
430 if (server_supports("side-band-64k")) {
431 if (verbose)
432 fprintf(stderr, "Server supports side-band-64k\n");
433 use_sideband = 2;
435 else if (server_supports("side-band")) {
436 if (verbose)
437 fprintf(stderr, "Server supports side-band\n");
438 use_sideband = 1;
440 if (!ref) {
441 packet_flush(fd[1]);
442 die("no matching remote head");
444 if (everything_local(&ref, nr_match, match)) {
445 packet_flush(fd[1]);
446 goto all_done;
448 if (find_common(fd, sha1, ref) < 0)
449 if (!keep_pack)
450 /* When cloning, it is not unusual to have
451 * no common commit.
453 fprintf(stderr, "warning: no common commits\n");
455 if (keep_pack)
456 status = receive_keep_pack(fd, "git-fetch-pack", quiet, use_sideband);
457 else
458 status = receive_unpack_pack(fd, "git-fetch-pack", quiet, use_sideband);
460 if (status)
461 die("git-fetch-pack: fetch failed.");
463 all_done:
464 while (ref) {
465 printf("%s %s\n",
466 sha1_to_hex(ref->old_sha1), ref->name);
467 ref = ref->next;
469 return 0;
472 int main(int argc, char **argv)
474 int i, ret, nr_heads;
475 char *dest = NULL, **heads;
476 int fd[2];
477 pid_t pid;
479 setup_git_directory();
481 nr_heads = 0;
482 heads = NULL;
483 for (i = 1; i < argc; i++) {
484 char *arg = argv[i];
486 if (*arg == '-') {
487 if (!strncmp("--exec=", arg, 7)) {
488 exec = arg + 7;
489 continue;
491 if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
492 quiet = 1;
493 continue;
495 if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
496 keep_pack = 1;
497 continue;
499 if (!strcmp("--thin", arg)) {
500 use_thin_pack = 1;
501 continue;
503 if (!strcmp("--all", arg)) {
504 fetch_all = 1;
505 continue;
507 if (!strcmp("-v", arg)) {
508 verbose = 1;
509 continue;
511 usage(fetch_pack_usage);
513 dest = arg;
514 heads = argv + i + 1;
515 nr_heads = argc - i - 1;
516 break;
518 if (!dest)
519 usage(fetch_pack_usage);
520 if (keep_pack)
521 use_thin_pack = 0;
522 pid = git_connect(fd, dest, exec);
523 if (pid < 0)
524 return 1;
525 ret = fetch_pack(fd, nr_heads, heads);
526 close(fd[0]);
527 close(fd[1]);
528 ret |= finish_connect(pid);
530 if (!ret && nr_heads) {
531 /* If the heads to pull were given, we should have
532 * consumed all of them by matching the remote.
533 * Otherwise, 'git-fetch remote no-such-ref' would
534 * silently succeed without issuing an error.
536 for (i = 0; i < nr_heads; i++)
537 if (heads[i] && heads[i][0]) {
538 error("no such remote ref %s", heads[i]);
539 ret = 1;
543 return !!ret;