Use the asyncronous function infrastructure in builtin-fetch-pack.c.
[git/git.git] / builtin-fetch-pack.c
CommitLineData
def88e9a 1#include "cache.h"
fb9040cc 2#include "refs.h"
def88e9a 3#include "pkt-line.h"
49bb805e
JH
4#include "commit.h"
5#include "tag.h"
da093d37 6#include "exec_cmd.h"
9e10fd1a 7#include "pack.h"
da093d37 8#include "sideband.h"
2d4177c0 9#include "fetch-pack.h"
477822c3 10#include "run-command.h"
def88e9a 11
e28714c5
JH
12static int transfer_unpack_limit = -1;
13static int fetch_unpack_limit = -1;
af7cf268 14static int unpack_limit = 100;
fa740529
SP
15static struct fetch_pack_args args;
16
33b83034 17static const char fetch_pack_usage[] =
83a5ad61 18"git-fetch-pack [--all] [--quiet|-q] [--keep|-k] [--thin] [--upload-pack=<git-upload-pack>] [--depth=<n>] [--no-progress] [-v] [<host>:]<directory> [<refs>...]";
27dca07f 19static const char *uploadpack = "git-upload-pack";
def88e9a 20
0a8944dd 21#define COMPLETE (1U << 0)
23d61f83
JS
22#define COMMON (1U << 1)
23#define COMMON_REF (1U << 2)
24#define SEEN (1U << 3)
25#define POPPED (1U << 4)
26
f061e5fd
JH
27/*
28 * After sending this many "have"s if we do not get any new ACK , we
29 * give up traversing our history.
30 */
31#define MAX_IN_VAIN 256
32
96f1e58f
DR
33static struct commit_list *rev_list;
34static int non_common_revs, multi_ack, use_thin_pack, use_sideband;
23d61f83
JS
35
36static void rev_list_push(struct commit *commit, int mark)
37{
38 if (!(commit->object.flags & mark)) {
39 commit->object.flags |= mark;
40
41 if (!(commit->object.parsed))
42 parse_commit(commit);
43
44 insert_by_date(commit, &rev_list);
45
46 if (!(commit->object.flags & COMMON))
47 non_common_revs++;
48 }
49}
50
8da19775 51static int rev_list_insert_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
23d61f83 52{
9534f40b 53 struct object *o = deref_tag(parse_object(sha1), path, 0);
23d61f83 54
1974632c 55 if (o && o->type == OBJ_COMMIT)
23d61f83
JS
56 rev_list_push((struct commit *)o, SEEN);
57
58 return 0;
59}
60
61/*
62 This function marks a rev and its ancestors as common.
63 In some cases, it is desirable to mark only the ancestors (for example
64 when only the server does not yet know that they are common).
65*/
66
67static void mark_common(struct commit *commit,
68 int ancestors_only, int dont_parse)
69{
70 if (commit != NULL && !(commit->object.flags & COMMON)) {
71 struct object *o = (struct object *)commit;
72
73 if (!ancestors_only)
74 o->flags |= COMMON;
75
76 if (!(o->flags & SEEN))
77 rev_list_push(commit, SEEN);
78 else {
79 struct commit_list *parents;
80
81 if (!ancestors_only && !(o->flags & POPPED))
82 non_common_revs--;
83 if (!o->parsed && !dont_parse)
84 parse_commit(commit);
85
86 for (parents = commit->parents;
87 parents;
88 parents = parents->next)
89 mark_common(parents->item, 0, dont_parse);
90 }
91 }
92}
93
94/*
95 Get the next rev to send, ignoring the common.
96*/
97
962554c6 98static const unsigned char* get_rev(void)
23d61f83
JS
99{
100 struct commit *commit = NULL;
101
102 while (commit == NULL) {
103 unsigned int mark;
104 struct commit_list* parents;
105
106 if (rev_list == NULL || non_common_revs == 0)
107 return NULL;
108
109 commit = rev_list->item;
110 if (!(commit->object.parsed))
111 parse_commit(commit);
112 commit->object.flags |= POPPED;
113 if (!(commit->object.flags & COMMON))
114 non_common_revs--;
a6080a0a 115
23d61f83
JS
116 parents = commit->parents;
117
118 if (commit->object.flags & COMMON) {
119 /* do not send "have", and ignore ancestors */
120 commit = NULL;
121 mark = COMMON | SEEN;
122 } else if (commit->object.flags & COMMON_REF)
123 /* send "have", and ignore ancestors */
124 mark = COMMON | SEEN;
125 else
126 /* send "have", also for its ancestors */
127 mark = SEEN;
128
129 while (parents) {
130 if (!(parents->item->object.flags & SEEN))
131 rev_list_push(parents->item, mark);
132 if (mark & COMMON)
133 mark_common(parents->item, 1, 0);
134 parents = parents->next;
135 }
136
137 rev_list = rev_list->next;
138 }
139
140 return commit->object.sha1;
141}
0a8944dd 142
33b83034
JH
143static int find_common(int fd[2], unsigned char *result_sha1,
144 struct ref *refs)
def88e9a 145{
2759cbc7 146 int fetching;
23d61f83
JS
147 int count = 0, flushes = 0, retval;
148 const unsigned char *sha1;
f061e5fd
JH
149 unsigned in_vain = 0;
150 int got_continue = 0;
23d61f83 151
cb5d709f 152 for_each_ref(rev_list_insert_ref, NULL);
def88e9a 153
2759cbc7
LT
154 fetching = 0;
155 for ( ; refs ; refs = refs->next) {
33b83034 156 unsigned char *remote = refs->old_sha1;
4dab94d5 157 struct object *o;
2759cbc7 158
0a8944dd 159 /*
4dab94d5
JH
160 * If that object is complete (i.e. it is an ancestor of a
161 * local ref), we tell them we have it but do not have to
162 * tell them about its ancestors, which they already know
163 * about.
f1f0a2be
JH
164 *
165 * We use lookup_object here because we are only
166 * interested in the case we *know* the object is
167 * reachable and we have already scanned it.
4dab94d5 168 */
f1f0a2be 169 if (((o = lookup_object(remote)) != NULL) &&
1baaae5e 170 (o->flags & COMPLETE)) {
2759cbc7 171 continue;
0a8944dd 172 }
23d61f83 173
583b7ea3 174 if (!fetching)
b0e90897 175 packet_write(fd[1], "want %s%s%s%s%s%s%s\n",
583b7ea3
JH
176 sha1_to_hex(remote),
177 (multi_ack ? " multi_ack" : ""),
d47f3db7
JH
178 (use_sideband == 2 ? " side-band-64k" : ""),
179 (use_sideband == 1 ? " side-band" : ""),
e4fe4b8e 180 (use_thin_pack ? " thin-pack" : ""),
fa740529 181 (args.no_progress ? " no-progress" : ""),
e4fe4b8e 182 " ofs-delta");
583b7ea3
JH
183 else
184 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
2759cbc7 185 fetching++;
33b83034 186 }
ed09aef0
JS
187 if (is_repository_shallow())
188 write_shallow_commits(fd[1], 1);
fa740529
SP
189 if (args.depth > 0)
190 packet_write(fd[1], "deepen %d", args.depth);
fb9040cc 191 packet_flush(fd[1]);
2759cbc7
LT
192 if (!fetching)
193 return 1;
0a8944dd 194
fa740529 195 if (args.depth > 0) {
016e6ccb
JS
196 char line[1024];
197 unsigned char sha1[20];
198 int len;
199
200 while ((len = packet_read_line(fd[0], line, sizeof(line)))) {
599065a3 201 if (!prefixcmp(line, "shallow ")) {
016e6ccb
JS
202 if (get_sha1_hex(line + 8, sha1))
203 die("invalid shallow line: %s", line);
016e6ccb 204 register_shallow(sha1);
cf01bd52
JH
205 continue;
206 }
599065a3 207 if (!prefixcmp(line, "unshallow ")) {
f53514bc
JS
208 if (get_sha1_hex(line + 10, sha1))
209 die("invalid unshallow line: %s", line);
210 if (!lookup_object(sha1))
211 die("object not found: %s", line);
212 /* make sure that it is parsed as shallow */
213 parse_object(sha1);
214 if (unregister_shallow(sha1))
215 die("no shallow found: %s", line);
cf01bd52
JH
216 continue;
217 }
218 die("expected shallow/unshallow, got %s", line);
016e6ccb
JS
219 }
220 }
221
23d61f83 222 flushes = 0;
75bfc6c2 223 retval = -1;
23d61f83 224 while ((sha1 = get_rev())) {
def88e9a 225 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
fa740529 226 if (args.verbose)
33b83034 227 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
f061e5fd 228 in_vain++;
def88e9a 229 if (!(31 & ++count)) {
c4c86f07
JS
230 int ack;
231
def88e9a
LT
232 packet_flush(fd[1]);
233 flushes++;
234
235 /*
236 * We keep one window "ahead" of the other side, and
237 * will wait for an ACK only on the next one
238 */
239 if (count == 32)
240 continue;
c4c86f07
JS
241
242 do {
243 ack = get_ack(fd[0], result_sha1);
fa740529 244 if (args.verbose && ack)
c4c86f07
JS
245 fprintf(stderr, "got ack %d %s\n", ack,
246 sha1_to_hex(result_sha1));
247 if (ack == 1) {
248 flushes = 0;
249 multi_ack = 0;
250 retval = 0;
251 goto done;
252 } else if (ack == 2) {
253 struct commit *commit =
254 lookup_commit(result_sha1);
255 mark_common(commit, 0, 1);
256 retval = 0;
f061e5fd
JH
257 in_vain = 0;
258 got_continue = 1;
c4c86f07
JS
259 }
260 } while (ack);
def88e9a 261 flushes--;
f061e5fd 262 if (got_continue && MAX_IN_VAIN < in_vain) {
fa740529 263 if (args.verbose)
f061e5fd
JH
264 fprintf(stderr, "giving up\n");
265 break; /* give up */
266 }
def88e9a
LT
267 }
268 }
c4c86f07 269done:
75bfc6c2 270 packet_write(fd[1], "done\n");
fa740529 271 if (args.verbose)
33b83034 272 fprintf(stderr, "done\n");
c4c86f07
JS
273 if (retval != 0) {
274 multi_ack = 0;
23d61f83 275 flushes++;
c4c86f07
JS
276 }
277 while (flushes || multi_ack) {
278 int ack = get_ack(fd[0], result_sha1);
279 if (ack) {
fa740529 280 if (args.verbose)
c4c86f07
JS
281 fprintf(stderr, "got ack (%d) %s\n", ack,
282 sha1_to_hex(result_sha1));
283 if (ack == 1)
284 return 0;
285 multi_ack = 1;
286 continue;
33b83034 287 }
c4c86f07 288 flushes--;
def88e9a 289 }
75bfc6c2 290 return retval;
def88e9a
LT
291}
292
96f1e58f 293static struct commit_list *complete;
49bb805e 294
8da19775 295static int mark_complete(const char *path, const unsigned char *sha1, int flag, void *cb_data)
49bb805e
JH
296{
297 struct object *o = parse_object(sha1);
298
1974632c 299 while (o && o->type == OBJ_TAG) {
f1f0a2be
JH
300 struct tag *t = (struct tag *) o;
301 if (!t->tagged)
302 break; /* broken repository */
49bb805e 303 o->flags |= COMPLETE;
f1f0a2be 304 o = parse_object(t->tagged->sha1);
49bb805e 305 }
1974632c 306 if (o && o->type == OBJ_COMMIT) {
49bb805e
JH
307 struct commit *commit = (struct commit *)o;
308 commit->object.flags |= COMPLETE;
309 insert_by_date(commit, &complete);
310 }
311 return 0;
312}
313
314static void mark_recent_complete_commits(unsigned long cutoff)
315{
316 while (complete && cutoff <= complete->item->date) {
fa740529 317 if (args.verbose)
49bb805e
JH
318 fprintf(stderr, "Marking %s as complete\n",
319 sha1_to_hex(complete->item->object.sha1));
320 pop_most_recent_commit(&complete, COMPLETE);
321 }
322}
323
1baaae5e
JS
324static void filter_refs(struct ref **refs, int nr_match, char **match)
325{
9546010b
JH
326 struct ref **return_refs;
327 struct ref *newlist = NULL;
328 struct ref **newtail = &newlist;
329 struct ref *ref, *next;
330 struct ref *fastarray[32];
331
fa740529 332 if (nr_match && !args.fetch_all) {
9546010b
JH
333 if (ARRAY_SIZE(fastarray) < nr_match)
334 return_refs = xcalloc(nr_match, sizeof(struct ref *));
335 else {
336 return_refs = fastarray;
337 memset(return_refs, 0, sizeof(struct ref *) * nr_match);
338 }
339 }
340 else
341 return_refs = NULL;
342
343 for (ref = *refs; ref; ref = next) {
344 next = ref->next;
345 if (!memcmp(ref->name, "refs/", 5) &&
346 check_ref_format(ref->name + 5))
347 ; /* trash */
fa740529
SP
348 else if (args.fetch_all &&
349 (!args.depth || prefixcmp(ref->name, "refs/tags/") )) {
9546010b
JH
350 *newtail = ref;
351 ref->next = NULL;
352 newtail = &ref->next;
353 continue;
354 }
355 else {
356 int order = path_match(ref->name, nr_match, match);
357 if (order) {
358 return_refs[order-1] = ref;
359 continue; /* we will link it later */
360 }
361 }
362 free(ref);
363 }
364
fa740529 365 if (!args.fetch_all) {
9546010b
JH
366 int i;
367 for (i = 0; i < nr_match; i++) {
368 ref = return_refs[i];
369 if (ref) {
370 *newtail = ref;
371 ref->next = NULL;
372 newtail = &ref->next;
373 }
374 }
375 if (return_refs != fastarray)
376 free(return_refs);
1baaae5e 377 }
9546010b 378 *refs = newlist;
1baaae5e
JS
379}
380
381static int everything_local(struct ref **refs, int nr_match, char **match)
2759cbc7 382{
49bb805e 383 struct ref *ref;
2759cbc7 384 int retval;
49bb805e
JH
385 unsigned long cutoff = 0;
386
387 track_object_refs = 0;
388 save_commit_buffer = 0;
389
1baaae5e 390 for (ref = *refs; ref; ref = ref->next) {
49bb805e
JH
391 struct object *o;
392
393 o = parse_object(ref->old_sha1);
394 if (!o)
395 continue;
396
397 /* We already have it -- which may mean that we were
398 * in sync with the other side at some time after
399 * that (it is OK if we guess wrong here).
400 */
1974632c 401 if (o->type == OBJ_COMMIT) {
49bb805e
JH
402 struct commit *commit = (struct commit *)o;
403 if (!cutoff || cutoff < commit->date)
404 cutoff = commit->date;
405 }
406 }
407
fa740529 408 if (!args.depth) {
f53514bc
JS
409 for_each_ref(mark_complete, NULL);
410 if (cutoff)
411 mark_recent_complete_commits(cutoff);
412 }
2759cbc7 413
1baaae5e
JS
414 /*
415 * Mark all complete remote refs as common refs.
416 * Don't mark them common yet; the server has to be told so first.
417 */
418 for (ref = *refs; ref; ref = ref->next) {
9534f40b
JH
419 struct object *o = deref_tag(lookup_object(ref->old_sha1),
420 NULL, 0);
1baaae5e 421
1974632c 422 if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE))
1baaae5e
JS
423 continue;
424
425 if (!(o->flags & SEEN)) {
426 rev_list_push((struct commit *)o, COMMON_REF | SEEN);
427
428 mark_common((struct commit *)o, 1, 1);
429 }
430 }
431
432 filter_refs(refs, nr_match, match);
433
434 for (retval = 1, ref = *refs; ref ; ref = ref->next) {
435 const unsigned char *remote = ref->old_sha1;
2759cbc7 436 unsigned char local[20];
49bb805e 437 struct object *o;
2759cbc7 438
1baaae5e 439 o = lookup_object(remote);
49bb805e 440 if (!o || !(o->flags & COMPLETE)) {
2759cbc7 441 retval = 0;
fa740529 442 if (!args.verbose)
2759cbc7
LT
443 continue;
444 fprintf(stderr,
445 "want %s (%s)\n", sha1_to_hex(remote),
1baaae5e 446 ref->name);
2759cbc7
LT
447 continue;
448 }
449
e702496e 450 hashcpy(ref->new_sha1, local);
fa740529 451 if (!args.verbose)
2759cbc7
LT
452 continue;
453 fprintf(stderr,
454 "already have %s (%s)\n", sha1_to_hex(remote),
1baaae5e 455 ref->name);
2759cbc7
LT
456 }
457 return retval;
458}
459
088fab5f 460static int sideband_demux(int fd, void *data)
da093d37 461{
088fab5f 462 int *xd = data;
da093d37 463
088fab5f
JS
464 close(xd[1]);
465 return recv_sideband("fetch-pack", xd[0], fd, 2);
466}
467
468static void setup_sideband(int fd[2], int xd[2], struct async *demux)
469{
da093d37
NP
470 if (!use_sideband) {
471 fd[0] = xd[0];
472 fd[1] = xd[1];
088fab5f 473 return;
da093d37
NP
474 }
475 /* xd[] is talking with upload-pack; subprocess reads from
476 * xd[0], spits out band#2 to stderr, and feeds us band#1
088fab5f 477 * through demux->out.
da093d37 478 */
088fab5f
JS
479 demux->proc = sideband_demux;
480 demux->data = xd;
481 if (start_async(demux))
da093d37 482 die("fetch-pack: unable to fork off sideband demultiplexer");
da093d37 483 close(xd[0]);
088fab5f 484 fd[0] = demux->out;
da093d37 485 fd[1] = xd[1];
da093d37
NP
486}
487
1788c39c 488static int get_pack(int xd[2], char **pack_lockfile)
da093d37 489{
088fab5f 490 struct async demux;
da093d37 491 int fd[2];
9e10fd1a
JH
492 const char *argv[20];
493 char keep_arg[256];
494 char hdr_arg[256];
495 const char **av;
fa740529 496 int do_keep = args.keep_pack;
477822c3 497 struct child_process cmd;
da093d37 498
088fab5f 499 setup_sideband(fd, xd, &demux);
9e10fd1a 500
477822c3
JS
501 memset(&cmd, 0, sizeof(cmd));
502 cmd.argv = argv;
9e10fd1a
JH
503 av = argv;
504 *hdr_arg = 0;
fa740529 505 if (!args.keep_pack && unpack_limit) {
9e10fd1a
JH
506 struct pack_header header;
507
508 if (read_pack_header(fd[0], &header))
509 die("protocol error: bad pack header");
510 snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
511 ntohl(header.hdr_version), ntohl(header.hdr_entries));
af7cf268 512 if (ntohl(header.hdr_entries) < unpack_limit)
9e10fd1a
JH
513 do_keep = 0;
514 else
515 do_keep = 1;
516 }
517
518 if (do_keep) {
477822c3
JS
519 if (pack_lockfile)
520 cmd.out = -1;
9e10fd1a
JH
521 *av++ = "index-pack";
522 *av++ = "--stdin";
fa740529 523 if (!args.quiet && !args.no_progress)
9e10fd1a 524 *av++ = "-v";
fa740529 525 if (args.use_thin_pack)
9e10fd1a 526 *av++ = "--fix-thin";
fa740529 527 if (args.lock_pack || unpack_limit) {
9e10fd1a
JH
528 int s = sprintf(keep_arg,
529 "--keep=fetch-pack %d on ", getpid());
530 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
531 strcpy(keep_arg + s, "localhost");
532 *av++ = keep_arg;
533 }
534 }
535 else {
536 *av++ = "unpack-objects";
fa740529 537 if (args.quiet)
9e10fd1a
JH
538 *av++ = "-q";
539 }
540 if (*hdr_arg)
541 *av++ = hdr_arg;
542 *av++ = NULL;
543
477822c3
JS
544 cmd.in = fd[0];
545 cmd.git_cmd = 1;
546 if (start_command(&cmd))
da093d37 547 die("fetch-pack: unable to fork off %s", argv[0]);
da093d37 548 close(fd[1]);
477822c3
JS
549 if (do_keep && pack_lockfile)
550 *pack_lockfile = index_pack_lockfile(cmd.out);
551
552 if (finish_command(&cmd))
553 die("%s failed", argv[0]);
088fab5f
JS
554 if (use_sideband && finish_async(&demux))
555 die("error in sideband demultiplexer");
477822c3 556 return 0;
da093d37
NP
557}
558
1788c39c
SP
559static struct ref *do_fetch_pack(int fd[2],
560 int nr_match,
561 char **match,
562 char **pack_lockfile)
def88e9a 563{
d1c133f5
LT
564 struct ref *ref;
565 unsigned char sha1[20];
def88e9a 566
1baaae5e 567 get_remote_heads(fd[0], &ref, 0, NULL, 0);
ed09aef0
JS
568 if (is_repository_shallow() && !server_supports("shallow"))
569 die("Server does not support shallow clients");
c4c86f07 570 if (server_supports("multi_ack")) {
fa740529 571 if (args.verbose)
c4c86f07
JS
572 fprintf(stderr, "Server supports multi_ack\n");
573 multi_ack = 1;
574 }
d47f3db7 575 if (server_supports("side-band-64k")) {
fa740529 576 if (args.verbose)
d47f3db7
JH
577 fprintf(stderr, "Server supports side-band-64k\n");
578 use_sideband = 2;
579 }
580 else if (server_supports("side-band")) {
fa740529 581 if (args.verbose)
583b7ea3
JH
582 fprintf(stderr, "Server supports side-band\n");
583 use_sideband = 1;
584 }
d1c133f5
LT
585 if (!ref) {
586 packet_flush(fd[1]);
587 die("no matching remote head");
588 }
1baaae5e 589 if (everything_local(&ref, nr_match, match)) {
2759cbc7
LT
590 packet_flush(fd[1]);
591 goto all_done;
592 }
33b83034 593 if (find_common(fd, sha1, ref) < 0)
fa740529 594 if (!args.keep_pack)
dfeff66e
JH
595 /* When cloning, it is not unusual to have
596 * no common commit.
597 */
598 fprintf(stderr, "warning: no common commits\n");
ad897215 599
1788c39c 600 if (get_pack(fd, pack_lockfile))
ad897215
JH
601 die("git-fetch-pack: fetch failed.");
602
603 all_done:
2d4177c0 604 return ref;
def88e9a
LT
605}
606
310b86d4
JH
607static int remove_duplicates(int nr_heads, char **heads)
608{
609 int src, dst;
610
611 for (src = dst = 0; src < nr_heads; src++) {
612 /* If heads[src] is different from any of
613 * heads[0..dst], push it in.
614 */
615 int i;
616 for (i = 0; i < dst; i++) {
617 if (!strcmp(heads[i], heads[src]))
618 break;
619 }
620 if (i < dst)
621 continue;
622 if (src != dst)
623 heads[dst] = heads[src];
624 dst++;
625 }
310b86d4
JH
626 return dst;
627}
628
af7cf268
JH
629static int fetch_pack_config(const char *var, const char *value)
630{
631 if (strcmp(var, "fetch.unpacklimit") == 0) {
e28714c5
JH
632 fetch_unpack_limit = git_config_int(var, value);
633 return 0;
634 }
635
636 if (strcmp(var, "transfer.unpacklimit") == 0) {
637 transfer_unpack_limit = git_config_int(var, value);
af7cf268
JH
638 return 0;
639 }
640
641 return git_default_config(var, value);
642}
643
54b9e022
JH
644static struct lock_file lock;
645
50ab5fd3 646static void fetch_pack_setup(void)
def88e9a 647{
50ab5fd3
SP
648 static int did_setup;
649 if (did_setup)
650 return;
af7cf268 651 git_config(fetch_pack_config);
e28714c5
JH
652 if (0 <= transfer_unpack_limit)
653 unpack_limit = transfer_unpack_limit;
654 else if (0 <= fetch_unpack_limit)
655 unpack_limit = fetch_unpack_limit;
50ab5fd3
SP
656 did_setup = 1;
657}
658
659int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
660{
661 int i, ret, nr_heads;
662 struct ref *ref;
663 char *dest = NULL, **heads;
e28714c5 664
def88e9a
LT
665 nr_heads = 0;
666 heads = NULL;
667 for (i = 1; i < argc; i++) {
2d4177c0 668 const char *arg = argv[i];
def88e9a
LT
669
670 if (*arg == '-') {
599065a3 671 if (!prefixcmp(arg, "--upload-pack=")) {
fa740529 672 args.uploadpack = arg + 14;
27dca07f
UKK
673 continue;
674 }
599065a3 675 if (!prefixcmp(arg, "--exec=")) {
fa740529 676 args.uploadpack = arg + 7;
8b3d9dc0
JH
677 continue;
678 }
2247efb4 679 if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
fa740529 680 args.quiet = 1;
33b83034
JH
681 continue;
682 }
2247efb4 683 if (!strcmp("--keep", arg) || !strcmp("-k", arg)) {
fa740529
SP
684 args.lock_pack = args.keep_pack;
685 args.keep_pack = 1;
9e10fd1a
JH
686 continue;
687 }
b19696c2 688 if (!strcmp("--thin", arg)) {
fa740529 689 args.use_thin_pack = 1;
b19696c2
JH
690 continue;
691 }
dfeff66e 692 if (!strcmp("--all", arg)) {
fa740529 693 args.fetch_all = 1;
dfeff66e
JH
694 continue;
695 }
33b83034 696 if (!strcmp("-v", arg)) {
fa740529 697 args.verbose = 1;
33b83034
JH
698 continue;
699 }
599065a3 700 if (!prefixcmp(arg, "--depth=")) {
fa740529 701 args.depth = strtol(arg + 8, NULL, 0);
016e6ccb
JS
702 continue;
703 }
83a5ad61 704 if (!strcmp("--no-progress", arg)) {
fa740529 705 args.no_progress = 1;
83a5ad61
JS
706 continue;
707 }
def88e9a
LT
708 usage(fetch_pack_usage);
709 }
2d4177c0
DB
710 dest = (char *)arg;
711 heads = (char **)(argv + i + 1);
def88e9a
LT
712 nr_heads = argc - i - 1;
713 break;
714 }
715 if (!dest)
716 usage(fetch_pack_usage);
2d4177c0 717
fa740529 718 ref = fetch_pack(&args, dest, nr_heads, heads, NULL);
2d4177c0
DB
719 ret = !ref;
720
721 while (ref) {
722 printf("%s %s\n",
723 sha1_to_hex(ref->old_sha1), ref->name);
724 ref = ref->next;
725 }
726
727 return ret;
728}
729
fa740529
SP
730struct ref *fetch_pack(struct fetch_pack_args *my_args,
731 const char *dest,
1788c39c
SP
732 int nr_heads,
733 char **heads,
734 char **pack_lockfile)
2d4177c0
DB
735{
736 int i, ret;
737 int fd[2];
98158e9c 738 struct child_process *conn;
2d4177c0
DB
739 struct ref *ref;
740 struct stat st;
741
50ab5fd3 742 fetch_pack_setup();
fa740529
SP
743 memcpy(&args, my_args, sizeof(args));
744 if (args.depth > 0) {
2d4177c0
DB
745 if (stat(git_path("shallow"), &st))
746 st.st_mtime = 0;
747 }
748
98158e9c 749 conn = git_connect(fd, (char *)dest, uploadpack,
fa740529 750 args.verbose ? CONNECT_VERBOSE : 0);
310b86d4
JH
751 if (heads && nr_heads)
752 nr_heads = remove_duplicates(nr_heads, heads);
1788c39c 753 ref = do_fetch_pack(fd, nr_heads, heads, pack_lockfile);
def88e9a
LT
754 close(fd[0]);
755 close(fd[1]);
98158e9c 756 ret = finish_connect(conn);
9e5d2b40
JH
757
758 if (!ret && nr_heads) {
759 /* If the heads to pull were given, we should have
760 * consumed all of them by matching the remote.
761 * Otherwise, 'git-fetch remote no-such-ref' would
762 * silently succeed without issuing an error.
763 */
764 for (i = 0; i < nr_heads; i++)
765 if (heads[i] && heads[i][0]) {
766 error("no such remote ref %s", heads[i]);
767 ret = 1;
768 }
769 }
770
fa740529 771 if (!ret && args.depth > 0) {
016e6ccb
JS
772 struct cache_time mtime;
773 char *shallow = git_path("shallow");
774 int fd;
775
776 mtime.sec = st.st_mtime;
777#ifdef USE_NSEC
778 mtime.usec = st.st_mtim.usec;
779#endif
780 if (stat(shallow, &st)) {
781 if (mtime.sec)
782 die("shallow file was removed during fetch");
783 } else if (st.st_mtime != mtime.sec
784#ifdef USE_NSEC
785 || st.st_mtim.usec != mtime.usec
786#endif
787 )
788 die("shallow file was changed during fetch");
789
790 fd = hold_lock_file_for_update(&lock, shallow, 1);
791 if (!write_shallow_commits(fd, 0)) {
d6491e3a 792 unlink(shallow);
016e6ccb
JS
793 rollback_lock_file(&lock);
794 } else {
795 close(fd);
796 commit_lock_file(&lock);
797 }
798 }
799
2d4177c0
DB
800 if (ret)
801 ref = NULL;
802
803 return ref;
def88e9a 804}