gitweb: Add "next" link to commitdiff view
[git/dscho.git] / fetch-pack.c
blob474d54520eae356a8987349b1e36186a30914966
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%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 " ofs-delta");
176 else
177 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
178 fetching++;
180 packet_flush(fd[1]);
181 if (!fetching)
182 return 1;
184 flushes = 0;
185 retval = -1;
186 while ((sha1 = get_rev())) {
187 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
188 if (verbose)
189 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
190 in_vain++;
191 if (!(31 & ++count)) {
192 int ack;
194 packet_flush(fd[1]);
195 flushes++;
198 * We keep one window "ahead" of the other side, and
199 * will wait for an ACK only on the next one
201 if (count == 32)
202 continue;
204 do {
205 ack = get_ack(fd[0], result_sha1);
206 if (verbose && ack)
207 fprintf(stderr, "got ack %d %s\n", ack,
208 sha1_to_hex(result_sha1));
209 if (ack == 1) {
210 flushes = 0;
211 multi_ack = 0;
212 retval = 0;
213 goto done;
214 } else if (ack == 2) {
215 struct commit *commit =
216 lookup_commit(result_sha1);
217 mark_common(commit, 0, 1);
218 retval = 0;
219 in_vain = 0;
220 got_continue = 1;
222 } while (ack);
223 flushes--;
224 if (got_continue && MAX_IN_VAIN < in_vain) {
225 if (verbose)
226 fprintf(stderr, "giving up\n");
227 break; /* give up */
231 done:
232 packet_write(fd[1], "done\n");
233 if (verbose)
234 fprintf(stderr, "done\n");
235 if (retval != 0) {
236 multi_ack = 0;
237 flushes++;
239 while (flushes || multi_ack) {
240 int ack = get_ack(fd[0], result_sha1);
241 if (ack) {
242 if (verbose)
243 fprintf(stderr, "got ack (%d) %s\n", ack,
244 sha1_to_hex(result_sha1));
245 if (ack == 1)
246 return 0;
247 multi_ack = 1;
248 continue;
250 flushes--;
252 return retval;
255 static struct commit_list *complete;
257 static int mark_complete(const char *path, const unsigned char *sha1)
259 struct object *o = parse_object(sha1);
261 while (o && o->type == OBJ_TAG) {
262 struct tag *t = (struct tag *) o;
263 if (!t->tagged)
264 break; /* broken repository */
265 o->flags |= COMPLETE;
266 o = parse_object(t->tagged->sha1);
268 if (o && o->type == OBJ_COMMIT) {
269 struct commit *commit = (struct commit *)o;
270 commit->object.flags |= COMPLETE;
271 insert_by_date(commit, &complete);
273 return 0;
276 static void mark_recent_complete_commits(unsigned long cutoff)
278 while (complete && cutoff <= complete->item->date) {
279 if (verbose)
280 fprintf(stderr, "Marking %s as complete\n",
281 sha1_to_hex(complete->item->object.sha1));
282 pop_most_recent_commit(&complete, COMPLETE);
286 static void filter_refs(struct ref **refs, int nr_match, char **match)
288 struct ref **return_refs;
289 struct ref *newlist = NULL;
290 struct ref **newtail = &newlist;
291 struct ref *ref, *next;
292 struct ref *fastarray[32];
294 if (nr_match && !fetch_all) {
295 if (ARRAY_SIZE(fastarray) < nr_match)
296 return_refs = xcalloc(nr_match, sizeof(struct ref *));
297 else {
298 return_refs = fastarray;
299 memset(return_refs, 0, sizeof(struct ref *) * nr_match);
302 else
303 return_refs = NULL;
305 for (ref = *refs; ref; ref = next) {
306 next = ref->next;
307 if (!memcmp(ref->name, "refs/", 5) &&
308 check_ref_format(ref->name + 5))
309 ; /* trash */
310 else if (fetch_all) {
311 *newtail = ref;
312 ref->next = NULL;
313 newtail = &ref->next;
314 continue;
316 else {
317 int order = path_match(ref->name, nr_match, match);
318 if (order) {
319 return_refs[order-1] = ref;
320 continue; /* we will link it later */
323 free(ref);
326 if (!fetch_all) {
327 int i;
328 for (i = 0; i < nr_match; i++) {
329 ref = return_refs[i];
330 if (ref) {
331 *newtail = ref;
332 ref->next = NULL;
333 newtail = &ref->next;
336 if (return_refs != fastarray)
337 free(return_refs);
339 *refs = newlist;
342 static int everything_local(struct ref **refs, int nr_match, char **match)
344 struct ref *ref;
345 int retval;
346 unsigned long cutoff = 0;
348 track_object_refs = 0;
349 save_commit_buffer = 0;
351 for (ref = *refs; ref; ref = ref->next) {
352 struct object *o;
354 o = parse_object(ref->old_sha1);
355 if (!o)
356 continue;
358 /* We already have it -- which may mean that we were
359 * in sync with the other side at some time after
360 * that (it is OK if we guess wrong here).
362 if (o->type == OBJ_COMMIT) {
363 struct commit *commit = (struct commit *)o;
364 if (!cutoff || cutoff < commit->date)
365 cutoff = commit->date;
369 for_each_ref(mark_complete);
370 if (cutoff)
371 mark_recent_complete_commits(cutoff);
374 * Mark all complete remote refs as common refs.
375 * Don't mark them common yet; the server has to be told so first.
377 for (ref = *refs; ref; ref = ref->next) {
378 struct object *o = deref_tag(lookup_object(ref->old_sha1),
379 NULL, 0);
381 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
382 continue;
384 if (!(o->flags & SEEN)) {
385 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
387 mark_common((struct commit *)o, 1, 1);
391 filter_refs(refs, nr_match, match);
393 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
394 const unsigned char *remote = ref->old_sha1;
395 unsigned char local[20];
396 struct object *o;
398 o = lookup_object(remote);
399 if (!o || !(o->flags & COMPLETE)) {
400 retval = 0;
401 if (!verbose)
402 continue;
403 fprintf(stderr,
404 "want %s (%s)\n", sha1_to_hex(remote),
405 ref->name);
406 continue;
409 hashcpy(ref->new_sha1, local);
410 if (!verbose)
411 continue;
412 fprintf(stderr,
413 "already have %s (%s)\n", sha1_to_hex(remote),
414 ref->name);
416 return retval;
419 static int fetch_pack(int fd[2], int nr_match, char **match)
421 struct ref *ref;
422 unsigned char sha1[20];
423 int status;
425 get_remote_heads(fd[0], &ref, 0, NULL, 0);
426 if (server_supports("multi_ack")) {
427 if (verbose)
428 fprintf(stderr, "Server supports multi_ack\n");
429 multi_ack = 1;
431 if (server_supports("side-band-64k")) {
432 if (verbose)
433 fprintf(stderr, "Server supports side-band-64k\n");
434 use_sideband = 2;
436 else if (server_supports("side-band")) {
437 if (verbose)
438 fprintf(stderr, "Server supports side-band\n");
439 use_sideband = 1;
441 if (!ref) {
442 packet_flush(fd[1]);
443 die("no matching remote head");
445 if (everything_local(&ref, nr_match, match)) {
446 packet_flush(fd[1]);
447 goto all_done;
449 if (find_common(fd, sha1, ref) < 0)
450 if (!keep_pack)
451 /* When cloning, it is not unusual to have
452 * no common commit.
454 fprintf(stderr, "warning: no common commits\n");
456 if (keep_pack)
457 status = receive_keep_pack(fd, "git-fetch-pack", quiet, use_sideband);
458 else
459 status = receive_unpack_pack(fd, "git-fetch-pack", quiet, use_sideband);
461 if (status)
462 die("git-fetch-pack: fetch failed.");
464 all_done:
465 while (ref) {
466 printf("%s %s\n",
467 sha1_to_hex(ref->old_sha1), ref->name);
468 ref = ref->next;
470 return 0;
473 int main(int argc, char **argv)
475 int i, ret, nr_heads;
476 char *dest = NULL, **heads;
477 int fd[2];
478 pid_t pid;
480 setup_git_directory();
482 nr_heads = 0;
483 heads = NULL;
484 for (i = 1; i < argc; i++) {
485 char *arg = argv[i];
487 if (*arg == '-') {
488 if (!strncmp("--exec=", arg, 7)) {
489 exec = arg + 7;
490 continue;
492 if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
493 quiet = 1;
494 continue;
496 if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
497 keep_pack = 1;
498 continue;
500 if (!strcmp("--thin", arg)) {
501 use_thin_pack = 1;
502 continue;
504 if (!strcmp("--all", arg)) {
505 fetch_all = 1;
506 continue;
508 if (!strcmp("-v", arg)) {
509 verbose = 1;
510 continue;
512 usage(fetch_pack_usage);
514 dest = arg;
515 heads = argv + i + 1;
516 nr_heads = argc - i - 1;
517 break;
519 if (!dest)
520 usage(fetch_pack_usage);
521 if (keep_pack)
522 use_thin_pack = 0;
523 pid = git_connect(fd, dest, exec);
524 if (pid < 0)
525 return 1;
526 ret = fetch_pack(fd, nr_heads, heads);
527 close(fd[0]);
528 close(fd[1]);
529 ret |= finish_connect(pid);
531 if (!ret && nr_heads) {
532 /* If the heads to pull were given, we should have
533 * consumed all of them by matching the remote.
534 * Otherwise, 'git-fetch remote no-such-ref' would
535 * silently succeed without issuing an error.
537 for (i = 0; i < nr_heads; i++)
538 if (heads[i] && heads[i][0]) {
539 error("no such remote ref %s", heads[i]);
540 ret = 1;
544 return !!ret;