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 "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 75 76 77 78 79 80
static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
{
	FILE *fp = cb_data;
	if (graft->nr_parent == -1)
		fprintf(fp, "--shallow %s\n", sha1_to_hex(graft->sha1));
	return 0;
}

81 82
static void create_pack_file(void)
{
83
	struct child_process pack_objects;
84
	char data[8193], progress[128];
85 86
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
87
	int buffered = -1;
J
Junio C Hamano 已提交
88
	ssize_t sz;
89 90 91
	const char *argv[12];
	int i, arg = 0;
	FILE *pipe_fd;
92

93 94
	if (shallow_nr) {
		argv[arg++] = "--shallow-file";
95
		argv[arg++] = "";
96
	}
97 98 99 100
	argv[arg++] = "pack-objects";
	argv[arg++] = "--revs";
	if (use_thin_pack)
		argv[arg++] = "--thin";
101

102 103 104 105 106
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
107 108
	if (use_include_tag)
		argv[arg++] = "--include-tag";
109 110 111
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
112
	pack_objects.in = -1;
113 114 115 116
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
117

118
	if (start_command(&pack_objects))
119
		die("git upload-pack: unable to fork git-pack-objects");
120

121 122
	pipe_fd = xfdopen(pack_objects.in, "w");

123 124 125
	if (shallow_nr)
		for_each_commit_graft(write_one_shallow, pipe_fd);

126 127 128 129 130 131 132 133 134 135 136 137 138
	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);
139

140 141
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
142 143 144 145
	 */

	while (1) {
		struct pollfd pfd[2];
146
		int pe, pu, pollsize;
147
		int ret;
148

149 150
		reset_timeout();

151
		pollsize = 0;
152
		pe = pu = -1;
153

154 155
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
156 157 158 159
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
160 161
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
162 163 164 165
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
166

167 168 169
		if (!pollsize)
			break;

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

		/*
		 * 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);
		}
248
	}
249

250
	if (finish_command(&pack_objects)) {
251
		error("git upload-pack: git-pack-objects died with error.");
252 253
		goto fail;
	}
254

255 256 257 258 259 260 261
	/* 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");
262
	}
263 264 265 266
	if (use_sideband)
		packet_flush(1);
	return;

267
 fail:
268
	send_client_data(3, abort_msg, sizeof(abort_msg));
269
	die("git upload-pack: %s", abort_msg);
270 271
}

272 273
static int got_sha1(char *hex, unsigned char *sha1)
{
274
	struct object *o;
275
	int we_knew_they_have = 0;
276

277
	if (get_sha1_hex(hex, sha1))
278
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
279
	if (!has_sha1_file(sha1))
280
		return -1;
281

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

310
	commit_list_insert_by_date(want, &work);
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
	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))
331
				commit_list_insert_by_date(parent, &work);
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 361 362 363 364
		}
	}
	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;
	}
365
	return 1;
366 367 368 369
}

static int get_common_commits(void)
{
370
	unsigned char sha1[20];
371
	char last_hex[41];
372 373
	int got_common = 0;
	int got_other = 0;
J
Junio C Hamano 已提交
374
	int sent_ready = 0;
375

376 377
	save_commit_buffer = 0;

378
	for (;;) {
379
		char *line = packet_read_line(0, NULL);
380
		reset_timeout();
381

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

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

440 441 442 443 444 445
static int is_our_ref(struct object *o)
{
	return o->flags &
		((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF);
}

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 476 477 478 479
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);
480 481
		if (!o)
			continue;
482
		if (!is_our_ref(o))
483 484 485 486 487 488 489 490
			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;
491
		if (is_our_ref(o))
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 524
			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;
525
		if (!is_our_ref(o))
526 527 528 529 530
			die("git upload-pack: not our ref %s",
			    sha1_to_hex(o->sha1));
	}
}

531
static void receive_needs(void)
532
{
533
	struct object_array shallows = OBJECT_ARRAY_INIT;
534
	int depth = 0;
535
	int has_non_tip = 0;
536

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

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

		features = line + 45;

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

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

608 609 610 611 612 613 614 615 616 617
	/*
	 * 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();

618 619 620
	if (!use_sideband && daemon_mode)
		no_progress = 1;

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

	shallow_nr += shallows.nr;
677
	free(shallows.objects);
678 679
}

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

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

695 696 697 698 699 700 701 702 703 704
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);
}

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

713
	if (mark_our_ref(refname, sha1, flag, NULL))
714
		return 0;
J
Junio C Hamano 已提交
715

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

737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
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;
}

754
static void upload_pack(void)
755
{
756 757 758 759
	struct string_list symref = STRING_LIST_INIT_DUP;

	head_ref_namespaced(find_symref, &symref);

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

774
	receive_needs();
775 776 777 778
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
779 780
}

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

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

799 800
	git_setup_gettext();

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

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

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

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

836
	setup_path();
837

838
	dir = argv[i];
839

840
	if (!enter_repo(dir, strict))
841
		die("'%s' does not appear to be a git repository", dir);
842

843
	git_config(upload_pack_config, NULL);
844 845 846
	upload_pack();
	return 0;
}