blob: 9c81305be5f4c1a78794c9d5397bd828ba705fcc [file] [log] [blame]
Linus Torvaldsdef88e92005-07-04 13:26:53 -07001#include "cache.h"
Linus Torvaldsfb9040c2005-07-04 15:29:17 -07002#include "refs.h"
Linus Torvaldsdef88e92005-07-04 13:26:53 -07003#include "pkt-line.h"
Junio C Hamano49bb8052005-10-19 14:27:02 -07004#include "commit.h"
5#include "tag.h"
Nicolas Pitreda093d32006-11-01 17:06:23 -05006#include "exec_cmd.h"
Junio C Hamano9e10fd12007-01-22 22:37:33 -08007#include "pack.h"
Nicolas Pitreda093d32006-11-01 17:06:23 -05008#include "sideband.h"
Linus Torvaldsdef88e92005-07-04 13:26:53 -07009
Junio C Hamanoad897212005-12-14 22:17:38 -080010static int keep_pack;
Junio C Hamanoe28714c2007-01-24 17:02:15 -080011static int transfer_unpack_limit = -1;
12static int fetch_unpack_limit = -1;
Junio C Hamanoaf7cf262007-01-24 16:47:24 -080013static int unpack_limit = 100;
Junio C Hamano8b3d9dc2005-07-14 00:08:37 -070014static int quiet;
Junio C Hamano33b83032005-08-12 02:08:29 -070015static int verbose;
Junio C Hamanodfeff662006-03-20 00:21:10 -080016static int fetch_all;
Johannes Schindelin016e6cc2006-10-30 20:09:29 +010017static int depth;
Johannes Schindelin83a5ad62007-02-20 03:01:44 +010018static int no_progress;
Junio C Hamano33b83032005-08-12 02:08:29 -070019static const char fetch_pack_usage[] =
Johannes Schindelin83a5ad62007-02-20 03:01:44 +010020"git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
Uwe Kleine-König27dca072007-01-23 09:20:17 +010021static const char *uploadpack = "git-upload-pack";
Linus Torvaldsdef88e92005-07-04 13:26:53 -070022
Johannes Schindelin0a8944d2005-10-19 16:14:34 -070023#define COMPLETE (1U << 0)
Johannes Schindelin23d61f82005-10-28 04:46:27 +020024#define COMMON (1U << 1)
25#define COMMON_REF (1U << 2)
26#define SEEN (1U << 3)
27#define POPPED (1U << 4)
28
Junio C Hamanof061e5f2006-05-24 21:48:34 -070029/*
30 * After sending this many "have"s if we do not get any new ACK , we
31 * give up traversing our history.
32 */
33#define MAX_IN_VAIN 256
34
David Rientjes96f1e582006-08-15 10:23:48 -070035static struct commit_list *rev_list;
36static int non_common_revs, multi_ack, use_thin_pack, use_sideband;
Johannes Schindelin23d61f82005-10-28 04:46:27 +020037
38static void rev_list_push(struct commit *commit, int mark)
39{
40 if (!(commit->object.flags & mark)) {
41 commit->object.flags |= mark;
42
43 if (!(commit->object.parsed))
44 parse_commit(commit);
45
46 insert_by_date(commit, &rev_list);
47
48 if (!(commit->object.flags & COMMON))
49 non_common_revs++;
50 }
51}
52
Junio C Hamano8da19772006-09-20 22:02:01 -070053static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
Johannes Schindelin23d61f82005-10-28 04:46:27 +020054{
Junio C Hamano9534f402005-11-02 15:19:13 -080055 struct object *o = deref_tag(parse_object(sha1), path, 0);
Johannes Schindelin23d61f82005-10-28 04:46:27 +020056
Linus Torvalds19746322006-07-11 20:45:31 -070057 if (o && o->type == OBJ_COMMIT)
Johannes Schindelin23d61f82005-10-28 04:46:27 +020058 rev_list_push((struct commit *)o, SEEN);
59
60 return 0;
61}
62
63/*
64 This function marks a rev and its ancestors as common.
65 In some cases, it is desirable to mark only the ancestors (for example
66 when only the server does not yet know that they are common).
67*/
68
69static void mark_common(struct commit *commit,
70 int ancestors_only, int dont_parse)
71{
72 if (commit != NULL && !(commit->object.flags & COMMON)) {
73 struct object *o = (struct object *)commit;
74
75 if (!ancestors_only)
76 o->flags |= COMMON;
77
78 if (!(o->flags & SEEN))
79 rev_list_push(commit, SEEN);
80 else {
81 struct commit_list *parents;
82
83 if (!ancestors_only && !(o->flags & POPPED))
84 non_common_revs--;
85 if (!o->parsed && !dont_parse)
86 parse_commit(commit);
87
88 for (parents = commit->parents;
89 parents;
90 parents = parents->next)
91 mark_common(parents->item, 0, dont_parse);
92 }
93 }
94}
95
96/*
97 Get the next rev to send, ignoring the common.
98*/
99
Timo Hirvonen962554c2006-02-26 17:13:46 +0200100static const unsigned char* get_rev(void)
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200101{
102 struct commit *commit = NULL;
103
104 while (commit == NULL) {
105 unsigned int mark;
106 struct commit_list* parents;
107
108 if (rev_list == NULL || non_common_revs == 0)
109 return NULL;
110
111 commit = rev_list->item;
112 if (!(commit->object.parsed))
113 parse_commit(commit);
114 commit->object.flags |= POPPED;
115 if (!(commit->object.flags & COMMON))
116 non_common_revs--;
Junio C Hamanoa6080a02007-06-07 00:04:01 -0700117
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200118 parents = commit->parents;
119
120 if (commit->object.flags & COMMON) {
121 /* do not send "have", and ignore ancestors */
122 commit = NULL;
123 mark = COMMON | SEEN;
124 } else if (commit->object.flags & COMMON_REF)
125 /* send "have", and ignore ancestors */
126 mark = COMMON | SEEN;
127 else
128 /* send "have", also for its ancestors */
129 mark = SEEN;
130
131 while (parents) {
132 if (!(parents->item->object.flags & SEEN))
133 rev_list_push(parents->item, mark);
134 if (mark & COMMON)
135 mark_common(parents->item, 1, 0);
136 parents = parents->next;
137 }
138
139 rev_list = rev_list->next;
140 }
141
142 return commit->object.sha1;
143}
Johannes Schindelin0a8944d2005-10-19 16:14:34 -0700144
Junio C Hamano33b83032005-08-12 02:08:29 -0700145static int find_common(int fd[2], unsigned char *result_sha1,
146 struct ref *refs)
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700147{
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700148 int fetching;
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200149 int count = 0, flushes = 0, retval;
150 const unsigned char *sha1;
Junio C Hamanof061e5f2006-05-24 21:48:34 -0700151 unsigned in_vain = 0;
152 int got_continue = 0;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700153
Junio C Hamanocb5d7092006-09-20 21:47:42 -0700154 for_each_ref(rev_list_insert_ref, NULL);
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200155
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700156 fetching = 0;
157 for ( ; refs ; refs = refs->next) {
Junio C Hamano33b83032005-08-12 02:08:29 -0700158 unsigned char *remote = refs->old_sha1;
Junio C Hamano4dab94d2005-10-19 18:28:17 -0700159 struct object *o;
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700160
Johannes Schindelin0a8944d2005-10-19 16:14:34 -0700161 /*
Junio C Hamano4dab94d2005-10-19 18:28:17 -0700162 * If that object is complete (i.e. it is an ancestor of a
163 * local ref), we tell them we have it but do not have to
164 * tell them about its ancestors, which they already know
165 * about.
Junio C Hamanof1f0a2b2005-10-19 21:55:49 -0700166 *
167 * We use lookup_object here because we are only
168 * interested in the case we *know* the object is
169 * reachable and we have already scanned it.
Junio C Hamano4dab94d2005-10-19 18:28:17 -0700170 */
Junio C Hamanof1f0a2b2005-10-19 21:55:49 -0700171 if (((o = lookup_object(remote)) != NULL) &&
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200172 (o->flags & COMPLETE)) {
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700173 continue;
Johannes Schindelin0a8944d2005-10-19 16:14:34 -0700174 }
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200175
Junio C Hamano583b7ea2006-06-21 00:30:21 -0700176 if (!fetching)
Johannes Schindelinb0e90892007-02-23 20:03:10 +0100177 packet_write(fd[1], "want %s%s%s%s%s%s%s\n",
Junio C Hamano583b7ea2006-06-21 00:30:21 -0700178 sha1_to_hex(remote),
179 (multi_ack ? " multi_ack" : ""),
Junio C Hamanod47f3db2006-09-10 16:27:08 -0700180 (use_sideband == 2 ? " side-band-64k" : ""),
181 (use_sideband == 1 ? " side-band" : ""),
Nicolas Pitree4fe4b82006-09-26 11:27:39 -0400182 (use_thin_pack ? " thin-pack" : ""),
Johannes Schindelinb0e90892007-02-23 20:03:10 +0100183 (no_progress ? " no-progress" : ""),
Nicolas Pitree4fe4b82006-09-26 11:27:39 -0400184 " ofs-delta");
Junio C Hamano583b7ea2006-06-21 00:30:21 -0700185 else
186 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700187 fetching++;
Junio C Hamano33b83032005-08-12 02:08:29 -0700188 }
Johannes Schindelined09aef2006-10-30 20:09:06 +0100189 if (is_repository_shallow())
190 write_shallow_commits(fd[1], 1);
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100191 if (depth > 0)
192 packet_write(fd[1], "deepen %d", depth);
Linus Torvaldsfb9040c2005-07-04 15:29:17 -0700193 packet_flush(fd[1]);
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700194 if (!fetching)
195 return 1;
Johannes Schindelin0a8944d2005-10-19 16:14:34 -0700196
Junio C Hamanocf01bd52006-11-13 22:04:56 -0800197 if (depth > 0) {
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100198 char line[1024];
199 unsigned char sha1[20];
200 int len;
201
202 while ((len = packet_read_line(fd[0], line, sizeof(line)))) {
Junio C Hamano599065a2007-02-20 01:54:00 -0800203 if (!prefixcmp(line, "shallow ")) {
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100204 if (get_sha1_hex(line + 8, sha1))
205 die("invalid shallow line: %s", line);
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100206 register_shallow(sha1);
Junio C Hamanocf01bd52006-11-13 22:04:56 -0800207 continue;
208 }
Junio C Hamano599065a2007-02-20 01:54:00 -0800209 if (!prefixcmp(line, "unshallow ")) {
Johannes Schindelinf53514b2006-10-30 20:09:53 +0100210 if (get_sha1_hex(line + 10, sha1))
211 die("invalid unshallow line: %s", line);
212 if (!lookup_object(sha1))
213 die("object not found: %s", line);
214 /* make sure that it is parsed as shallow */
215 parse_object(sha1);
216 if (unregister_shallow(sha1))
217 die("no shallow found: %s", line);
Junio C Hamanocf01bd52006-11-13 22:04:56 -0800218 continue;
219 }
220 die("expected shallow/unshallow, got %s", line);
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100221 }
222 }
223
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200224 flushes = 0;
Linus Torvalds75bfc6c2005-07-04 16:35:13 -0700225 retval = -1;
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200226 while ((sha1 = get_rev())) {
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700227 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
Junio C Hamano33b83032005-08-12 02:08:29 -0700228 if (verbose)
229 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
Junio C Hamanof061e5f2006-05-24 21:48:34 -0700230 in_vain++;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700231 if (!(31 & ++count)) {
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200232 int ack;
233
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700234 packet_flush(fd[1]);
235 flushes++;
236
237 /*
238 * We keep one window "ahead" of the other side, and
239 * will wait for an ACK only on the next one
240 */
241 if (count == 32)
242 continue;
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200243
244 do {
245 ack = get_ack(fd[0], result_sha1);
246 if (verbose && ack)
247 fprintf(stderr, "got ack %d %s\n", ack,
248 sha1_to_hex(result_sha1));
249 if (ack == 1) {
250 flushes = 0;
251 multi_ack = 0;
252 retval = 0;
253 goto done;
254 } else if (ack == 2) {
255 struct commit *commit =
256 lookup_commit(result_sha1);
257 mark_common(commit, 0, 1);
258 retval = 0;
Junio C Hamanof061e5f2006-05-24 21:48:34 -0700259 in_vain = 0;
260 got_continue = 1;
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200261 }
262 } while (ack);
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700263 flushes--;
Junio C Hamanof061e5f2006-05-24 21:48:34 -0700264 if (got_continue && MAX_IN_VAIN < in_vain) {
265 if (verbose)
266 fprintf(stderr, "giving up\n");
267 break; /* give up */
268 }
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700269 }
270 }
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200271done:
Linus Torvalds75bfc6c2005-07-04 16:35:13 -0700272 packet_write(fd[1], "done\n");
Junio C Hamano33b83032005-08-12 02:08:29 -0700273 if (verbose)
274 fprintf(stderr, "done\n");
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200275 if (retval != 0) {
276 multi_ack = 0;
Johannes Schindelin23d61f82005-10-28 04:46:27 +0200277 flushes++;
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200278 }
279 while (flushes || multi_ack) {
280 int ack = get_ack(fd[0], result_sha1);
281 if (ack) {
Junio C Hamano33b83032005-08-12 02:08:29 -0700282 if (verbose)
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200283 fprintf(stderr, "got ack (%d) %s\n", ack,
284 sha1_to_hex(result_sha1));
285 if (ack == 1)
286 return 0;
287 multi_ack = 1;
288 continue;
Junio C Hamano33b83032005-08-12 02:08:29 -0700289 }
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200290 flushes--;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700291 }
Linus Torvalds75bfc6c2005-07-04 16:35:13 -0700292 return retval;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700293}
294
David Rientjes96f1e582006-08-15 10:23:48 -0700295static struct commit_list *complete;
Junio C Hamano49bb8052005-10-19 14:27:02 -0700296
Junio C Hamano8da19772006-09-20 22:02:01 -0700297static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
Junio C Hamano49bb8052005-10-19 14:27:02 -0700298{
299 struct object *o = parse_object(sha1);
300
Linus Torvalds19746322006-07-11 20:45:31 -0700301 while (o && o->type == OBJ_TAG) {
Junio C Hamanof1f0a2b2005-10-19 21:55:49 -0700302 struct tag *t = (struct tag *) o;
303 if (!t->tagged)
304 break; /* broken repository */
Junio C Hamano49bb8052005-10-19 14:27:02 -0700305 o->flags |= COMPLETE;
Junio C Hamanof1f0a2b2005-10-19 21:55:49 -0700306 o = parse_object(t->tagged->sha1);
Junio C Hamano49bb8052005-10-19 14:27:02 -0700307 }
Linus Torvalds19746322006-07-11 20:45:31 -0700308 if (o && o->type == OBJ_COMMIT) {
Junio C Hamano49bb8052005-10-19 14:27:02 -0700309 struct commit *commit = (struct commit *)o;
310 commit->object.flags |= COMPLETE;
311 insert_by_date(commit, &complete);
312 }
313 return 0;
314}
315
316static void mark_recent_complete_commits(unsigned long cutoff)
317{
318 while (complete && cutoff <= complete->item->date) {
319 if (verbose)
320 fprintf(stderr, "Marking %s as complete\n",
321 sha1_to_hex(complete->item->object.sha1));
322 pop_most_recent_commit(&complete, COMPLETE);
323 }
324}
325
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200326static void filter_refs(struct ref **refs, int nr_match, char **match)
327{
Junio C Hamano95460102006-05-11 15:28:44 -0700328 struct ref **return_refs;
329 struct ref *newlist = NULL;
330 struct ref **newtail = &newlist;
331 struct ref *ref, *next;
332 struct ref *fastarray[32];
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200333
Junio C Hamano95460102006-05-11 15:28:44 -0700334 if (nr_match && !fetch_all) {
335 if (ARRAY_SIZE(fastarray) < nr_match)
336 return_refs = xcalloc(nr_match, sizeof(struct ref *));
337 else {
338 return_refs = fastarray;
339 memset(return_refs, 0, sizeof(struct ref *) * nr_match);
340 }
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200341 }
Junio C Hamano95460102006-05-11 15:28:44 -0700342 else
343 return_refs = NULL;
344
345 for (ref = *refs; ref; ref = next) {
346 next = ref->next;
347 if (!memcmp(ref->name, "refs/", 5) &&
348 check_ref_format(ref->name + 5))
349 ; /* trash */
Alexandre Julliard4bcb3102006-11-24 16:00:13 +0100350 else if (fetch_all &&
Junio C Hamanocc44c762007-02-20 01:53:29 -0800351 (!depth || prefixcmp(ref->name, "refs/tags/") )) {
Junio C Hamano95460102006-05-11 15:28:44 -0700352 *newtail = ref;
353 ref->next = NULL;
354 newtail = &ref->next;
355 continue;
356 }
357 else {
358 int order = path_match(ref->name, nr_match, match);
359 if (order) {
360 return_refs[order-1] = ref;
361 continue; /* we will link it later */
362 }
363 }
364 free(ref);
365 }
366
367 if (!fetch_all) {
368 int i;
369 for (i = 0; i < nr_match; i++) {
370 ref = return_refs[i];
371 if (ref) {
372 *newtail = ref;
373 ref->next = NULL;
374 newtail = &ref->next;
375 }
376 }
377 if (return_refs != fastarray)
378 free(return_refs);
379 }
380 *refs = newlist;
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200381}
382
383static int everything_local(struct ref **refs, int nr_match, char **match)
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700384{
Junio C Hamano49bb8052005-10-19 14:27:02 -0700385 struct ref *ref;
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700386 int retval;
Junio C Hamano49bb8052005-10-19 14:27:02 -0700387 unsigned long cutoff = 0;
388
389 track_object_refs = 0;
390 save_commit_buffer = 0;
391
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200392 for (ref = *refs; ref; ref = ref->next) {
Junio C Hamano49bb8052005-10-19 14:27:02 -0700393 struct object *o;
394
395 o = parse_object(ref->old_sha1);
396 if (!o)
397 continue;
398
399 /* We already have it -- which may mean that we were
400 * in sync with the other side at some time after
401 * that (it is OK if we guess wrong here).
402 */
Linus Torvalds19746322006-07-11 20:45:31 -0700403 if (o->type == OBJ_COMMIT) {
Junio C Hamano49bb8052005-10-19 14:27:02 -0700404 struct commit *commit = (struct commit *)o;
405 if (!cutoff || cutoff < commit->date)
406 cutoff = commit->date;
407 }
408 }
409
Johannes Schindelinf53514b2006-10-30 20:09:53 +0100410 if (!depth) {
411 for_each_ref(mark_complete, NULL);
412 if (cutoff)
413 mark_recent_complete_commits(cutoff);
414 }
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700415
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200416 /*
417 * Mark all complete remote refs as common refs.
418 * Don't mark them common yet; the server has to be told so first.
419 */
420 for (ref = *refs; ref; ref = ref->next) {
Junio C Hamano9534f402005-11-02 15:19:13 -0800421 struct object *o = deref_tag(lookup_object(ref->old_sha1),
422 NULL, 0);
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200423
Linus Torvalds19746322006-07-11 20:45:31 -0700424 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200425 continue;
426
427 if (!(o->flags & SEEN)) {
428 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
429
430 mark_common((struct commit *)o, 1, 1);
431 }
432 }
433
434 filter_refs(refs, nr_match, match);
435
436 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
437 const unsigned char *remote = ref->old_sha1;
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700438 unsigned char local[20];
Junio C Hamano49bb8052005-10-19 14:27:02 -0700439 struct object *o;
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700440
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200441 o = lookup_object(remote);
Junio C Hamano49bb8052005-10-19 14:27:02 -0700442 if (!o || !(o->flags & COMPLETE)) {
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700443 retval = 0;
444 if (!verbose)
445 continue;
446 fprintf(stderr,
447 "want %s (%s)\n", sha1_to_hex(remote),
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200448 ref->name);
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700449 continue;
450 }
451
Shawn Pearcee7024962006-08-23 02:49:00 -0400452 hashcpy(ref->new_sha1, local);
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700453 if (!verbose)
454 continue;
455 fprintf(stderr,
456 "already have %s (%s)\n", sha1_to_hex(remote),
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200457 ref->name);
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700458 }
459 return retval;
460}
461
Nicolas Pitreda093d32006-11-01 17:06:23 -0500462static pid_t setup_sideband(int fd[2], int xd[2])
463{
464 pid_t side_pid;
465
466 if (!use_sideband) {
467 fd[0] = xd[0];
468 fd[1] = xd[1];
469 return 0;
470 }
471 /* xd[] is talking with upload-pack; subprocess reads from
472 * xd[0], spits out band#2 to stderr, and feeds us band#1
473 * through our fd[0].
474 */
475 if (pipe(fd) < 0)
476 die("fetch-pack: unable to set up pipe");
477 side_pid = fork();
478 if (side_pid < 0)
479 die("fetch-pack: unable to fork off sideband demultiplexer");
480 if (!side_pid) {
481 /* subprocess */
482 close(fd[0]);
483 if (xd[0] != xd[1])
484 close(xd[1]);
485 if (recv_sideband("fetch-pack", xd[0], fd[1], 2))
486 exit(1);
487 exit(0);
488 }
489 close(xd[0]);
490 close(fd[1]);
491 fd[1] = xd[1];
492 return side_pid;
493}
494
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800495static int get_pack(int xd[2])
Nicolas Pitreda093d32006-11-01 17:06:23 -0500496{
497 int status;
498 pid_t pid, side_pid;
499 int fd[2];
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800500 const char *argv[20];
501 char keep_arg[256];
502 char hdr_arg[256];
503 const char **av;
504 int do_keep = keep_pack;
Nicolas Pitreda093d32006-11-01 17:06:23 -0500505
506 side_pid = setup_sideband(fd, xd);
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800507
508 av = argv;
509 *hdr_arg = 0;
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800510 if (unpack_limit) {
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800511 struct pack_header header;
512
513 if (read_pack_header(fd[0], &header))
514 die("protocol error: bad pack header");
515 snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
516 ntohl(header.hdr_version), ntohl(header.hdr_entries));
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800517 if (ntohl(header.hdr_entries) < unpack_limit)
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800518 do_keep = 0;
519 else
520 do_keep = 1;
521 }
522
523 if (do_keep) {
524 *av++ = "index-pack";
525 *av++ = "--stdin";
Johannes Schindelin83a5ad62007-02-20 03:01:44 +0100526 if (!quiet && !no_progress)
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800527 *av++ = "-v";
528 if (use_thin_pack)
529 *av++ = "--fix-thin";
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800530 if (keep_pack > 1 || unpack_limit) {
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800531 int s = sprintf(keep_arg,
532 "--keep=fetch-pack %d on ", getpid());
533 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
534 strcpy(keep_arg + s, "localhost");
535 *av++ = keep_arg;
536 }
537 }
538 else {
539 *av++ = "unpack-objects";
540 if (quiet)
541 *av++ = "-q";
542 }
543 if (*hdr_arg)
544 *av++ = hdr_arg;
545 *av++ = NULL;
546
Nicolas Pitreda093d32006-11-01 17:06:23 -0500547 pid = fork();
548 if (pid < 0)
549 die("fetch-pack: unable to fork off %s", argv[0]);
550 if (!pid) {
551 dup2(fd[0], 0);
552 close(fd[0]);
553 close(fd[1]);
554 execv_git_cmd(argv);
555 die("%s exec failed", argv[0]);
556 }
557 close(fd[0]);
558 close(fd[1]);
559 while (waitpid(pid, &status, 0) < 0) {
560 if (errno != EINTR)
561 die("waiting for %s: %s", argv[0], strerror(errno));
562 }
563 if (WIFEXITED(status)) {
564 int code = WEXITSTATUS(status);
565 if (code)
566 die("%s died with error code %d", argv[0], code);
567 return 0;
568 }
569 if (WIFSIGNALED(status)) {
570 int sig = WTERMSIG(status);
571 die("%s died of signal %d", argv[0], sig);
572 }
573 die("%s died of unnatural causes %d", argv[0], status);
574}
575
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700576static int fetch_pack(int fd[2], int nr_match, char **match)
577{
Linus Torvaldsd1c133f2005-07-16 13:55:50 -0700578 struct ref *ref;
579 unsigned char sha1[20];
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700580
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200581 get_remote_heads(fd[0], &ref, 0, NULL, 0);
Johannes Schindelined09aef2006-10-30 20:09:06 +0100582 if (is_repository_shallow() && !server_supports("shallow"))
583 die("Server does not support shallow clients");
Johannes Schindelinc4c86f02005-10-28 04:50:26 +0200584 if (server_supports("multi_ack")) {
585 if (verbose)
586 fprintf(stderr, "Server supports multi_ack\n");
587 multi_ack = 1;
588 }
Junio C Hamanod47f3db2006-09-10 16:27:08 -0700589 if (server_supports("side-band-64k")) {
590 if (verbose)
591 fprintf(stderr, "Server supports side-band-64k\n");
592 use_sideband = 2;
593 }
594 else if (server_supports("side-band")) {
Junio C Hamano583b7ea2006-06-21 00:30:21 -0700595 if (verbose)
596 fprintf(stderr, "Server supports side-band\n");
597 use_sideband = 1;
598 }
Linus Torvaldsd1c133f2005-07-16 13:55:50 -0700599 if (!ref) {
Linus Torvaldsfb9040c2005-07-04 15:29:17 -0700600 packet_flush(fd[1]);
Linus Torvaldsd1c133f2005-07-16 13:55:50 -0700601 die("no matching remote head");
Linus Torvaldsfb9040c2005-07-04 15:29:17 -0700602 }
Johannes Schindelin1baaae52005-10-28 04:47:07 +0200603 if (everything_local(&ref, nr_match, match)) {
Linus Torvalds2759cbc2005-10-18 11:35:17 -0700604 packet_flush(fd[1]);
605 goto all_done;
606 }
Junio C Hamano33b83032005-08-12 02:08:29 -0700607 if (find_common(fd, sha1, ref) < 0)
Nicolas Pitreda093d32006-11-01 17:06:23 -0500608 if (keep_pack != 1)
Junio C Hamanodfeff662006-03-20 00:21:10 -0800609 /* When cloning, it is not unusual to have
610 * no common commit.
611 */
612 fprintf(stderr, "warning: no common commits\n");
Junio C Hamanoad897212005-12-14 22:17:38 -0800613
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800614 if (get_pack(fd))
Junio C Hamanoad897212005-12-14 22:17:38 -0800615 die("git-fetch-pack: fetch failed.");
616
617 all_done:
618 while (ref) {
619 printf("%s %s\n",
620 sha1_to_hex(ref->old_sha1), ref->name);
621 ref = ref->next;
Linus Torvalds75bfc6c2005-07-04 16:35:13 -0700622 }
Junio C Hamanoad897212005-12-14 22:17:38 -0800623 return 0;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700624}
625
Junio C Hamano310b86d2006-11-25 01:33:06 -0800626static int remove_duplicates(int nr_heads, char **heads)
627{
628 int src, dst;
629
630 for (src = dst = 0; src < nr_heads; src++) {
631 /* If heads[src] is different from any of
632 * heads[0..dst], push it in.
633 */
634 int i;
635 for (i = 0; i < dst; i++) {
636 if (!strcmp(heads[i], heads[src]))
637 break;
638 }
639 if (i < dst)
640 continue;
641 if (src != dst)
642 heads[dst] = heads[src];
643 dst++;
644 }
645 heads[dst] = 0;
646 return dst;
647}
648
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800649static int fetch_pack_config(const char *var, const char *value)
650{
651 if (strcmp(var, "fetch.unpacklimit") == 0) {
Junio C Hamanoe28714c2007-01-24 17:02:15 -0800652 fetch_unpack_limit = git_config_int(var, value);
653 return 0;
654 }
655
656 if (strcmp(var, "transfer.unpacklimit") == 0) {
657 transfer_unpack_limit = git_config_int(var, value);
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800658 return 0;
659 }
660
661 return git_default_config(var, value);
662}
663
Junio C Hamano54b9e022007-01-02 11:22:08 -0800664static struct lock_file lock;
665
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700666int main(int argc, char **argv)
667{
668 int i, ret, nr_heads;
669 char *dest = NULL, **heads;
670 int fd[2];
671 pid_t pid;
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100672 struct stat st;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700673
Junio C Hamano5a327712005-11-26 00:47:59 -0800674 setup_git_directory();
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800675 git_config(fetch_pack_config);
Junio C Hamano5a327712005-11-26 00:47:59 -0800676
Junio C Hamanoe28714c2007-01-24 17:02:15 -0800677 if (0 <= transfer_unpack_limit)
678 unpack_limit = transfer_unpack_limit;
679 else if (0 <= fetch_unpack_limit)
680 unpack_limit = fetch_unpack_limit;
681
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700682 nr_heads = 0;
683 heads = NULL;
684 for (i = 1; i < argc; i++) {
685 char *arg = argv[i];
686
687 if (*arg == '-') {
Junio C Hamano599065a2007-02-20 01:54:00 -0800688 if (!prefixcmp(arg, "--upload-pack=")) {
Uwe Kleine-König27dca072007-01-23 09:20:17 +0100689 uploadpack = arg + 14;
690 continue;
691 }
Junio C Hamano599065a2007-02-20 01:54:00 -0800692 if (!prefixcmp(arg, "--exec=")) {
Uwe Kleine-König27dca072007-01-23 09:20:17 +0100693 uploadpack = arg + 7;
Junio C Hamano8b3d9dc2005-07-14 00:08:37 -0700694 continue;
695 }
Junio C Hamano2247efb2005-12-18 01:55:29 -0800696 if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
Junio C Hamano33b83032005-08-12 02:08:29 -0700697 quiet = 1;
698 continue;
699 }
Junio C Hamano2247efb2005-12-18 01:55:29 -0800700 if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
Nicolas Pitreda093d32006-11-01 17:06:23 -0500701 keep_pack++;
Junio C Hamanoaf7cf262007-01-24 16:47:24 -0800702 unpack_limit = 0;
Junio C Hamano9e10fd12007-01-22 22:37:33 -0800703 continue;
704 }
Junio C Hamanob19696c2006-02-20 00:38:39 -0800705 if (!strcmp("--thin", arg)) {
706 use_thin_pack = 1;
707 continue;
708 }
Junio C Hamanodfeff662006-03-20 00:21:10 -0800709 if (!strcmp("--all", arg)) {
710 fetch_all = 1;
711 continue;
712 }
Junio C Hamano33b83032005-08-12 02:08:29 -0700713 if (!strcmp("-v", arg)) {
714 verbose = 1;
715 continue;
716 }
Junio C Hamano599065a2007-02-20 01:54:00 -0800717 if (!prefixcmp(arg, "--depth=")) {
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100718 depth = strtol(arg + 8, NULL, 0);
719 if (stat(git_path("shallow"), &st))
720 st.st_mtime = 0;
721 continue;
722 }
Johannes Schindelin83a5ad62007-02-20 03:01:44 +0100723 if (!strcmp("--no-progress", arg)) {
724 no_progress = 1;
725 continue;
726 }
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700727 usage(fetch_pack_usage);
728 }
729 dest = arg;
730 heads = argv + i + 1;
731 nr_heads = argc - i - 1;
732 break;
733 }
734 if (!dest)
735 usage(fetch_pack_usage);
Michael S. Tsirkin7841ce72007-05-16 20:09:41 +0300736 pid = git_connect(fd, dest, uploadpack, verbose ? CONNECT_VERBOSE : 0);
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700737 if (pid < 0)
738 return 1;
Junio C Hamano310b86d2006-11-25 01:33:06 -0800739 if (heads && nr_heads)
740 nr_heads = remove_duplicates(nr_heads, heads);
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700741 ret = fetch_pack(fd, nr_heads, heads);
742 close(fd[0]);
743 close(fd[1]);
Franck Bui-Huu8a5dbef2006-09-13 10:26:47 +0200744 ret |= finish_connect(pid);
Junio C Hamano9e5d2b42005-11-06 00:09:59 -0800745
746 if (!ret && nr_heads) {
747 /* If the heads to pull were given, we should have
748 * consumed all of them by matching the remote.
749 * Otherwise, 'git-fetch remote no-such-ref' would
750 * silently succeed without issuing an error.
751 */
752 for (i = 0; i < nr_heads; i++)
753 if (heads[i] && heads[i][0]) {
754 error("no such remote ref %s", heads[i]);
755 ret = 1;
756 }
757 }
758
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100759 if (!ret && depth > 0) {
760 struct cache_time mtime;
761 char *shallow = git_path("shallow");
762 int fd;
763
764 mtime.sec = st.st_mtime;
765#ifdef USE_NSEC
766 mtime.usec = st.st_mtim.usec;
767#endif
768 if (stat(shallow, &st)) {
769 if (mtime.sec)
770 die("shallow file was removed during fetch");
771 } else if (st.st_mtime != mtime.sec
772#ifdef USE_NSEC
773 || st.st_mtim.usec != mtime.usec
774#endif
775 )
776 die("shallow file was changed during fetch");
777
778 fd = hold_lock_file_for_update(&lock, shallow, 1);
779 if (!write_shallow_commits(fd, 0)) {
Alexandre Julliardd6491e32006-11-24 15:58:04 +0100780 unlink(shallow);
Johannes Schindelin016e6cc2006-10-30 20:09:29 +0100781 rollback_lock_file(&lock);
782 } else {
783 close(fd);
784 commit_lock_file(&lock);
785 }
786 }
787
Franck Bui-Huu8a5dbef2006-09-13 10:26:47 +0200788 return !!ret;
Linus Torvaldsdef88e92005-07-04 13:26:53 -0700789}