upload-pack.c 20.0 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 "connect.h"
14
#include "sigchain.h"
15
#include "version.h"
16
#include "string-list.h"
17

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

20 21 22 23 24 25 26
/* 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)

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

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

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

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

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

73 74
static void create_pack_file(void)
{
75
	struct child_process pack_objects;
76
	char data[8193], progress[128];
77 78
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
79
	int buffered = -1;
J
Junio C Hamano 已提交
80
	ssize_t sz;
81 82 83 84
	const char *argv[12];
	int i, arg = 0;
	FILE *pipe_fd;
	char *shallow_file = NULL;
85

86
	if (shallow_nr) {
87
		shallow_file = setup_temporary_shallow(NULL);
88 89
		argv[arg++] = "--shallow-file";
		argv[arg++] = shallow_file;
90
	}
91 92 93 94
	argv[arg++] = "pack-objects";
	argv[arg++] = "--revs";
	if (use_thin_pack)
		argv[arg++] = "--thin";
95

96 97 98 99 100
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
101 102
	if (use_include_tag)
		argv[arg++] = "--include-tag";
103 104 105
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
106
	pack_objects.in = -1;
107 108 109 110
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
111

112
	if (start_command(&pack_objects))
113
		die("git upload-pack: unable to fork git-pack-objects");
114

115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
	pipe_fd = xfdopen(pack_objects.in, "w");

	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));
	for (i = 0; i < extra_edge_obj.nr; i++)
		fprintf(pipe_fd, "%s\n",
			sha1_to_hex(extra_edge_obj.objects[i].item->sha1));
	fprintf(pipe_fd, "\n");
	fflush(pipe_fd);
	fclose(pipe_fd);
130

131 132
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
133 134 135 136
	 */

	while (1) {
		struct pollfd pfd[2];
137
		int pe, pu, pollsize;
138
		int ret;
139

140 141
		reset_timeout();

142
		pollsize = 0;
143
		pe = pu = -1;
144

145 146
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
147 148 149 150
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
151 152
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
153 154 155 156
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
157

158 159 160
		if (!pollsize)
			break;

161 162
		ret = poll(pfd, pollsize, 1000 * keepalive);
		if (ret < 0) {
163 164 165 166
			if (errno != EINTR) {
				error("poll failed, resuming: %s",
				      strerror(errno));
				sleep(1);
167
			}
168 169
			continue;
		}
N
Nicolas Pitre 已提交
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
		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;
		}
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
		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++;
202
			}
203 204 205
			sz = xread(pack_objects.out, cp,
				  sizeof(data) - outsz);
			if (0 < sz)
J
Junio C Hamano 已提交
206
				;
207 208 209
			else if (sz == 0) {
				close(pack_objects.out);
				pack_objects.out = -1;
210
			}
211 212 213 214 215 216
			else
				goto fail;
			sz += outsz;
			if (1 < sz) {
				buffered = data[sz-1] & 0xFF;
				sz--;
217
			}
218 219 220 221
			else
				buffered = -1;
			sz = send_client_data(1, data, sz);
			if (sz < 0)
222
				goto fail;
223
		}
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

		/*
		 * We hit the keepalive timeout without saying anything; send
		 * an empty message on the data sideband just to let the other
		 * side know we're still working on it, but don't have any data
		 * yet.
		 *
		 * If we don't have a sideband channel, there's no room in the
		 * protocol to say anything, so those clients are just out of
		 * luck.
		 */
		if (!ret && use_sideband) {
			static const char buf[] = "0005\1";
			write_or_die(1, buf, 5);
		}
239
	}
240

241
	if (finish_command(&pack_objects)) {
242
		error("git upload-pack: git-pack-objects died with error.");
243 244
		goto fail;
	}
245 246 247 248 249
	if (shallow_file) {
		if (*shallow_file)
			unlink(shallow_file);
		free(shallow_file);
	}
250

251 252 253 254 255 256 257
	/* 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");
258
	}
259 260 261 262
	if (use_sideband)
		packet_flush(1);
	return;

263
 fail:
264
	send_client_data(3, abort_msg, sizeof(abort_msg));
265
	die("git upload-pack: %s", abort_msg);
266 267
}

268 269
static int got_sha1(char *hex, unsigned char *sha1)
{
270
	struct object *o;
271
	int we_knew_they_have = 0;
272

273
	if (get_sha1_hex(hex, sha1))
274
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
275
	if (!has_sha1_file(sha1))
276
		return -1;
277

278
	o = parse_object(sha1);
279 280
	if (!o)
		die("oops (%s)", sha1_to_hex(sha1));
J
Junio C Hamano 已提交
281
	if (o->type == OBJ_COMMIT) {
282
		struct commit_list *parents;
283
		struct commit *commit = (struct commit *)o;
284
		if (o->flags & THEY_HAVE)
285 286 287 288 289 290
			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;
291 292 293
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
294
	}
295 296 297 298 299 300 301 302 303 304 305
	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;

306
	commit_list_insert_by_date(want, &work);
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
	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))
327
				commit_list_insert_by_date(parent, &work);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
		}
	}
	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;
	}
361
	return 1;
362 363 364 365
}

static int get_common_commits(void)
{
366
	unsigned char sha1[20];
367
	char last_hex[41];
368 369
	int got_common = 0;
	int got_other = 0;
J
Junio C Hamano 已提交
370
	int sent_ready = 0;
371

372 373
	save_commit_buffer = 0;

374
	for (;;) {
375
		char *line = packet_read_line(0, NULL);
376
		reset_timeout();
377

378
		if (!line) {
379
			if (multi_ack == 2 && got_common
J
Junio C Hamano 已提交
380 381
			    && !got_other && ok_to_give_up()) {
				sent_ready = 1;
382
				packet_write(1, "ACK %s ready\n", last_hex);
J
Junio C Hamano 已提交
383
			}
384
			if (have_obj.nr == 0 || multi_ack)
385
				packet_write(1, "NAK\n");
J
Junio C Hamano 已提交
386 387 388 389 390

			if (no_done && sent_ready) {
				packet_write(1, "ACK %s\n", last_hex);
				return 0;
			}
391 392
			if (stateless_rpc)
				exit(0);
393 394
			got_common = 0;
			got_other = 0;
395 396
			continue;
		}
397
		if (starts_with(line, "have ")) {
398 399
			switch (got_sha1(line+5, sha1)) {
			case -1: /* they have what we do not */
400
				got_other = 1;
401 402
				if (multi_ack && ok_to_give_up()) {
					const char *hex = sha1_to_hex(sha1);
J
Junio C Hamano 已提交
403 404
					if (multi_ack == 2) {
						sent_ready = 1;
405
						packet_write(1, "ACK %s ready\n", hex);
J
Junio C Hamano 已提交
406
					} else
407 408
						packet_write(1, "ACK %s continue\n", hex);
				}
409 410
				break;
			default:
411
				got_common = 1;
412 413 414 415 416
				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);
417
				else if (have_obj.nr == 1)
418
					packet_write(1, "ACK %s\n", last_hex);
419
				break;
420
			}
421 422 423
			continue;
		}
		if (!strcmp(line, "done")) {
424
			if (have_obj.nr > 0) {
425
				if (multi_ack)
426
					packet_write(1, "ACK %s\n", last_hex);
427 428
				return 0;
			}
429 430 431
			packet_write(1, "NAK\n");
			return -1;
		}
432
		die("git upload-pack: expected SHA1 list, got '%s'", line);
433 434 435
	}
}

436 437 438 439 440 441
static int is_our_ref(struct object *o)
{
	return o->flags &
		((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
}

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
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);
476 477
		if (!o)
			continue;
478
		if (!is_our_ref(o))
479 480 481 482 483 484 485 486
			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;
487
		if (is_our_ref(o))
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
			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;
521
		if (!is_our_ref(o))
522 523 524 525 526
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(o->sha1));
	}
}

527
static void receive_needs(void)
528
{
529
	struct object_array shallows = OBJECT_ARRAY_INIT;
530
	int depth = 0;
531
	int has_non_tip = 0;
532

533
	shallow_nr = 0;
534
	for (;;) {
535
		struct object *o;
536
		const char *features;
537
		unsigned char sha1_buf[20];
538
		char *line = packet_read_line(0, NULL);
539
		reset_timeout();
540
		if (!line)
541
			break;
542

543
		if (starts_with(line, "shallow ")) {
544 545
			unsigned char sha1[20];
			struct object *object;
546
			if (get_sha1_hex(line + 8, sha1))
547 548 549
				die("invalid shallow line: %s", line);
			object = parse_object(sha1);
			if (!object)
550
				continue;
551 552
			if (object->type != OBJ_COMMIT)
				die("invalid shallow object %s", sha1_to_hex(sha1));
553 554 555 556
			if (!(object->flags & CLIENT_SHALLOW)) {
				object->flags |= CLIENT_SHALLOW;
				add_object_array(object, NULL, &shallows);
			}
557 558
			continue;
		}
559
		if (starts_with(line, "deepen ")) {
560 561 562 563 564 565
			char *end;
			depth = strtol(line + 7, &end, 0);
			if (end == line + 7 || depth <= 0)
				die("Invalid deepen: %s", line);
			continue;
		}
566
		if (!starts_with(line, "want ") ||
567
		    get_sha1_hex(line+5, sha1_buf))
568
			die("git upload-pack: protocol error, "
569
			    "expected to get sha, not '%s'", line);
570 571 572 573

		features = line + 45;

		if (parse_feature_request(features, "multi_ack_detailed"))
574
			multi_ack = 2;
575
		else if (parse_feature_request(features, "multi_ack"))
576
			multi_ack = 1;
577
		if (parse_feature_request(features, "no-done"))
J
Junio C Hamano 已提交
578
			no_done = 1;
579
		if (parse_feature_request(features, "thin-pack"))
580
			use_thin_pack = 1;
581
		if (parse_feature_request(features, "ofs-delta"))
582
			use_ofs_delta = 1;
583
		if (parse_feature_request(features, "side-band-64k"))
584
			use_sideband = LARGE_PACKET_MAX;
585
		else if (parse_feature_request(features, "side-band"))
586
			use_sideband = DEFAULT_PACKET_MAX;
587
		if (parse_feature_request(features, "no-progress"))
588
			no_progress = 1;
589
		if (parse_feature_request(features, "include-tag"))
590
			use_include_tag = 1;
591

592
		o = parse_object(sha1_buf);
593
		if (!o)
594 595
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(sha1_buf));
596 597
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
598
			if (!is_our_ref(o))
599
				has_non_tip = 1;
600
			add_object_array(o, NULL, &want_obj);
601
		}
602
	}
603

604 605 606 607 608 609 610 611 612 613
	/*
	 * 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();

614 615 616
	if (!use_sideband && daemon_mode)
		no_progress = 1;

617 618
	if (depth == 0 && shallows.nr == 0)
		return;
619
	if (depth > 0) {
620
		struct commit_list *result = NULL, *backup = NULL;
621
		int i;
622
		if (depth == INFINITE_DEPTH && !is_repository_shallow())
623 624 625 626 627 628 629 630
			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);
631
		while (result) {
632
			struct object *object = &result->item->object;
633
			if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
634 635 636
				packet_write(1, "shallow %s",
						sha1_to_hex(object->sha1));
				register_shallow(object->sha1);
637
				shallow_nr++;
638
			}
639 640 641
			result = result->next;
		}
		free_commit_list(backup);
642 643 644 645 646 647 648 649 650
		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);
651
				object->parsed = 0;
652
				parse_commit_or_die((struct commit *)object);
653 654 655 656 657 658
				parents = ((struct commit *)object)->parents;
				while (parents) {
					add_object_array(&parents->item->object,
							NULL, &want_obj);
					parents = parents->next;
				}
659
				add_object_array(object, NULL, &extra_edge_obj);
660 661 662 663 664 665 666 667 668 669 670
			}
			/* 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);
		}
671 672

	shallow_nr += shallows.nr;
673
	free(shallows.objects);
674 675
}

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

681 682
	if (ref_is_hidden(refname)) {
		o->flags |= HIDDEN_REF;
683
		return 1;
684
	}
J
Junio C Hamano 已提交
685 686
	if (!o)
		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
687
	o->flags |= OUR_REF;
J
Junio C Hamano 已提交
688 689 690
	return 0;
}

691 692 693 694 695 696 697 698 699 700
static void format_symref_info(struct strbuf *buf, struct string_list *symref)
{
	struct string_list_item *item;

	if (!symref->nr)
		return;
	for_each_string_list_item(item, symref)
		strbuf_addf(buf, " symref=%s:%s", item->string, (char *)item->util);
}

701
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
702
{
703
	static const char *capabilities = "multi_ack thin-pack side-band"
704
		" side-band-64k ofs-delta shallow no-progress"
705
		" include-tag multi_ack_detailed";
706
	const char *refname_nons = strip_namespace(refname);
707
	unsigned char peeled[20];
708

709
	if (mark_our_ref(refname, sha1, flag, NULL))
710
		return 0;
J
Junio C Hamano 已提交
711

712 713 714 715 716
	if (capabilities) {
		struct strbuf symref_info = STRBUF_INIT;

		format_symref_info(&symref_info, cb_data);
		packet_write(1, "%s %s%c%s%s%s%s agent=%s\n",
717
			     sha1_to_hex(sha1), refname_nons,
718
			     0, capabilities,
719
			     allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "",
720
			     stateless_rpc ? " no-done" : "",
721
			     symref_info.buf,
722
			     git_user_agent_sanitized());
723 724
		strbuf_release(&symref_info);
	} else {
725
		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
726
	}
J
Johannes Schindelin 已提交
727
	capabilities = NULL;
728 729
	if (!peel_ref(refname, peeled))
		packet_write(1, "%s %s^{}\n", sha1_to_hex(peeled), refname_nons);
730 731 732
	return 0;
}

733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749
static int find_symref(const char *refname, const unsigned char *sha1, int flag,
		       void *cb_data)
{
	const char *symref_target;
	struct string_list_item *item;
	unsigned char unused[20];

	if ((flag & REF_ISSYMREF) == 0)
		return 0;
	symref_target = resolve_ref_unsafe(refname, unused, 0, &flag);
	if (!symref_target || (flag & REF_ISSYMREF) == 0)
		die("'%s' is a symref but it is not?", refname);
	item = string_list_append(cb_data, refname);
	item->util = xstrdup(symref_target);
	return 0;
}

750
static void upload_pack(void)
751
{
752 753 754 755
	struct string_list symref = STRING_LIST_INIT_DUP;

	head_ref_namespaced(find_symref, &symref);

756 757
	if (advertise_refs || !stateless_rpc) {
		reset_timeout();
758 759
		head_ref_namespaced(send_ref, &symref);
		for_each_namespaced_ref(send_ref, &symref);
760
		advertise_shallow_grafts(1);
761 762
		packet_flush(1);
	} else {
763 764
		head_ref_namespaced(mark_our_ref, NULL);
		for_each_namespaced_ref(mark_our_ref, NULL);
765
	}
766
	string_list_clear(&symref, 1);
767 768 769
	if (advertise_refs)
		return;

770
	receive_needs();
771 772 773 774
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
775 776
}

777 778
static int upload_pack_config(const char *var, const char *value, void *unused)
{
779 780
	if (!strcmp("uploadpack.allowtipsha1inwant", var))
		allow_tip_sha1_in_want = git_config_bool(var, value);
781 782 783 784 785
	else if (!strcmp("uploadpack.keepalive", var)) {
		keepalive = git_config_int(var, value);
		if (!keepalive)
			keepalive = -1;
	}
786 787 788
	return parse_hide_refs_config(var, value, "uploadpack");
}

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

795 796
	git_setup_gettext();

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

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

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

829
	if (i != argc-1)
830
		usage(upload_pack_usage);
831

832
	setup_path();
833

834
	dir = argv[i];
835

836
	if (!enter_repo(dir, strict))
837
		die("'%s' does not appear to be a git repository", dir);
838

839
	git_config(upload_pack_config, NULL);
840 841 842
	upload_pack();
	return 0;
}