Code

contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD
[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 const char fetch_pack_usage[] =
11 "git-fetch-pack [-q] [-v] [-k] [--thin] [--exec=upload-pack] [host:]directory <refs>...";
12 static const char *exec = "git-upload-pack";
14 #define COMPLETE        (1U << 0)
15 #define COMMON          (1U << 1)
16 #define COMMON_REF      (1U << 2)
17 #define SEEN            (1U << 3)
18 #define POPPED          (1U << 4)
20 static struct commit_list *rev_list = NULL;
21 static int non_common_revs = 0, multi_ack = 0, use_thin_pack = 0;
23 static void rev_list_push(struct commit *commit, int mark)
24 {
25         if (!(commit->object.flags & mark)) {
26                 commit->object.flags |= mark;
28                 if (!(commit->object.parsed))
29                         parse_commit(commit);
31                 insert_by_date(commit, &rev_list);
33                 if (!(commit->object.flags & COMMON))
34                         non_common_revs++;
35         }
36 }
38 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
39 {
40         struct object *o = deref_tag(parse_object(sha1), path, 0);
42         if (o && o->type == commit_type)
43                 rev_list_push((struct commit *)o, SEEN);
45         return 0;
46 }
48 /*
49    This function marks a rev and its ancestors as common.
50    In some cases, it is desirable to mark only the ancestors (for example
51    when only the server does not yet know that they are common).
52 */
54 static void mark_common(struct commit *commit,
55                 int ancestors_only, int dont_parse)
56 {
57         if (commit != NULL && !(commit->object.flags & COMMON)) {
58                 struct object *o = (struct object *)commit;
60                 if (!ancestors_only)
61                         o->flags |= COMMON;
63                 if (!(o->flags & SEEN))
64                         rev_list_push(commit, SEEN);
65                 else {
66                         struct commit_list *parents;
68                         if (!ancestors_only && !(o->flags & POPPED))
69                                 non_common_revs--;
70                         if (!o->parsed && !dont_parse)
71                                 parse_commit(commit);
73                         for (parents = commit->parents;
74                                         parents;
75                                         parents = parents->next)
76                                 mark_common(parents->item, 0, dont_parse);
77                 }
78         }
79 }
81 /*
82   Get the next rev to send, ignoring the common.
83 */
85 static const unsigned char* get_rev(void)
86 {
87         struct commit *commit = NULL;
89         while (commit == NULL) {
90                 unsigned int mark;
91                 struct commit_list* parents;
93                 if (rev_list == NULL || non_common_revs == 0)
94                         return NULL;
96                 commit = rev_list->item;
97                 if (!(commit->object.parsed))
98                         parse_commit(commit);
99                 commit->object.flags |= POPPED;
100                 if (!(commit->object.flags & COMMON))
101                         non_common_revs--;
102         
103                 parents = commit->parents;
105                 if (commit->object.flags & COMMON) {
106                         /* do not send "have", and ignore ancestors */
107                         commit = NULL;
108                         mark = COMMON | SEEN;
109                 } else if (commit->object.flags & COMMON_REF)
110                         /* send "have", and ignore ancestors */
111                         mark = COMMON | SEEN;
112                 else
113                         /* send "have", also for its ancestors */
114                         mark = SEEN;
116                 while (parents) {
117                         if (!(parents->item->object.flags & SEEN))
118                                 rev_list_push(parents->item, mark);
119                         if (mark & COMMON)
120                                 mark_common(parents->item, 1, 0);
121                         parents = parents->next;
122                 }
124                 rev_list = rev_list->next;
125         }
127         return commit->object.sha1;
130 static int find_common(int fd[2], unsigned char *result_sha1,
131                        struct ref *refs)
133         int fetching;
134         int count = 0, flushes = 0, retval;
135         const unsigned char *sha1;
137         for_each_ref(rev_list_insert_ref);
139         fetching = 0;
140         for ( ; refs ; refs = refs->next) {
141                 unsigned char *remote = refs->old_sha1;
142                 struct object *o;
144                 /*
145                  * If that object is complete (i.e. it is an ancestor of a
146                  * local ref), we tell them we have it but do not have to
147                  * tell them about its ancestors, which they already know
148                  * about.
149                  *
150                  * We use lookup_object here because we are only
151                  * interested in the case we *know* the object is
152                  * reachable and we have already scanned it.
153                  */
154                 if (((o = lookup_object(remote)) != NULL) &&
155                                 (o->flags & COMPLETE)) {
156                         continue;
157                 }
159                 packet_write(fd[1], "want %s%s%s\n", sha1_to_hex(remote),
160                              (multi_ack ? " multi_ack" : ""),
161                              (use_thin_pack ? " thin-pack" : ""));
162                 fetching++;
163         }
164         packet_flush(fd[1]);
165         if (!fetching)
166                 return 1;
168         flushes = 0;
169         retval = -1;
170         while ((sha1 = get_rev())) {
171                 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
172                 if (verbose)
173                         fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
174                 if (!(31 & ++count)) {
175                         int ack;
177                         packet_flush(fd[1]);
178                         flushes++;
180                         /*
181                          * We keep one window "ahead" of the other side, and
182                          * will wait for an ACK only on the next one
183                          */
184                         if (count == 32)
185                                 continue;
187                         do {
188                                 ack = get_ack(fd[0], result_sha1);
189                                 if (verbose && ack)
190                                         fprintf(stderr, "got ack %d %s\n", ack,
191                                                         sha1_to_hex(result_sha1));
192                                 if (ack == 1) {
193                                         flushes = 0;
194                                         multi_ack = 0;
195                                         retval = 0;
196                                         goto done;
197                                 } else if (ack == 2) {
198                                         struct commit *commit =
199                                                 lookup_commit(result_sha1);
200                                         mark_common(commit, 0, 1);
201                                         retval = 0;
202                                 }
203                         } while (ack);
204                         flushes--;
205                 }
206         }
207 done:
208         packet_write(fd[1], "done\n");
209         if (verbose)
210                 fprintf(stderr, "done\n");
211         if (retval != 0) {
212                 multi_ack = 0;
213                 flushes++;
214         }
215         while (flushes || multi_ack) {
216                 int ack = get_ack(fd[0], result_sha1);
217                 if (ack) {
218                         if (verbose)
219                                 fprintf(stderr, "got ack (%d) %s\n", ack,
220                                         sha1_to_hex(result_sha1));
221                         if (ack == 1)
222                                 return 0;
223                         multi_ack = 1;
224                         continue;
225                 }
226                 flushes--;
227         }
228         return retval;
231 static struct commit_list *complete = NULL;
233 static int mark_complete(const char *path, const unsigned char *sha1)
235         struct object *o = parse_object(sha1);
237         while (o && o->type == tag_type) {
238                 struct tag *t = (struct tag *) o;
239                 if (!t->tagged)
240                         break; /* broken repository */
241                 o->flags |= COMPLETE;
242                 o = parse_object(t->tagged->sha1);
243         }
244         if (o && o->type == commit_type) {
245                 struct commit *commit = (struct commit *)o;
246                 commit->object.flags |= COMPLETE;
247                 insert_by_date(commit, &complete);
248         }
249         return 0;
252 static void mark_recent_complete_commits(unsigned long cutoff)
254         while (complete && cutoff <= complete->item->date) {
255                 if (verbose)
256                         fprintf(stderr, "Marking %s as complete\n",
257                                 sha1_to_hex(complete->item->object.sha1));
258                 pop_most_recent_commit(&complete, COMPLETE);
259         }
262 static void filter_refs(struct ref **refs, int nr_match, char **match)
264         struct ref *prev, *current, *next;
266         for (prev = NULL, current = *refs; current; current = next) {
267                 next = current->next;
268                 if ((!memcmp(current->name, "refs/", 5) &&
269                                         check_ref_format(current->name + 5)) ||
270                                 !path_match(current->name, nr_match, match)) {
271                         if (prev == NULL)
272                                 *refs = next;
273                         else
274                                 prev->next = next;
275                         free(current);
276                 } else
277                         prev = current;
278         }
281 static int everything_local(struct ref **refs, int nr_match, char **match)
283         struct ref *ref;
284         int retval;
285         unsigned long cutoff = 0;
287         track_object_refs = 0;
288         save_commit_buffer = 0;
290         for (ref = *refs; ref; ref = ref->next) {
291                 struct object *o;
293                 o = parse_object(ref->old_sha1);
294                 if (!o)
295                         continue;
297                 /* We already have it -- which may mean that we were
298                  * in sync with the other side at some time after
299                  * that (it is OK if we guess wrong here).
300                  */
301                 if (o->type == commit_type) {
302                         struct commit *commit = (struct commit *)o;
303                         if (!cutoff || cutoff < commit->date)
304                                 cutoff = commit->date;
305                 }
306         }
308         for_each_ref(mark_complete);
309         if (cutoff)
310                 mark_recent_complete_commits(cutoff);
312         /*
313          * Mark all complete remote refs as common refs.
314          * Don't mark them common yet; the server has to be told so first.
315          */
316         for (ref = *refs; ref; ref = ref->next) {
317                 struct object *o = deref_tag(lookup_object(ref->old_sha1),
318                                              NULL, 0);
320                 if (!o || o->type != commit_type || !(o->flags & COMPLETE))
321                         continue;
323                 if (!(o->flags & SEEN)) {
324                         rev_list_push((struct commit *)o, COMMON_REF | SEEN);
326                         mark_common((struct commit *)o, 1, 1);
327                 }
328         }
330         filter_refs(refs, nr_match, match);
332         for (retval = 1, ref = *refs; ref ; ref = ref->next) {
333                 const unsigned char *remote = ref->old_sha1;
334                 unsigned char local[20];
335                 struct object *o;
337                 o = lookup_object(remote);
338                 if (!o || !(o->flags & COMPLETE)) {
339                         retval = 0;
340                         if (!verbose)
341                                 continue;
342                         fprintf(stderr,
343                                 "want %s (%s)\n", sha1_to_hex(remote),
344                                 ref->name);
345                         continue;
346                 }
348                 memcpy(ref->new_sha1, local, 20);
349                 if (!verbose)
350                         continue;
351                 fprintf(stderr,
352                         "already have %s (%s)\n", sha1_to_hex(remote),
353                         ref->name);
354         }
355         return retval;
358 static int fetch_pack(int fd[2], int nr_match, char **match)
360         struct ref *ref;
361         unsigned char sha1[20];
362         int status;
364         get_remote_heads(fd[0], &ref, 0, NULL, 0);
365         if (server_supports("multi_ack")) {
366                 if (verbose)
367                         fprintf(stderr, "Server supports multi_ack\n");
368                 multi_ack = 1;
369         }
370         if (!ref) {
371                 packet_flush(fd[1]);
372                 die("no matching remote head");
373         }
374         if (everything_local(&ref, nr_match, match)) {
375                 packet_flush(fd[1]);
376                 goto all_done;
377         }
378         if (find_common(fd, sha1, ref) < 0)
379                 fprintf(stderr, "warning: no common commits\n");
381         if (keep_pack)
382                 status = receive_keep_pack(fd, "git-fetch-pack", quiet);
383         else
384                 status = receive_unpack_pack(fd, "git-fetch-pack", quiet);
386         if (status)
387                 die("git-fetch-pack: fetch failed.");
389  all_done:
390         while (ref) {
391                 printf("%s %s\n",
392                        sha1_to_hex(ref->old_sha1), ref->name);
393                 ref = ref->next;
394         }
395         return 0;
398 int main(int argc, char **argv)
400         int i, ret, nr_heads;
401         char *dest = NULL, **heads;
402         int fd[2];
403         pid_t pid;
405         setup_git_directory();
407         nr_heads = 0;
408         heads = NULL;
409         for (i = 1; i < argc; i++) {
410                 char *arg = argv[i];
412                 if (*arg == '-') {
413                         if (!strncmp("--exec=", arg, 7)) {
414                                 exec = arg + 7;
415                                 continue;
416                         }
417                         if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
418                                 quiet = 1;
419                                 continue;
420                         }
421                         if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
422                                 keep_pack = 1;
423                                 continue;
424                         }
425                         if (!strcmp("--thin", arg)) {
426                                 use_thin_pack = 1;
427                                 continue;
428                         }
429                         if (!strcmp("-v", arg)) {
430                                 verbose = 1;
431                                 continue;
432                         }
433                         usage(fetch_pack_usage);
434                 }
435                 dest = arg;
436                 heads = argv + i + 1;
437                 nr_heads = argc - i - 1;
438                 break;
439         }
440         if (!dest)
441                 usage(fetch_pack_usage);
442         if (keep_pack)
443                 use_thin_pack = 0;
444         pid = git_connect(fd, dest, exec);
445         if (pid < 0)
446                 return 1;
447         ret = fetch_pack(fd, nr_heads, heads);
448         close(fd[0]);
449         close(fd[1]);
450         finish_connect(pid);
452         if (!ret && nr_heads) {
453                 /* If the heads to pull were given, we should have
454                  * consumed all of them by matching the remote.
455                  * Otherwise, 'git-fetch remote no-such-ref' would
456                  * silently succeed without issuing an error.
457                  */
458                 for (i = 0; i < nr_heads; i++)
459                         if (heads[i] && heads[i][0]) {
460                                 error("no such remote ref %s", heads[i]);
461                                 ret = 1;
462                         }
463         }
465         return ret;