Code

Merge branch 'jc/http'
[git.git] / fetch-pack.c
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)
21 /*
22  * After sending this many "have"s if we do not get any new ACK , we
23  * give up traversing our history.
24  */
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)
31 {
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++;
42         }
43 }
45 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
46 {
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;
53 }
55 /*
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).
59 */
61 static void mark_common(struct commit *commit,
62                 int ancestors_only, int dont_parse)
63 {
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);
84                 }
85         }
86 }
88 /*
89   Get the next rev to send, ignoring the common.
90 */
92 static const unsigned char* get_rev(void)
93 {
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--;
109         
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;
129                 }
131                 rev_list = rev_list->next;
132         }
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;
153                 /*
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.
158                  *
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.
162                  */
163                 if (((o = lookup_object(remote)) != NULL) &&
164                                 (o->flags & COMPLETE)) {
165                         continue;
166                 }
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++;
178         }
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++;
196                         /*
197                          * We keep one window "ahead" of the other side, and
198                          * will wait for an ACK only on the next one
199                          */
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;
220                                 }
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 */
227                         }
228                 }
229         }
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++;
237         }
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;
248                 }
249                 flushes--;
250         }
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);
266         }
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);
271         }
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);
282         }
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);
299                 }
300         }
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;
314                 }
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 */
320                         }
321                 }
322                 free(ref);
323         }
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;
333                         }
334                 }
335                 if (return_refs != fastarray)
336                         free(return_refs);
337         }
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).
360                  */
361                 if (o->type == OBJ_COMMIT) {
362                         struct commit *commit = (struct commit *)o;
363                         if (!cutoff || cutoff < commit->date)
364                                 cutoff = commit->date;
365                 }
366         }
368         for_each_ref(mark_complete);
369         if (cutoff)
370                 mark_recent_complete_commits(cutoff);
372         /*
373          * Mark all complete remote refs as common refs.
374          * Don't mark them common yet; the server has to be told so first.
375          */
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);
387                 }
388         }
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;
406                 }
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);
414         }
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;
429         }
430         if (server_supports("side-band-64k")) {
431                 if (verbose)
432                         fprintf(stderr, "Server supports side-band-64k\n");
433                 use_sideband = 2;
434         }
435         else if (server_supports("side-band")) {
436                 if (verbose)
437                         fprintf(stderr, "Server supports side-band\n");
438                 use_sideband = 1;
439         }
440         if (!ref) {
441                 packet_flush(fd[1]);
442                 die("no matching remote head");
443         }
444         if (everything_local(&ref, nr_match, match)) {
445                 packet_flush(fd[1]);
446                 goto all_done;
447         }
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.
452                          */
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;
468         }
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;
490                         }
491                         if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
492                                 quiet = 1;
493                                 continue;
494                         }
495                         if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
496                                 keep_pack = 1;
497                                 continue;
498                         }
499                         if (!strcmp("--thin", arg)) {
500                                 use_thin_pack = 1;
501                                 continue;
502                         }
503                         if (!strcmp("--all", arg)) {
504                                 fetch_all = 1;
505                                 continue;
506                         }
507                         if (!strcmp("-v", arg)) {
508                                 verbose = 1;
509                                 continue;
510                         }
511                         usage(fetch_pack_usage);
512                 }
513                 dest = arg;
514                 heads = argv + i + 1;
515                 nr_heads = argc - i - 1;
516                 break;
517         }
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.
535                  */
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;
540                         }
541         }
543         return !!ret;