3be77c3a8e76c6bc08414e9467c1dc1d0d91c6d1
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)
18#define SEEN (1U << 3)
19#define POPPED (1U << 4)
20
21static struct commit_list *rev_list = NULL;
22static int non_common_revs = 0;
23
24static 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
39static 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
55static 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
86static 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
131static 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 o = deref_tag(o);
158
159 if (o->type == commit_type) {
160 struct commit *commit = (struct commit *)o;
161
162 rev_list_push(commit, COMMON_REF | SEEN);
163
164 mark_common(commit, 1, 1);
165 }
166 continue;
167 }
168
169 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
170 fetching++;
171 }
172 packet_flush(fd[1]);
173 if (!fetching)
174 return 1;
175
176 flushes = 0;
177 retval = -1;
178 while ((sha1 = get_rev())) {
179 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
180 if (verbose)
181 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
182 if (!(31 & ++count)) {
183 packet_flush(fd[1]);
184 flushes++;
185
186 /*
187 * We keep one window "ahead" of the other side, and
188 * will wait for an ACK only on the next one
189 */
190 if (count == 32)
191 continue;
192 if (get_ack(fd[0], result_sha1)) {
193 flushes = 0;
194 retval = 0;
195 if (verbose)
196 fprintf(stderr, "got ack\n");
197 break;
198 }
199 flushes--;
200 }
201 }
202
203 packet_write(fd[1], "done\n");
204 if (verbose)
205 fprintf(stderr, "done\n");
206 if (retval != 0)
207 flushes++;
208 while (flushes) {
209 flushes--;
210 if (get_ack(fd[0], result_sha1)) {
211 if (verbose)
212 fprintf(stderr, "got ack\n");
213 return 0;
214 }
215 }
216 return retval;
217}
218
219static struct commit_list *complete = NULL;
220
221static int mark_complete(const char *path, const unsigned char *sha1)
222{
223 struct object *o = parse_object(sha1);
224
225 while (o && o->type == tag_type) {
226 struct tag *t = (struct tag *) o;
227 if (!t->tagged)
228 break; /* broken repository */
229 o->flags |= COMPLETE;
230 o = parse_object(t->tagged->sha1);
231 }
232 if (o && o->type == commit_type) {
233 struct commit *commit = (struct commit *)o;
234 commit->object.flags |= COMPLETE;
235 insert_by_date(commit, &complete);
236 }
237 return 0;
238}
239
240static void mark_recent_complete_commits(unsigned long cutoff)
241{
242 while (complete && cutoff <= complete->item->date) {
243 if (verbose)
244 fprintf(stderr, "Marking %s as complete\n",
245 sha1_to_hex(complete->item->object.sha1));
246 pop_most_recent_commit(&complete, COMPLETE);
247 }
248}
249
250static int everything_local(struct ref *refs)
251{
252 struct ref *ref;
253 int retval;
254 unsigned long cutoff = 0;
255
256 track_object_refs = 0;
257 save_commit_buffer = 0;
258
259 for (ref = refs; ref; ref = ref->next) {
260 struct object *o;
261
262 o = parse_object(ref->old_sha1);
263 if (!o)
264 continue;
265
266 /* We already have it -- which may mean that we were
267 * in sync with the other side at some time after
268 * that (it is OK if we guess wrong here).
269 */
270 if (o->type == commit_type) {
271 struct commit *commit = (struct commit *)o;
272 if (!cutoff || cutoff < commit->date)
273 cutoff = commit->date;
274 }
275 }
276
277 for_each_ref(mark_complete);
278 if (cutoff)
279 mark_recent_complete_commits(cutoff);
280
281 for (retval = 1; refs ; refs = refs->next) {
282 const unsigned char *remote = refs->old_sha1;
283 unsigned char local[20];
284 struct object *o;
285
286 o = parse_object(remote);
287 if (!o || !(o->flags & COMPLETE)) {
288 retval = 0;
289 if (!verbose)
290 continue;
291 fprintf(stderr,
292 "want %s (%s)\n", sha1_to_hex(remote),
293 refs->name);
294 continue;
295 }
296
297 memcpy(refs->new_sha1, local, 20);
298 if (!verbose)
299 continue;
300 fprintf(stderr,
301 "already have %s (%s)\n", sha1_to_hex(remote),
302 refs->name);
303 }
304 return retval;
305}
306
307static int fetch_pack(int fd[2], int nr_match, char **match)
308{
309 struct ref *ref;
310 unsigned char sha1[20];
311 int status;
312 pid_t pid;
313
314 get_remote_heads(fd[0], &ref, nr_match, match, 1);
315 if (!ref) {
316 packet_flush(fd[1]);
317 die("no matching remote head");
318 }
319 if (everything_local(ref)) {
320 packet_flush(fd[1]);
321 goto all_done;
322 }
323 if (find_common(fd, sha1, ref) < 0)
324 fprintf(stderr, "warning: no common commits\n");
325 pid = fork();
326 if (pid < 0)
327 die("git-fetch-pack: unable to fork off git-unpack-objects");
328 if (!pid) {
329 dup2(fd[0], 0);
330 close(fd[0]);
331 close(fd[1]);
332 execlp("git-unpack-objects", "git-unpack-objects",
333 quiet ? "-q" : NULL, NULL);
334 die("git-unpack-objects exec failed");
335 }
336 close(fd[0]);
337 close(fd[1]);
338 while (waitpid(pid, &status, 0) < 0) {
339 if (errno != EINTR)
340 die("waiting for git-unpack-objects: %s", strerror(errno));
341 }
342 if (WIFEXITED(status)) {
343 int code = WEXITSTATUS(status);
344 if (code)
345 die("git-unpack-objects died with error code %d", code);
346all_done:
347 while (ref) {
348 printf("%s %s\n",
349 sha1_to_hex(ref->old_sha1), ref->name);
350 ref = ref->next;
351 }
352 return 0;
353 }
354 if (WIFSIGNALED(status)) {
355 int sig = WTERMSIG(status);
356 die("git-unpack-objects died of signal %d", sig);
357 }
358 die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
359}
360
361int main(int argc, char **argv)
362{
363 int i, ret, nr_heads;
364 char *dest = NULL, **heads;
365 int fd[2];
366 pid_t pid;
367
368 nr_heads = 0;
369 heads = NULL;
370 for (i = 1; i < argc; i++) {
371 char *arg = argv[i];
372
373 if (*arg == '-') {
374 if (!strncmp("--exec=", arg, 7)) {
375 exec = arg + 7;
376 continue;
377 }
378 if (!strcmp("-q", arg)) {
379 quiet = 1;
380 continue;
381 }
382 if (!strcmp("-v", arg)) {
383 verbose = 1;
384 continue;
385 }
386 usage(fetch_pack_usage);
387 }
388 dest = arg;
389 heads = argv + i + 1;
390 nr_heads = argc - i - 1;
391 break;
392 }
393 if (!dest)
394 usage(fetch_pack_usage);
395 pid = git_connect(fd, dest, exec);
396 if (pid < 0)
397 return 1;
398 ret = fetch_pack(fd, nr_heads, heads);
399 close(fd[0]);
400 close(fd[1]);
401 finish_connect(pid);
402 return ret;
403}