upload-pack.c 20.1 KB
Newer Older
1 2 3
#include "cache.h"
#include "refs.h"
#include "pkt-line.h"
4
#include "sideband.h"
5 6
#include "tag.h"
#include "object.h"
7
#include "commit.h"
8
#include "exec_cmd.h"
9 10 11
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
12
#include "run-command.h"
13
#include "sigchain.h"
14
#include "version.h"
15
#include "string-list.h"
16

17
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<n>] <dir>";
18

19 20 21 22 23 24 25
/* bits #0..7 in revision.h, #8..10 in commit.c */
#define THEY_HAVE	(1u << 11)
#define OUR_REF		(1u << 12)
#define WANTED		(1u << 13)
#define COMMON_KNOWN	(1u << 14)
#define REACHABLE	(1u << 15)

26 27 28
#define SHALLOW		(1u << 16)
#define NOT_SHALLOW	(1u << 17)
#define CLIENT_SHALLOW	(1u << 18)
29
#define HIDDEN_REF	(1u << 19)
30

J
Junio C Hamano 已提交
31
static unsigned long oldest_have;
32

33
static int multi_ack;
J
Junio C Hamano 已提交
34
static int no_done;
35
static int use_thin_pack, use_ofs_delta, use_include_tag;
36
static int no_progress, daemon_mode;
37
static int allow_tip_sha1_in_want;
38
static int shallow_nr;
39 40
static struct object_array have_obj;
static struct object_array want_obj;
41
static struct object_array extra_edge_obj;
42
static unsigned int timeout;
43 44 45
/* 0 for no sideband,
 * otherwise maximum packet size (up to 65520 bytes).
 */
46
static int use_sideband;
47 48
static int advertise_refs;
static int stateless_rpc;
49 50 51 52 53

static void reset_timeout(void)
{
	alarm(timeout);
}
54

55 56
static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
{
57
	if (use_sideband)
58
		return send_sideband(1, fd, data, sz, use_sideband);
59 60 61 62
	if (fd == 3)
		/* emergency quit */
		fd = 2;
	if (fd == 2) {
63
		/* XXX: are we happy to lose stuff here? */
64 65
		xwrite(fd, data, sz);
		return sz;
66
	}
J
Jeff King 已提交
67 68
	write_or_die(fd, data, sz);
	return sz;
69 70
}

J
Junio C Hamano 已提交
71
static FILE *pack_pipe = NULL;
72
static void show_commit(struct commit *commit, void *data)
73 74 75 76 77 78 79 80 81 82 83
{
	if (commit->object.flags & BOUNDARY)
		fputc('-', pack_pipe);
	if (fputs(sha1_to_hex(commit->object.sha1), pack_pipe) < 0)
		die("broken output pipe");
	fputc('\n', pack_pipe);
	fflush(pack_pipe);
	free(commit->buffer);
	commit->buffer = NULL;
}

84 85 86
static void show_object(struct object *obj,
			const struct name_path *path, const char *component,
			void *cb_data)
87
{
88
	show_object_with_name(pack_pipe, obj, path, component);
89 90 91 92 93 94 95
}

static void show_edge(struct commit *commit)
{
	fprintf(pack_pipe, "-%s\n", sha1_to_hex(commit->object.sha1));
}

96
static int do_rev_list(int in, int out, void *user_data)
97 98 99 100
{
	int i;
	struct rev_info revs;

101
	pack_pipe = xfdopen(out, "w");
102 103 104 105 106 107 108
	init_revisions(&revs, NULL);
	revs.tag_objects = 1;
	revs.tree_objects = 1;
	revs.blob_objects = 1;
	if (use_thin_pack)
		revs.edge_hint = 1;

109 110 111 112 113
	for (i = 0; i < want_obj.nr; i++) {
		struct object *o = want_obj.objects[i].item;
		/* why??? */
		o->flags &= ~UNINTERESTING;
		add_pending_object(&revs, o, NULL);
114
	}
115 116 117 118 119 120
	for (i = 0; i < have_obj.nr; i++) {
		struct object *o = have_obj.objects[i].item;
		o->flags |= UNINTERESTING;
		add_pending_object(&revs, o, NULL);
	}
	setup_revisions(0, NULL, &revs, NULL);
121 122
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
123
	mark_edges_uninteresting(revs.commits, &revs, show_edge);
124 125 126 127
	if (use_thin_pack)
		for (i = 0; i < extra_edge_obj.nr; i++)
			fprintf(pack_pipe, "-%s\n", sha1_to_hex(
					extra_edge_obj.objects[i].item->sha1));
128
	traverse_commit_list(&revs, show_commit, show_object, NULL);
129 130
	fflush(pack_pipe);
	fclose(pack_pipe);
131
	return 0;
132 133
}

134 135
static void create_pack_file(void)
{
136
	struct async rev_list;
137
	struct child_process pack_objects;
138
	char data[8193], progress[128];
139 140
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
141
	int buffered = -1;
J
Junio C Hamano 已提交
142
	ssize_t sz;
143 144
	const char *argv[10];
	int arg = 0;
145

146 147
	argv[arg++] = "pack-objects";
	if (!shallow_nr) {
148
		argv[arg++] = "--revs";
149
		if (use_thin_pack)
150 151
			argv[arg++] = "--thin";
	}
152

153 154 155 156 157
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
158 159
	if (use_include_tag)
		argv[arg++] = "--include-tag";
160 161 162
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
163
	pack_objects.in = -1;
164 165 166 167
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
168

169
	if (start_command(&pack_objects))
170
		die("git upload-pack: unable to fork git-pack-objects");
171

172 173 174 175 176 177 178 179
	if (shallow_nr) {
		memset(&rev_list, 0, sizeof(rev_list));
		rev_list.proc = do_rev_list;
		rev_list.out = pack_objects.in;
		if (start_async(&rev_list))
			die("git upload-pack: unable to fork git-rev-list");
	}
	else {
180
		FILE *pipe_fd = xfdopen(pack_objects.in, "w");
181
		int i;
182

183 184 185 186 187 188 189
		for (i = 0; i < want_obj.nr; i++)
			fprintf(pipe_fd, "%s\n",
				sha1_to_hex(want_obj.objects[i].item->sha1));
		fprintf(pipe_fd, "--not\n");
		for (i = 0; i < have_obj.nr; i++)
			fprintf(pipe_fd, "%s\n",
				sha1_to_hex(have_obj.objects[i].item->sha1));
190 191 192 193 194 195
		fprintf(pipe_fd, "\n");
		fflush(pipe_fd);
		fclose(pipe_fd);
	}


196 197
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
198 199 200 201
	 */

	while (1) {
		struct pollfd pfd[2];
202
		int pe, pu, pollsize;
203

204 205
		reset_timeout();

206
		pollsize = 0;
207
		pe = pu = -1;
208

209 210
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
211 212 213 214
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
215 216
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
217 218 219 220
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
221

222 223 224 225 226 227 228 229
		if (!pollsize)
			break;

		if (poll(pfd, pollsize, -1) < 0) {
			if (errno != EINTR) {
				error("poll failed, resuming: %s",
				      strerror(errno));
				sleep(1);
230
			}
231 232
			continue;
		}
N
Nicolas Pitre 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
		if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
			/* Status ready; we ship that in the side-band
			 * or dump to the standard error.
			 */
			sz = xread(pack_objects.err, progress,
				  sizeof(progress));
			if (0 < sz)
				send_client_data(2, progress, sz);
			else if (sz == 0) {
				close(pack_objects.err);
				pack_objects.err = -1;
			}
			else
				goto fail;
			/* give priority to status messages */
			continue;
		}
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
		if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
			/* Data ready; we keep the last byte to ourselves
			 * in case we detect broken rev-list, so that we
			 * can leave the stream corrupted.  This is
			 * unfortunate -- unpack-objects would happily
			 * accept a valid packdata with trailing garbage,
			 * so appending garbage after we pass all the
			 * pack data is not good enough to signal
			 * breakage to downstream.
			 */
			char *cp = data;
			ssize_t outsz = 0;
			if (0 <= buffered) {
				*cp++ = buffered;
				outsz++;
265
			}
266 267 268
			sz = xread(pack_objects.out, cp,
				  sizeof(data) - outsz);
			if (0 < sz)
J
Junio C Hamano 已提交
269
				;
270 271 272
			else if (sz == 0) {
				close(pack_objects.out);
				pack_objects.out = -1;
273
			}
274 275 276 277 278 279
			else
				goto fail;
			sz += outsz;
			if (1 < sz) {
				buffered = data[sz-1] & 0xFF;
				sz--;
280
			}
281 282 283 284
			else
				buffered = -1;
			sz = send_client_data(1, data, sz);
			if (sz < 0)
285
				goto fail;
286 287
		}
	}
288

289
	if (finish_command(&pack_objects)) {
290
		error("git upload-pack: git-pack-objects died with error.");
291 292
		goto fail;
	}
293
	if (shallow_nr && finish_async(&rev_list))
294
		goto fail;	/* error was already reported */
295

296 297 298 299 300 301 302
	/* flush the data */
	if (0 <= buffered) {
		data[0] = buffered;
		sz = send_client_data(1, data, 1);
		if (sz < 0)
			goto fail;
		fprintf(stderr, "flushed.\n");
303
	}
304 305 306 307
	if (use_sideband)
		packet_flush(1);
	return;

308
 fail:
309
	send_client_data(3, abort_msg, sizeof(abort_msg));
310
	die("git upload-pack: %s", abort_msg);
311 312
}

313 314
static int got_sha1(char *hex, unsigned char *sha1)
{
315
	struct object *o;
316
	int we_knew_they_have = 0;
317

318
	if (get_sha1_hex(hex, sha1))
319
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
320
	if (!has_sha1_file(sha1))
321
		return -1;
322

323
	o = parse_object(sha1);
324 325
	if (!o)
		die("oops (%s)", sha1_to_hex(sha1));
J
Junio C Hamano 已提交
326
	if (o->type == OBJ_COMMIT) {
327
		struct commit_list *parents;
328
		struct commit *commit = (struct commit *)o;
329
		if (o->flags & THEY_HAVE)
330 331 332 333 334 335
			we_knew_they_have = 1;
		else
			o->flags |= THEY_HAVE;
		if (!oldest_have || (commit->date < oldest_have))
			oldest_have = commit->date;
		for (parents = commit->parents;
336 337 338
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
339
	}
340 341 342 343 344 345 346 347 348 349 350
	if (!we_knew_they_have) {
		add_object_array(o, NULL, &have_obj);
		return 1;
	}
	return 0;
}

static int reachable(struct commit *want)
{
	struct commit_list *work = NULL;

351
	commit_list_insert_by_date(want, &work);
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
	while (work) {
		struct commit_list *list = work->next;
		struct commit *commit = work->item;
		free(work);
		work = list;

		if (commit->object.flags & THEY_HAVE) {
			want->object.flags |= COMMON_KNOWN;
			break;
		}
		if (!commit->object.parsed)
			parse_object(commit->object.sha1);
		if (commit->object.flags & REACHABLE)
			continue;
		commit->object.flags |= REACHABLE;
		if (commit->date < oldest_have)
			continue;
		for (list = commit->parents; list; list = list->next) {
			struct commit *parent = list->item;
			if (!(parent->object.flags & REACHABLE))
372
				commit_list_insert_by_date(parent, &work);
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
		}
	}
	want->object.flags |= REACHABLE;
	clear_commit_marks(want, REACHABLE);
	free_commit_list(work);
	return (want->object.flags & COMMON_KNOWN);
}

static int ok_to_give_up(void)
{
	int i;

	if (!have_obj.nr)
		return 0;

	for (i = 0; i < want_obj.nr; i++) {
		struct object *want = want_obj.objects[i].item;

		if (want->flags & COMMON_KNOWN)
			continue;
		want = deref_tag(want, "a want line", 0);
		if (!want || want->type != OBJ_COMMIT) {
			/* no way to tell if this is reachable by
			 * looking at the ancestry chain alone, so
			 * leave a note to ourselves not to worry about
			 * this object anymore.
			 */
			want_obj.objects[i].item->flags |= COMMON_KNOWN;
			continue;
		}
		if (!reachable((struct commit *)want))
			return 0;
	}
406
	return 1;
407 408 409 410
}

static int get_common_commits(void)
{
411
	unsigned char sha1[20];
412
	char last_hex[41];
413 414
	int got_common = 0;
	int got_other = 0;
J
Junio C Hamano 已提交
415
	int sent_ready = 0;
416

417 418
	save_commit_buffer = 0;

419
	for (;;) {
420
		char *line = packet_read_line(0, NULL);
421
		reset_timeout();
422

423
		if (!line) {
424
			if (multi_ack == 2 && got_common
J
Junio C Hamano 已提交
425 426
			    && !got_other && ok_to_give_up()) {
				sent_ready = 1;
427
				packet_write(1, "ACK %s ready\n", last_hex);
J
Junio C Hamano 已提交
428
			}
429
			if (have_obj.nr == 0 || multi_ack)
430
				packet_write(1, "NAK\n");
J
Junio C Hamano 已提交
431 432 433 434 435

			if (no_done && sent_ready) {
				packet_write(1, "ACK %s\n", last_hex);
				return 0;
			}
436 437
			if (stateless_rpc)
				exit(0);
438 439
			got_common = 0;
			got_other = 0;
440 441
			continue;
		}
442
		if (!prefixcmp(line, "have ")) {
443 444
			switch (got_sha1(line+5, sha1)) {
			case -1: /* they have what we do not */
445
				got_other = 1;
446 447
				if (multi_ack && ok_to_give_up()) {
					const char *hex = sha1_to_hex(sha1);
J
Junio C Hamano 已提交
448 449
					if (multi_ack == 2) {
						sent_ready = 1;
450
						packet_write(1, "ACK %s ready\n", hex);
J
Junio C Hamano 已提交
451
					} else
452 453
						packet_write(1, "ACK %s continue\n", hex);
				}
454 455
				break;
			default:
456
				got_common = 1;
457 458 459 460 461
				memcpy(last_hex, sha1_to_hex(sha1), 41);
				if (multi_ack == 2)
					packet_write(1, "ACK %s common\n", last_hex);
				else if (multi_ack)
					packet_write(1, "ACK %s continue\n", last_hex);
462
				else if (have_obj.nr == 1)
463
					packet_write(1, "ACK %s\n", last_hex);
464
				break;
465
			}
466 467 468
			continue;
		}
		if (!strcmp(line, "done")) {
469
			if (have_obj.nr > 0) {
470
				if (multi_ack)
471
					packet_write(1, "ACK %s\n", last_hex);
472 473
				return 0;
			}
474 475 476
			packet_write(1, "NAK\n");
			return -1;
		}
477
		die("git upload-pack: expected SHA1 list, got '%s'", line);
478 479 480
	}
}

481 482 483 484 485 486
static int is_our_ref(struct object *o)
{
	return o->flags &
		((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
}

487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
static void check_non_tip(void)
{
	static const char *argv[] = {
		"rev-list", "--stdin", NULL,
	};
	static struct child_process cmd;
	struct object *o;
	char namebuf[42]; /* ^ + SHA-1 + LF */
	int i;

	/* In the normal in-process case non-tip request can never happen */
	if (!stateless_rpc)
		goto error;

	cmd.argv = argv;
	cmd.git_cmd = 1;
	cmd.no_stderr = 1;
	cmd.in = -1;
	cmd.out = -1;

	if (start_command(&cmd))
		goto error;

	/*
	 * If rev-list --stdin encounters an unknown commit, it
	 * terminates, which will cause SIGPIPE in the write loop
	 * below.
	 */
	sigchain_push(SIGPIPE, SIG_IGN);

	namebuf[0] = '^';
	namebuf[41] = '\n';
	for (i = get_max_object_index(); 0 < i; ) {
		o = get_indexed_object(--i);
521 522
		if (!o)
			continue;
523
		if (!is_our_ref(o))
524 525 526 527 528 529 530 531
			continue;
		memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40);
		if (write_in_full(cmd.in, namebuf, 42) < 0)
			goto error;
	}
	namebuf[40] = '\n';
	for (i = 0; i < want_obj.nr; i++) {
		o = want_obj.objects[i].item;
532
		if (is_our_ref(o))
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
			continue;
		memcpy(namebuf, sha1_to_hex(o->sha1), 40);
		if (write_in_full(cmd.in, namebuf, 41) < 0)
			goto error;
	}
	close(cmd.in);

	sigchain_pop(SIGPIPE);

	/*
	 * The commits out of the rev-list are not ancestors of
	 * our ref.
	 */
	i = read_in_full(cmd.out, namebuf, 1);
	if (i)
		goto error;
	close(cmd.out);

	/*
	 * rev-list may have died by encountering a bad commit
	 * in the history, in which case we do want to bail out
	 * even when it showed no commit.
	 */
	if (finish_command(&cmd))
		goto error;

	/* All the non-tip ones are ancestors of what we advertised */
	return;

error:
	/* Pick one of them (we know there at least is one) */
	for (i = 0; i < want_obj.nr; i++) {
		o = want_obj.objects[i].item;
566
		if (!is_our_ref(o))
567 568 569 570 571
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(o->sha1));
	}
}

572
static void receive_needs(void)
573
{
574
	struct object_array shallows = OBJECT_ARRAY_INIT;
575
	int depth = 0;
576
	int has_non_tip = 0;
577

578
	shallow_nr = 0;
579
	for (;;) {
580
		struct object *o;
581
		const char *features;
582
		unsigned char sha1_buf[20];
583
		char *line = packet_read_line(0, NULL);
584
		reset_timeout();
585
		if (!line)
586
			break;
587

588
		if (!prefixcmp(line, "shallow ")) {
589 590
			unsigned char sha1[20];
			struct object *object;
591
			if (get_sha1_hex(line + 8, sha1))
592 593 594 595
				die("invalid shallow line: %s", line);
			object = parse_object(sha1);
			if (!object)
				die("did not find object for %s", line);
596 597
			if (object->type != OBJ_COMMIT)
				die("invalid shallow object %s", sha1_to_hex(sha1));
598 599 600 601
			if (!(object->flags & CLIENT_SHALLOW)) {
				object->flags |= CLIENT_SHALLOW;
				add_object_array(object, NULL, &shallows);
			}
602 603
			continue;
		}
604
		if (!prefixcmp(line, "deepen ")) {
605 606 607 608 609 610
			char *end;
			depth = strtol(line + 7, &end, 0);
			if (end == line + 7 || depth <= 0)
				die("Invalid deepen: %s", line);
			continue;
		}
611
		if (prefixcmp(line, "want ") ||
612
		    get_sha1_hex(line+5, sha1_buf))
613
			die("git upload-pack: protocol error, "
614
			    "expected to get sha, not '%s'", line);
615 616 617 618

		features = line + 45;

		if (parse_feature_request(features, "multi_ack_detailed"))
619
			multi_ack = 2;
620
		else if (parse_feature_request(features, "multi_ack"))
621
			multi_ack = 1;
622
		if (parse_feature_request(features, "no-done"))
J
Junio C Hamano 已提交
623
			no_done = 1;
624
		if (parse_feature_request(features, "thin-pack"))
625
			use_thin_pack = 1;
626
		if (parse_feature_request(features, "ofs-delta"))
627
			use_ofs_delta = 1;
628
		if (parse_feature_request(features, "side-band-64k"))
629
			use_sideband = LARGE_PACKET_MAX;
630
		else if (parse_feature_request(features, "side-band"))
631
			use_sideband = DEFAULT_PACKET_MAX;
632
		if (parse_feature_request(features, "no-progress"))
633
			no_progress = 1;
634
		if (parse_feature_request(features, "include-tag"))
635
			use_include_tag = 1;
636

637
		o = parse_object(sha1_buf);
638
		if (!o)
639 640
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(sha1_buf));
641 642
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
643
			if (!is_our_ref(o))
644
				has_non_tip = 1;
645
			add_object_array(o, NULL, &want_obj);
646
		}
647
	}
648

649 650 651 652 653 654 655 656 657 658
	/*
	 * We have sent all our refs already, and the other end
	 * should have chosen out of them. When we are operating
	 * in the stateless RPC mode, however, their choice may
	 * have been based on the set of older refs advertised
	 * by another process that handled the initial request.
	 */
	if (has_non_tip)
		check_non_tip();

659 660 661
	if (!use_sideband && daemon_mode)
		no_progress = 1;

662 663
	if (depth == 0 && shallows.nr == 0)
		return;
664
	if (depth > 0) {
665
		struct commit_list *result = NULL, *backup = NULL;
666
		int i;
667 668 669 670 671 672 673 674 675
		if (depth == INFINITE_DEPTH)
			for (i = 0; i < shallows.nr; i++) {
				struct object *object = shallows.objects[i].item;
				object->flags |= NOT_SHALLOW;
			}
		else
			backup = result =
				get_shallow_commits(&want_obj, depth,
						    SHALLOW, NOT_SHALLOW);
676
		while (result) {
677
			struct object *object = &result->item->object;
678
			if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
679 680 681
				packet_write(1, "shallow %s",
						sha1_to_hex(object->sha1));
				register_shallow(object->sha1);
682
				shallow_nr++;
683
			}
684 685 686
			result = result->next;
		}
		free_commit_list(backup);
687 688 689 690 691 692 693 694 695
		for (i = 0; i < shallows.nr; i++) {
			struct object *object = shallows.objects[i].item;
			if (object->flags & NOT_SHALLOW) {
				struct commit_list *parents;
				packet_write(1, "unshallow %s",
					sha1_to_hex(object->sha1));
				object->flags &= ~CLIENT_SHALLOW;
				/* make sure the real parents are parsed */
				unregister_shallow(object->sha1);
696
				object->parsed = 0;
697 698
				if (parse_commit((struct commit *)object))
					die("invalid commit");
699 700 701 702 703 704
				parents = ((struct commit *)object)->parents;
				while (parents) {
					add_object_array(&parents->item->object,
							NULL, &want_obj);
					parents = parents->next;
				}
705
				add_object_array(object, NULL, &extra_edge_obj);
706 707 708 709 710 711 712 713 714 715 716
			}
			/* make sure commit traversal conforms to client */
			register_shallow(object->sha1);
		}
		packet_flush(1);
	} else
		if (shallows.nr > 0) {
			int i;
			for (i = 0; i < shallows.nr; i++)
				register_shallow(shallows.objects[i].item->sha1);
		}
717 718

	shallow_nr += shallows.nr;
719
	free(shallows.objects);
720 721
}

722
/* return non-zero if the ref is hidden, otherwise 0 */
J
Junio C Hamano 已提交
723 724 725
static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
	struct object *o = lookup_unknown_object(sha1);
726

727 728
	if (ref_is_hidden(refname)) {
		o->flags |= HIDDEN_REF;
729
		return 1;
730
	}
J
Junio C Hamano 已提交
731 732
	if (!o)
		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
733
	o->flags |= OUR_REF;
J
Junio C Hamano 已提交
734 735 736
	return 0;
}

737
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
738
{
739
	static const char *capabilities = "multi_ack thin-pack side-band"
740
		" side-band-64k ofs-delta shallow no-progress"
741
		" include-tag multi_ack_detailed";
742
	const char *refname_nons = strip_namespace(refname);
743
	unsigned char peeled[20];
744

745 746
	if (mark_our_ref(refname, sha1, flag, cb_data))
		return 0;
J
Junio C Hamano 已提交
747

J
Johannes Schindelin 已提交
748
	if (capabilities)
749
		packet_write(1, "%s %s%c%s%s%s agent=%s\n",
750
			     sha1_to_hex(sha1), refname_nons,
751
			     0, capabilities,
752
			     allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
753 754
			     stateless_rpc ? " no-done" : "",
			     git_user_agent_sanitized());
J
Johannes Schindelin 已提交
755
	else
756
		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
J
Johannes Schindelin 已提交
757
	capabilities = NULL;
758 759
	if (!peel_ref(refname, peeled))
		packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
760 761 762
	return 0;
}

763
static void upload_pack(void)
764
{
765 766
	if (advertise_refs || !stateless_rpc) {
		reset_timeout();
767 768
		head_ref_namespaced(send_ref, NULL);
		for_each_namespaced_ref(send_ref, NULL);
769 770
		packet_flush(1);
	} else {
771 772
		head_ref_namespaced(mark_our_ref, NULL);
		for_each_namespaced_ref(mark_our_ref, NULL);
773 774 775 776
	}
	if (advertise_refs)
		return;

777
	receive_needs();
778 779 780 781
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
782 783
}

784 785
static int upload_pack_config(const char *var, const char *value, void *unused)
{
786 787
	if (!strcmp("uploadpack.allowtipsha1inwant", var))
		allow_tip_sha1_in_want = git_config_bool(var, value);
788 789 790
	return parse_hide_refs_config(var, value, "uploadpack");
}

791 792
int main(int argc, char **argv)
{
793
	char *dir;
794 795 796
	int i;
	int strict = 0;

797 798
	git_setup_gettext();

J
Jeff King 已提交
799
	packet_trace_identity("upload-pack");
800
	git_extract_argv0_path(argv[0]);
801
	read_replace_refs = 0;
802

803 804 805 806 807
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

		if (arg[0] != '-')
			break;
808 809 810 811 812 813 814 815
		if (!strcmp(arg, "--advertise-refs")) {
			advertise_refs = 1;
			continue;
		}
		if (!strcmp(arg, "--stateless-rpc")) {
			stateless_rpc = 1;
			continue;
		}
816 817 818 819
		if (!strcmp(arg, "--strict")) {
			strict = 1;
			continue;
		}
820
		if (!prefixcmp(arg, "--timeout=")) {
821
			timeout = atoi(arg+10);
822
			daemon_mode = 1;
823 824 825 826 827 828 829
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
	}
J
Junio C Hamano 已提交
830

831
	if (i != argc-1)
832
		usage(upload_pack_usage);
833

834
	setup_path();
835

836
	dir = argv[i];
837

838
	if (!enter_repo(dir, strict))
839
		die("'%s' does not appear to be a git repository", dir);
840 841
	if (is_repository_shallow())
		die("attempt to fetch/clone from a shallow repository");
842
	git_config(upload_pack_config, NULL);
843 844 845
	upload_pack();
	return 0;
}