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 29
#define SHALLOW		(1u << 16)
#define NOT_SHALLOW	(1u << 17)
#define CLIENT_SHALLOW	(1u << 18)

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

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

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

54 55 56 57 58 59 60
static int strip(char *line, int len)
{
	if (len && line[len-1] == '\n')
		line[--len] = 0;
	return len;
}

61 62
static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
{
63
	if (use_sideband)
64
		return send_sideband(1, fd, data, sz, use_sideband);
65 66 67 68
	if (fd == 3)
		/* emergency quit */
		fd = 2;
	if (fd == 2) {
69
		/* XXX: are we happy to lose stuff here? */
70 71
		xwrite(fd, data, sz);
		return sz;
72
	}
73
	return safe_write(fd, data, sz);
74 75
}

J
Junio C Hamano 已提交
76
static FILE *pack_pipe = NULL;
77
static void show_commit(struct commit *commit, void *data)
78 79 80 81 82 83 84 85 86 87 88
{
	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;
}

89 90 91
static void show_object(struct object *obj,
			const struct name_path *path, const char *component,
			void *cb_data)
92
{
93
	show_object_with_name(pack_pipe, obj, path, component);
94 95 96 97 98 99 100
}

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

101
static int do_rev_list(int in, int out, void *user_data)
102 103 104 105
{
	int i;
	struct rev_info revs;

106
	pack_pipe = xfdopen(out, "w");
107 108 109 110 111 112 113
	init_revisions(&revs, NULL);
	revs.tag_objects = 1;
	revs.tree_objects = 1;
	revs.blob_objects = 1;
	if (use_thin_pack)
		revs.edge_hint = 1;

114 115 116 117 118
	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);
119
	}
120 121 122 123 124 125
	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);
126 127
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
128
	mark_edges_uninteresting(revs.commits, &revs, show_edge);
129 130 131 132
	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));
133
	traverse_commit_list(&revs, show_commit, show_object, NULL);
134 135
	fflush(pack_pipe);
	fclose(pack_pipe);
136
	return 0;
137 138
}

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

151 152
	argv[arg++] = "pack-objects";
	if (!shallow_nr) {
153
		argv[arg++] = "--revs";
154
		if (use_thin_pack)
155 156
			argv[arg++] = "--thin";
	}
157

158 159 160 161 162
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
163 164
	if (use_include_tag)
		argv[arg++] = "--include-tag";
165 166 167
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
168
	pack_objects.in = -1;
169 170 171 172
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
173

174
	if (start_command(&pack_objects))
175
		die("git upload-pack: unable to fork git-pack-objects");
176

177 178 179 180 181 182 183 184
	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 {
185
		FILE *pipe_fd = xfdopen(pack_objects.in, "w");
186
		int i;
187

188 189 190 191 192 193 194
		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));
195 196 197 198 199 200
		fprintf(pipe_fd, "\n");
		fflush(pipe_fd);
		fclose(pipe_fd);
	}


201 202
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
203 204 205 206
	 */

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

209 210
		reset_timeout();

211
		pollsize = 0;
212
		pe = pu = -1;
213

214 215
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
216 217 218 219
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
220 221
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
222 223 224 225
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
226

227 228 229 230 231 232 233 234
		if (!pollsize)
			break;

		if (poll(pfd, pollsize, -1) < 0) {
			if (errno != EINTR) {
				error("poll failed, resuming: %s",
				      strerror(errno));
				sleep(1);
235
			}
236 237
			continue;
		}
N
Nicolas Pitre 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
		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;
		}
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
		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++;
270
			}
271 272 273
			sz = xread(pack_objects.out, cp,
				  sizeof(data) - outsz);
			if (0 < sz)
J
Junio C Hamano 已提交
274
				;
275 276 277
			else if (sz == 0) {
				close(pack_objects.out);
				pack_objects.out = -1;
278
			}
279 280 281 282 283 284
			else
				goto fail;
			sz += outsz;
			if (1 < sz) {
				buffered = data[sz-1] & 0xFF;
				sz--;
285
			}
286 287 288 289
			else
				buffered = -1;
			sz = send_client_data(1, data, sz);
			if (sz < 0)
290
				goto fail;
291 292
		}
	}
293

294
	if (finish_command(&pack_objects)) {
295
		error("git upload-pack: git-pack-objects died with error.");
296 297
		goto fail;
	}
298
	if (shallow_nr && finish_async(&rev_list))
299
		goto fail;	/* error was already reported */
300

301 302 303 304 305 306 307
	/* 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");
308
	}
309 310 311 312
	if (use_sideband)
		packet_flush(1);
	return;

313
 fail:
314
	send_client_data(3, abort_msg, sizeof(abort_msg));
315
	die("git upload-pack: %s", abort_msg);
316 317
}

318 319
static int got_sha1(char *hex, unsigned char *sha1)
{
320
	struct object *o;
321
	int we_knew_they_have = 0;
322

323
	if (get_sha1_hex(hex, sha1))
324
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
325
	if (!has_sha1_file(sha1))
326
		return -1;
327 328 329 330 331 332

	o = lookup_object(sha1);
	if (!(o && o->parsed))
		o = parse_object(sha1);
	if (!o)
		die("oops (%s)", sha1_to_hex(sha1));
J
Junio C Hamano 已提交
333
	if (o->type == OBJ_COMMIT) {
334
		struct commit_list *parents;
335
		struct commit *commit = (struct commit *)o;
336
		if (o->flags & THEY_HAVE)
337 338 339 340 341 342
			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;
343 344 345
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
346
	}
347 348 349 350 351 352 353 354 355 356 357
	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;

358
	commit_list_insert_by_date(want, &work);
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
	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))
379
				commit_list_insert_by_date(parent, &work);
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 406 407 408 409 410 411 412
		}
	}
	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;
	}
413
	return 1;
414 415 416 417 418
}

static int get_common_commits(void)
{
	static char line[1000];
419
	unsigned char sha1[20];
420
	char last_hex[41];
421 422
	int got_common = 0;
	int got_other = 0;
J
Junio C Hamano 已提交
423
	int sent_ready = 0;
424

425 426
	save_commit_buffer = 0;

427
	for (;;) {
428
		int len = packet_read_line(0, line, sizeof(line));
429
		reset_timeout();
430 431

		if (!len) {
432
			if (multi_ack == 2 && got_common
J
Junio C Hamano 已提交
433 434
			    && !got_other && ok_to_give_up()) {
				sent_ready = 1;
435
				packet_write(1, "ACK %s ready\n", last_hex);
J
Junio C Hamano 已提交
436
			}
437
			if (have_obj.nr == 0 || multi_ack)
438
				packet_write(1, "NAK\n");
J
Junio C Hamano 已提交
439 440 441 442 443

			if (no_done && sent_ready) {
				packet_write(1, "ACK %s\n", last_hex);
				return 0;
			}
444 445
			if (stateless_rpc)
				exit(0);
446 447
			got_common = 0;
			got_other = 0;
448 449
			continue;
		}
450
		strip(line, len);
451
		if (!prefixcmp(line, "have ")) {
452 453
			switch (got_sha1(line+5, sha1)) {
			case -1: /* they have what we do not */
454
				got_other = 1;
455 456
				if (multi_ack && ok_to_give_up()) {
					const char *hex = sha1_to_hex(sha1);
J
Junio C Hamano 已提交
457 458
					if (multi_ack == 2) {
						sent_ready = 1;
459
						packet_write(1, "ACK %s ready\n", hex);
J
Junio C Hamano 已提交
460
					} else
461 462
						packet_write(1, "ACK %s continue\n", hex);
				}
463 464
				break;
			default:
465
				got_common = 1;
466 467 468 469 470
				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);
471
				else if (have_obj.nr == 1)
472
					packet_write(1, "ACK %s\n", last_hex);
473
				break;
474
			}
475 476 477
			continue;
		}
		if (!strcmp(line, "done")) {
478
			if (have_obj.nr > 0) {
479
				if (multi_ack)
480
					packet_write(1, "ACK %s\n", last_hex);
481 482
				return 0;
			}
483 484 485
			packet_write(1, "NAK\n");
			return -1;
		}
486
		die("git upload-pack: expected SHA1 list, got '%s'", line);
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 521 522 523
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);
524 525
		if (!o)
			continue;
526 527 528 529 530 531 532 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 566 567 568 569 570 571 572 573 574
		if (!(o->flags & OUR_REF))
			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;
		if (o->flags & OUR_REF)
			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;
		if (!(o->flags & OUR_REF))
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(o->sha1));
	}
}

575
static void receive_needs(void)
576
{
577
	struct object_array shallows = OBJECT_ARRAY_INIT;
578
	static char line[1000];
579
	int len, depth = 0;
580
	int has_non_tip = 0;
581

582
	shallow_nr = 0;
583
	if (debug_fd)
584
		write_str_in_full(debug_fd, "#S\n");
585
	for (;;) {
586
		struct object *o;
587
		const char *features;
588
		unsigned char sha1_buf[20];
589
		len = packet_read_line(0, line, sizeof(line));
590
		reset_timeout();
591
		if (!len)
592
			break;
593 594
		if (debug_fd)
			write_in_full(debug_fd, line, len);
595

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

		features = line + 45;

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

		o = lookup_object(sha1_buf);
644
		if (!o)
645 646
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(sha1_buf));
647 648
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
649 650
			if (!(o->flags & OUR_REF))
				has_non_tip = 1;
651
			add_object_array(o, NULL, &want_obj);
652
		}
653
	}
654
	if (debug_fd)
655
		write_str_in_full(debug_fd, "#E\n");
656

657 658 659 660 661 662 663 664 665 666
	/*
	 * 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();

667 668 669
	if (!use_sideband && daemon_mode)
		no_progress = 1;

670 671
	if (depth == 0 && shallows.nr == 0)
		return;
672
	if (depth > 0) {
673
		struct commit_list *result = NULL, *backup = NULL;
674
		int i;
675 676 677 678 679 680 681 682 683
		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);
684
		while (result) {
685
			struct object *object = &result->item->object;
686
			if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
687 688 689
				packet_write(1, "shallow %s",
						sha1_to_hex(object->sha1));
				register_shallow(object->sha1);
690
				shallow_nr++;
691
			}
692 693 694
			result = result->next;
		}
		free_commit_list(backup);
695 696 697 698 699 700 701 702 703
		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);
704
				object->parsed = 0;
705 706
				if (parse_commit((struct commit *)object))
					die("invalid commit");
707 708 709 710 711 712
				parents = ((struct commit *)object)->parents;
				while (parents) {
					add_object_array(&parents->item->object,
							NULL, &want_obj);
					parents = parents->next;
				}
713
				add_object_array(object, NULL, &extra_edge_obj);
714 715 716 717 718 719 720 721 722 723 724
			}
			/* 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);
		}
725 726

	shallow_nr += shallows.nr;
727
	free(shallows.objects);
728 729
}

730
/* return non-zero if the ref is hidden, otherwise 0 */
J
Junio C Hamano 已提交
731 732 733
static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
	struct object *o = lookup_unknown_object(sha1);
734 735 736

	if (ref_is_hidden(refname))
		return 1;
J
Junio C Hamano 已提交
737 738
	if (!o)
		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
739
	o->flags |= OUR_REF;
J
Junio C Hamano 已提交
740 741 742
	return 0;
}

743
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
744
{
745
	static const char *capabilities = "multi_ack thin-pack side-band"
746
		" side-band-64k ofs-delta shallow no-progress"
747
		" include-tag multi_ack_detailed";
748
	const char *refname_nons = strip_namespace(refname);
749
	unsigned char peeled[20];
750

751 752
	if (mark_our_ref(refname, sha1, flag, cb_data))
		return 0;
J
Junio C Hamano 已提交
753

J
Johannes Schindelin 已提交
754
	if (capabilities)
755 756
		packet_write(1, "%s %s%c%s%s agent=%s\n",
			     sha1_to_hex(sha1), refname_nons,
757
			     0, capabilities,
758 759
			     stateless_rpc ? " no-done" : "",
			     git_user_agent_sanitized());
J
Johannes Schindelin 已提交
760
	else
761
		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
J
Johannes Schindelin 已提交
762
	capabilities = NULL;
763 764
	if (!peel_ref(refname, peeled))
		packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
765 766 767
	return 0;
}

768
static void upload_pack(void)
769
{
770 771
	if (advertise_refs || !stateless_rpc) {
		reset_timeout();
772 773
		head_ref_namespaced(send_ref, NULL);
		for_each_namespaced_ref(send_ref, NULL);
774 775
		packet_flush(1);
	} else {
776 777
		head_ref_namespaced(mark_our_ref, NULL);
		for_each_namespaced_ref(mark_our_ref, NULL);
778 779 780 781
	}
	if (advertise_refs)
		return;

782
	receive_needs();
783 784 785 786
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
787 788
}

789 790 791 792 793
static int upload_pack_config(const char *var, const char *value, void *unused)
{
	return parse_hide_refs_config(var, value, "uploadpack");
}

794 795
int main(int argc, char **argv)
{
796
	char *dir;
797 798 799
	int i;
	int strict = 0;

800 801
	git_setup_gettext();

J
Jeff King 已提交
802
	packet_trace_identity("upload-pack");
803
	git_extract_argv0_path(argv[0]);
804
	read_replace_refs = 0;
805

806 807 808 809 810
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

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

834
	if (i != argc-1)
835
		usage(upload_pack_usage);
836

837
	setup_path();
838

839
	dir = argv[i];
840

841
	if (!enter_repo(dir, strict))
842
		die("'%s' does not appear to be a git repository", dir);
843 844
	if (is_repository_shallow())
		die("attempt to fetch/clone from a shallow repository");
845
	git_config(upload_pack_config, NULL);
846 847
	if (getenv("GIT_DEBUG_SEND_PACK"))
		debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
848 849 850
	upload_pack();
	return 0;
}