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 static struct commit_list *rev_list = NULL;
22 static int non_common_revs = 0, multi_ack = 0, use_thin_pack = 0;
24 static void rev_list_push(struct commit *commit, int mark)
26 if (!(commit->object.flags & mark)) {
27 commit->object.flags |= mark;
29 if (!(commit->object.parsed))
32 insert_by_date(commit, &rev_list);
34 if (!(commit->object.flags & COMMON))
39 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
41 struct object *o = deref_tag(parse_object(sha1), path, 0);
43 if (o && o->type == commit_type)
44 rev_list_push((struct commit *)o, SEEN);
50 This function marks a rev and its ancestors as common.
51 In some cases, it is desirable to mark only the ancestors (for example
52 when only the server does not yet know that they are common).
55 static void mark_common(struct commit *commit,
56 int ancestors_only, int dont_parse)
58 if (commit != NULL && !(commit->object.flags & COMMON)) {
59 struct object *o = (struct object *)commit;
64 if (!(o->flags & SEEN))
65 rev_list_push(commit, SEEN);
67 struct commit_list *parents;
69 if (!ancestors_only && !(o->flags & POPPED))
71 if (!o->parsed && !dont_parse)
74 for (parents = commit->parents;
76 parents = parents->next)
77 mark_common(parents->item, 0, dont_parse);
83 Get the next rev to send, ignoring the common.
86 static const unsigned char* get_rev(void)
88 struct commit *commit = NULL;
90 while (commit == NULL) {
92 struct commit_list* parents;
94 if (rev_list == NULL || non_common_revs == 0)
97 commit = rev_list->item;
98 if (!(commit->object.parsed))
100 commit->object.flags |= POPPED;
101 if (!(commit->object.flags & COMMON))
104 parents = commit->parents;
106 if (commit->object.flags & COMMON) {
107 /* do not send "have", and ignore ancestors */
109 mark = COMMON | SEEN;
110 } else if (commit->object.flags & COMMON_REF)
111 /* send "have", and ignore ancestors */
112 mark = COMMON | SEEN;
114 /* send "have", also for its ancestors */
118 if (!(parents->item->object.flags & SEEN))
119 rev_list_push(parents->item, mark);
121 mark_common(parents->item, 1, 0);
122 parents = parents->next;
125 rev_list = rev_list->next;
128 return commit->object.sha1;
131 static int find_common(int fd[2], unsigned char *result_sha1,
135 int count = 0, flushes = 0, retval;
136 const unsigned char *sha1;
138 for_each_ref(rev_list_insert_ref);
141 for ( ; refs ; refs = refs->next) {
142 unsigned char *remote = refs->old_sha1;
146 * If that object is complete (i.e. it is an ancestor of a
147 * local ref), we tell them we have it but do not have to
148 * tell them about its ancestors, which they already know
151 * We use lookup_object here because we are only
152 * interested in the case we *know* the object is
153 * reachable and we have already scanned it.
155 if (((o = lookup_object(remote)) != NULL) &&
156 (o->flags & COMPLETE)) {
160 packet_write(fd[1], "want %s%s%s\n", sha1_to_hex(remote),
161 (multi_ack ? " multi_ack" : ""),
162 (use_thin_pack ? " thin-pack" : ""));
171 while ((sha1 = get_rev())) {
172 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
174 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
175 if (!(31 & ++count)) {
182 * We keep one window "ahead" of the other side, and
183 * will wait for an ACK only on the next one
189 ack = get_ack(fd[0], result_sha1);
191 fprintf(stderr, "got ack %d %s\n", ack,
192 sha1_to_hex(result_sha1));
198 } else if (ack == 2) {
199 struct commit *commit =
200 lookup_commit(result_sha1);
201 mark_common(commit, 0, 1);
209 packet_write(fd[1], "done\n");
211 fprintf(stderr, "done\n");
216 while (flushes || multi_ack) {
217 int ack = get_ack(fd[0], result_sha1);
220 fprintf(stderr, "got ack (%d) %s\n", ack,
221 sha1_to_hex(result_sha1));
232 static struct commit_list *complete = NULL;
234 static int mark_complete(const char *path, const unsigned char *sha1)
236 struct object *o = parse_object(sha1);
238 while (o && o->type == tag_type) {
239 struct tag *t = (struct tag *) o;
241 break; /* broken repository */
242 o->flags |= COMPLETE;
243 o = parse_object(t->tagged->sha1);
245 if (o && o->type == commit_type) {
246 struct commit *commit = (struct commit *)o;
247 commit->object.flags |= COMPLETE;
248 insert_by_date(commit, &complete);
253 static void mark_recent_complete_commits(unsigned long cutoff)
255 while (complete && cutoff <= complete->item->date) {
257 fprintf(stderr, "Marking %s as complete\n",
258 sha1_to_hex(complete->item->object.sha1));
259 pop_most_recent_commit(&complete, COMPLETE);
263 static void filter_refs(struct ref **refs, int nr_match, char **match)
265 struct ref *prev, *current, *next;
267 for (prev = NULL, current = *refs; current; current = next) {
268 next = current->next;
269 if ((!memcmp(current->name, "refs/", 5) &&
270 check_ref_format(current->name + 5)) ||
272 !path_match(current->name, nr_match, match))) {
283 static int everything_local(struct ref **refs, int nr_match, char **match)
287 unsigned long cutoff = 0;
289 track_object_refs = 0;
290 save_commit_buffer = 0;
292 for (ref = *refs; ref; ref = ref->next) {
295 o = parse_object(ref->old_sha1);
299 /* We already have it -- which may mean that we were
300 * in sync with the other side at some time after
301 * that (it is OK if we guess wrong here).
303 if (o->type == commit_type) {
304 struct commit *commit = (struct commit *)o;
305 if (!cutoff || cutoff < commit->date)
306 cutoff = commit->date;
310 for_each_ref(mark_complete);
312 mark_recent_complete_commits(cutoff);
315 * Mark all complete remote refs as common refs.
316 * Don't mark them common yet; the server has to be told so first.
318 for (ref = *refs; ref; ref = ref->next) {
319 struct object *o = deref_tag(lookup_object(ref->old_sha1),
322 if (!o || o->type != commit_type || !(o->flags & COMPLETE))
325 if (!(o->flags & SEEN)) {
326 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
328 mark_common((struct commit *)o, 1, 1);
332 filter_refs(refs, nr_match, match);
334 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
335 const unsigned char *remote = ref->old_sha1;
336 unsigned char local[20];
339 o = lookup_object(remote);
340 if (!o || !(o->flags & COMPLETE)) {
345 "want %s (%s)\n", sha1_to_hex(remote),
350 memcpy(ref->new_sha1, local, 20);
354 "already have %s (%s)\n", sha1_to_hex(remote),
360 static int fetch_pack(int fd[2], int nr_match, char **match)
363 unsigned char sha1[20];
366 get_remote_heads(fd[0], &ref, 0, NULL, 0);
367 if (server_supports("multi_ack")) {
369 fprintf(stderr, "Server supports multi_ack\n");
374 die("no matching remote head");
376 if (everything_local(&ref, nr_match, match)) {
380 if (find_common(fd, sha1, ref) < 0)
382 /* When cloning, it is not unusual to have
385 fprintf(stderr, "warning: no common commits\n");
388 status = receive_keep_pack(fd, "git-fetch-pack", quiet);
390 status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
393 die("git-fetch-pack: fetch failed.");
398 sha1_to_hex(ref->old_sha1), ref->name);
404 int main(int argc, char **argv)
406 int i, ret, nr_heads;
407 char *dest = NULL, **heads;
411 setup_git_directory();
415 for (i = 1; i < argc; i++) {
419 if (!strncmp("--exec=", arg, 7)) {
423 if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
427 if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
431 if (!strcmp("--thin", arg)) {
435 if (!strcmp("--all", arg)) {
439 if (!strcmp("-v", arg)) {
443 usage(fetch_pack_usage);
446 heads = argv + i + 1;
447 nr_heads = argc - i - 1;
451 usage(fetch_pack_usage);
454 pid = git_connect(fd, dest, exec);
457 ret = fetch_pack(fd, nr_heads, heads);
462 if (!ret && nr_heads) {
463 /* If the heads to pull were given, we should have
464 * consumed all of them by matching the remote.
465 * Otherwise, 'git-fetch remote no-such-ref' would
466 * silently succeed without issuing an error.
468 for (i = 0; i < nr_heads; i++)
469 if (heads[i] && heads[i][0]) {
470 error("no such remote ref %s", heads[i]);