Implement a test for git-fetch-pack/git-upload-pack
[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"
6 #include <time.h>
7 #include <sys/wait.h>
8
9 static int quiet;
10 static int verbose;
11 static const char fetch_pack_usage[] =
12 "git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
13 static const char *exec = "git-upload-pack";
14
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)
20
21 static struct commit_list *rev_list = NULL;
22 static int non_common_revs = 0;
23
24 static void rev_list_push(struct commit *commit, int mark)
25 {
26         if (!(commit->object.flags & mark)) {
27                 commit->object.flags |= mark;
28
29                 if (!(commit->object.parsed))
30                         parse_commit(commit);
31
32                 insert_by_date(commit, &rev_list);
33
34                 if (!(commit->object.flags & COMMON))
35                         non_common_revs++;
36         }
37 }
38
39 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
40 {
41         struct object *o = deref_tag(parse_object(sha1));
42
43         if (o->type == commit_type)
44                 rev_list_push((struct commit *)o, SEEN);
45
46         return 0;
47 }
48
49 /*
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).
53 */
54
55 static void mark_common(struct commit *commit,
56                 int ancestors_only, int dont_parse)
57 {
58         if (commit != NULL && !(commit->object.flags & COMMON)) {
59                 struct object *o = (struct object *)commit;
60
61                 if (!ancestors_only)
62                         o->flags |= COMMON;
63
64                 if (!(o->flags & SEEN))
65                         rev_list_push(commit, SEEN);
66                 else {
67                         struct commit_list *parents;
68
69                         if (!ancestors_only && !(o->flags & POPPED))
70                                 non_common_revs--;
71                         if (!o->parsed && !dont_parse)
72                                 parse_commit(commit);
73
74                         for (parents = commit->parents;
75                                         parents;
76                                         parents = parents->next)
77                                 mark_common(parents->item, 0, dont_parse);
78                 }
79         }
80 }
81
82 /*
83   Get the next rev to send, ignoring the common.
84 */
85
86 static const unsigned char* get_rev()
87 {
88         struct commit *commit = NULL;
89
90         while (commit == NULL) {
91                 unsigned int mark;
92                 struct commit_list* parents;
93
94                 if (rev_list == NULL || non_common_revs == 0)
95                         return NULL;
96
97                 commit = rev_list->item;
98                 if (!(commit->object.parsed))
99                         parse_commit(commit);
100                 commit->object.flags |= POPPED;
101                 if (!(commit->object.flags & COMMON))
102                         non_common_revs--;
103         
104                 parents = commit->parents;
105
106                 if (commit->object.flags & COMMON) {
107                         /* do not send "have", and ignore ancestors */
108                         commit = NULL;
109                         mark = COMMON | SEEN;
110                 } else if (commit->object.flags & COMMON_REF)
111                         /* send "have", and ignore ancestors */
112                         mark = COMMON | SEEN;
113                 else
114                         /* send "have", also for its ancestors */
115                         mark = SEEN;
116
117                 while (parents) {
118                         if (!(parents->item->object.flags & SEEN))
119                                 rev_list_push(parents->item, mark);
120                         if (mark & COMMON)
121                                 mark_common(parents->item, 1, 0);
122                         parents = parents->next;
123                 }
124
125                 rev_list = rev_list->next;
126         }
127
128         return commit->object.sha1;
129 }
130
131 static int find_common(int fd[2], unsigned char *result_sha1,
132                        struct ref *refs)
133 {
134         int fetching;
135         int count = 0, flushes = 0, retval;
136         const unsigned char *sha1;
137
138         for_each_ref(rev_list_insert_ref);
139
140         fetching = 0;
141         for ( ; refs ; refs = refs->next) {
142                 unsigned char *remote = refs->old_sha1;
143                 struct object *o;
144
145                 /*
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
149                  * about.
150                  *
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.
154                  */
155                 if (((o = lookup_object(remote)) != NULL) &&
156                                 (o->flags & COMPLETE)) {
157                         continue;
158                 }
159
160                 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
161                 fetching++;
162         }
163         packet_flush(fd[1]);
164         if (!fetching)
165                 return 1;
166
167         flushes = 0;
168         retval = -1;
169         while ((sha1 = get_rev())) {
170                 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
171                 if (verbose)
172                         fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
173                 if (!(31 & ++count)) {
174                         packet_flush(fd[1]);
175                         flushes++;
176
177                         /*
178                          * We keep one window "ahead" of the other side, and
179                          * will wait for an ACK only on the next one
180                          */
181                         if (count == 32)
182                                 continue;
183                         if (get_ack(fd[0], result_sha1)) {
184                                 flushes = 0;
185                                 retval = 0;
186                                 if (verbose)
187                                         fprintf(stderr, "got ack\n");
188                                 break;
189                         }
190                         flushes--;
191                 }
192         }
193
194         packet_write(fd[1], "done\n");
195         if (verbose)
196                 fprintf(stderr, "done\n");
197         if (retval != 0)
198                 flushes++;
199         while (flushes) {
200                 flushes--;
201                 if (get_ack(fd[0], result_sha1)) {
202                         if (verbose)
203                                 fprintf(stderr, "got ack\n");
204                         return 0;
205                 }
206         }
207         return retval;
208 }
209
210 static struct commit_list *complete = NULL;
211
212 static int mark_complete(const char *path, const unsigned char *sha1)
213 {
214         struct object *o = parse_object(sha1);
215
216         while (o && o->type == tag_type) {
217                 struct tag *t = (struct tag *) o;
218                 if (!t->tagged)
219                         break; /* broken repository */
220                 o->flags |= COMPLETE;
221                 o = parse_object(t->tagged->sha1);
222         }
223         if (o && o->type == commit_type) {
224                 struct commit *commit = (struct commit *)o;
225                 commit->object.flags |= COMPLETE;
226                 insert_by_date(commit, &complete);
227         }
228         return 0;
229 }
230
231 static void mark_recent_complete_commits(unsigned long cutoff)
232 {
233         while (complete && cutoff <= complete->item->date) {
234                 if (verbose)
235                         fprintf(stderr, "Marking %s as complete\n",
236                                 sha1_to_hex(complete->item->object.sha1));
237                 pop_most_recent_commit(&complete, COMPLETE);
238         }
239 }
240
241 static void filter_refs(struct ref **refs, int nr_match, char **match)
242 {
243         struct ref *prev, *current, *next;
244
245         if (!nr_match)
246                 return;
247
248         for (prev = NULL, current = *refs; current; current = next) {
249                 next = current->next;
250                 if ((!memcmp(current->name, "refs/", 5) &&
251                                         check_ref_format(current->name + 5)) ||
252                                 !path_match(current->name, nr_match, match)) {
253                         if (prev == NULL)
254                                 *refs = next;
255                         else
256                                 prev->next = next;
257                         free(current);
258                 } else
259                         prev = current;
260         }
261 }
262
263 static int everything_local(struct ref **refs, int nr_match, char **match)
264 {
265         struct ref *ref;
266         int retval;
267         unsigned long cutoff = 0;
268
269         track_object_refs = 0;
270         save_commit_buffer = 0;
271
272         for (ref = *refs; ref; ref = ref->next) {
273                 struct object *o;
274
275                 o = parse_object(ref->old_sha1);
276                 if (!o)
277                         continue;
278
279                 /* We already have it -- which may mean that we were
280                  * in sync with the other side at some time after
281                  * that (it is OK if we guess wrong here).
282                  */
283                 if (o->type == commit_type) {
284                         struct commit *commit = (struct commit *)o;
285                         if (!cutoff || cutoff < commit->date)
286                                 cutoff = commit->date;
287                 }
288         }
289
290         for_each_ref(mark_complete);
291         if (cutoff)
292                 mark_recent_complete_commits(cutoff);
293
294         /*
295          * Mark all complete remote refs as common refs.
296          * Don't mark them common yet; the server has to be told so first.
297          */
298         for (ref = *refs; ref; ref = ref->next) {
299                 struct object *o = deref_tag(lookup_object(ref->old_sha1));
300
301                 if (!o || o->type != commit_type || !(o->flags & COMPLETE))
302                         continue;
303
304                 if (!(o->flags & SEEN)) {
305                         rev_list_push((struct commit *)o, COMMON_REF | SEEN);
306
307                         mark_common((struct commit *)o, 1, 1);
308                 }
309         }
310
311         filter_refs(refs, nr_match, match);
312
313         for (retval = 1, ref = *refs; ref ; ref = ref->next) {
314                 const unsigned char *remote = ref->old_sha1;
315                 unsigned char local[20];
316                 struct object *o;
317
318                 o = lookup_object(remote);
319                 if (!o || !(o->flags & COMPLETE)) {
320                         retval = 0;
321                         if (!verbose)
322                                 continue;
323                         fprintf(stderr,
324                                 "want %s (%s)\n", sha1_to_hex(remote),
325                                 ref->name);
326                         continue;
327                 }
328
329                 memcpy(ref->new_sha1, local, 20);
330                 if (!verbose)
331                         continue;
332                 fprintf(stderr,
333                         "already have %s (%s)\n", sha1_to_hex(remote),
334                         ref->name);
335         }
336         return retval;
337 }
338
339 static int fetch_pack(int fd[2], int nr_match, char **match)
340 {
341         struct ref *ref;
342         unsigned char sha1[20];
343         int status;
344         pid_t pid;
345
346         get_remote_heads(fd[0], &ref, 0, NULL, 0);
347         if (!ref) {
348                 packet_flush(fd[1]);
349                 die("no matching remote head");
350         }
351         if (everything_local(&ref, nr_match, match)) {
352                 packet_flush(fd[1]);
353                 goto all_done;
354         }
355         if (find_common(fd, sha1, ref) < 0)
356                 fprintf(stderr, "warning: no common commits\n");
357         pid = fork();
358         if (pid < 0)
359                 die("git-fetch-pack: unable to fork off git-unpack-objects");
360         if (!pid) {
361                 dup2(fd[0], 0);
362                 close(fd[0]);
363                 close(fd[1]);
364                 execlp("git-unpack-objects", "git-unpack-objects",
365                        quiet ? "-q" : NULL, NULL);
366                 die("git-unpack-objects exec failed");
367         }
368         close(fd[0]);
369         close(fd[1]);
370         while (waitpid(pid, &status, 0) < 0) {
371                 if (errno != EINTR)
372                         die("waiting for git-unpack-objects: %s", strerror(errno));
373         }
374         if (WIFEXITED(status)) {
375                 int code = WEXITSTATUS(status);
376                 if (code)
377                         die("git-unpack-objects died with error code %d", code);
378 all_done:
379                 while (ref) {
380                         printf("%s %s\n",
381                                sha1_to_hex(ref->old_sha1), ref->name);
382                         ref = ref->next;
383                 }
384                 return 0;
385         }
386         if (WIFSIGNALED(status)) {
387                 int sig = WTERMSIG(status);
388                 die("git-unpack-objects died of signal %d", sig);
389         }
390         die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
391 }
392
393 int main(int argc, char **argv)
394 {
395         int i, ret, nr_heads;
396         char *dest = NULL, **heads;
397         int fd[2];
398         pid_t pid;
399
400         nr_heads = 0;
401         heads = NULL;
402         for (i = 1; i < argc; i++) {
403                 char *arg = argv[i];
404
405                 if (*arg == '-') {
406                         if (!strncmp("--exec=", arg, 7)) {
407                                 exec = arg + 7;
408                                 continue;
409                         }
410                         if (!strcmp("-q", arg)) {
411                                 quiet = 1;
412                                 continue;
413                         }
414                         if (!strcmp("-v", arg)) {
415                                 verbose = 1;
416                                 continue;
417                         }
418                         usage(fetch_pack_usage);
419                 }
420                 dest = arg;
421                 heads = argv + i + 1;
422                 nr_heads = argc - i - 1;
423                 break;
424         }
425         if (!dest)
426                 usage(fetch_pack_usage);
427         pid = git_connect(fd, dest, exec);
428         if (pid < 0)
429                 return 1;
430         ret = fetch_pack(fd, nr_heads, heads);
431         close(fd[0]);
432         close(fd[1]);
433         finish_connect(pid);
434         return ret;
435 }