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