upload-pack.c 18.3 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

14
static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=nn] <dir>";
15

16 17 18 19 20 21 22
/* 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)

23 24 25 26
#define SHALLOW		(1u << 16)
#define NOT_SHALLOW	(1u << 17)
#define CLIENT_SHALLOW	(1u << 18)

J
Junio C Hamano 已提交
27
static unsigned long oldest_have;
28

29
static int multi_ack, nr_our_refs;
30
static int use_thin_pack, use_ofs_delta, use_include_tag;
31
static int no_progress, daemon_mode;
32
static int shallow_nr;
33 34
static struct object_array have_obj;
static struct object_array want_obj;
35
static struct object_array extra_edge_obj;
36
static unsigned int timeout;
37 38 39
/* 0 for no sideband,
 * otherwise maximum packet size (up to 65520 bytes).
 */
40
static int use_sideband;
41
static int debug_fd;
42 43 44 45 46

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

48 49 50 51 52 53 54
static int strip(char *line, int len)
{
	if (len && line[len-1] == '\n')
		line[--len] = 0;
	return len;
}

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
	}
67
	return safe_write(fd, data, sz);
68 69
}

J
Junio C Hamano 已提交
70
static FILE *pack_pipe = NULL;
71
static void show_commit(struct commit *commit, void *data)
72 73 74 75 76 77 78 79 80 81 82
{
	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;
}

83
static void show_object(struct object *obj, const struct name_path *path, const char *component)
84 85 86 87
{
	/* An object with name "foo\n0000000..." can be used to
	 * confuse downstream git-pack-objects very badly.
	 */
88
	const char *name = path_name(path, component);
89
	const char *ep = strchr(name, '\n');
90
	if (ep) {
91 92 93
		fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(obj->sha1),
		       (int) (ep - name),
		       name);
94 95 96
	}
	else
		fprintf(pack_pipe, "%s %s\n",
97
				sha1_to_hex(obj->sha1), name);
98
	free((char *)name);
99 100 101 102 103 104 105
}

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

106
static int do_rev_list(int fd, void *create_full_pack)
107 108 109 110
{
	int i;
	struct rev_info revs;

111
	pack_pipe = fdopen(fd, "w");
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	init_revisions(&revs, NULL);
	revs.tag_objects = 1;
	revs.tree_objects = 1;
	revs.blob_objects = 1;
	if (use_thin_pack)
		revs.edge_hint = 1;

	if (create_full_pack) {
		const char *args[] = {"rev-list", "--all", NULL};
		setup_revisions(2, args, &revs, NULL);
	} else {
		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);
		}
		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);
	}
136 137
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
138
	mark_edges_uninteresting(revs.commits, &revs, show_edge);
139 140 141 142
	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));
143
	traverse_commit_list(&revs, show_commit, show_object, NULL);
144 145
	fflush(pack_pipe);
	fclose(pack_pipe);
146
	return 0;
147 148
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
static int feed_msg_to_hook(int fd, const char *fmt, ...)
{
	int cnt;
	char buf[1024];
	va_list params;

	va_start(params, fmt);
	cnt = vsprintf(buf, fmt, params);
	va_end(params);
	return write_in_full(fd, buf, cnt) != cnt;
}

static int feed_obj_to_hook(const char *label, struct object_array *oa, int i, int fd)
{
	return feed_msg_to_hook(fd, "%s %s\n", label,
				sha1_to_hex(oa->objects[i].item->sha1));
}

static int run_post_upload_pack_hook(size_t total, struct timeval *tv)
{
	const char *argv[2];
	struct child_process proc;
	int err, i;

	argv[0] = "hooks/post-upload-pack";
	argv[1] = NULL;

	if (access(argv[0], X_OK) < 0)
		return 0;

	memset(&proc, 0, sizeof(proc));
	proc.argv = argv;
	proc.in = -1;
	proc.stdout_to_stderr = 1;
	err = start_command(&proc);
	if (err)
		return err;
	for (i = 0; !err && i < want_obj.nr; i++)
		err |= feed_obj_to_hook("want", &want_obj, i, proc.in);
	for (i = 0; !err && i < have_obj.nr; i++)
		err |= feed_obj_to_hook("have", &have_obj, i, proc.in);
	if (!err)
		err |= feed_msg_to_hook(proc.in, "time %ld.%06ld\n",
					(long)tv->tv_sec, (long)tv->tv_usec);
	if (!err)
		err |= feed_msg_to_hook(proc.in, "size %ld\n", (long)total);
195 196 197 198
	if (!err)
		err |= feed_msg_to_hook(proc.in, "kind %s\n",
					(nr_our_refs == want_obj.nr && !have_obj.nr)
					? "clone" : "fetch");
199 200 201 202 203 204 205
	if (close(proc.in))
		err = 1;
	if (finish_command(&proc))
		err = 1;
	return err;
}

206 207
static void create_pack_file(void)
{
208
	struct timeval start_tv, tv;
209
	struct async rev_list;
210
	struct child_process pack_objects;
211
	int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr);
212
	char data[8193], progress[128];
213 214
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
215
	int buffered = -1;
216
	ssize_t sz, total_sz;
217 218
	const char *argv[10];
	int arg = 0;
219

220 221
	gettimeofday(&start_tv, NULL);
	total_sz = 0;
222 223 224 225 226 227 228 229 230 231 232 233 234 235
	if (shallow_nr) {
		rev_list.proc = do_rev_list;
		rev_list.data = 0;
		if (start_async(&rev_list))
			die("git upload-pack: unable to fork git-rev-list");
		argv[arg++] = "pack-objects";
	} else {
		argv[arg++] = "pack-objects";
		argv[arg++] = "--revs";
		if (create_full_pack)
			argv[arg++] = "--all";
		else if (use_thin_pack)
			argv[arg++] = "--thin";
	}
236

237 238 239 240 241
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
242 243
	if (use_include_tag)
		argv[arg++] = "--include-tag";
244 245 246
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
247
	pack_objects.in = shallow_nr ? rev_list.out : -1;
248 249 250 251
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
252

253
	if (start_command(&pack_objects))
254
		die("git upload-pack: unable to fork git-pack-objects");
255

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
	/* pass on revisions we (don't) want */
	if (!shallow_nr) {
		FILE *pipe_fd = fdopen(pack_objects.in, "w");
		if (!create_full_pack) {
			int i;
			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));
		}

		fprintf(pipe_fd, "\n");
		fflush(pipe_fd);
		fclose(pipe_fd);
	}


274 275
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
276 277 278 279
	 */

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

282 283
		reset_timeout();

284
		pollsize = 0;
285
		pe = pu = -1;
286

287 288
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
289 290 291 292
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
293 294
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
295 296 297 298
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
299

300 301 302 303 304 305 306 307
		if (!pollsize)
			break;

		if (poll(pfd, pollsize, -1) < 0) {
			if (errno != EINTR) {
				error("poll failed, resuming: %s",
				      strerror(errno));
				sleep(1);
308
			}
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
			continue;
		}
		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++;
326
			}
327 328 329
			sz = xread(pack_objects.out, cp,
				  sizeof(data) - outsz);
			if (0 < sz)
330
				total_sz += sz;
331 332 333
			else if (sz == 0) {
				close(pack_objects.out);
				pack_objects.out = -1;
334
			}
335 336 337 338 339 340
			else
				goto fail;
			sz += outsz;
			if (1 < sz) {
				buffered = data[sz-1] & 0xFF;
				sz--;
341
			}
342 343 344 345
			else
				buffered = -1;
			sz = send_client_data(1, data, sz);
			if (sz < 0)
346
				goto fail;
347 348 349 350 351 352 353 354 355 356 357 358
		}
		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;
359
			}
360 361
			else
				goto fail;
362
		}
363
	}
364

365
	if (finish_command(&pack_objects)) {
366
		error("git upload-pack: git-pack-objects died with error.");
367 368
		goto fail;
	}
369
	if (shallow_nr && finish_async(&rev_list))
370
		goto fail;	/* error was already reported */
371

372 373 374 375 376 377 378
	/* 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");
379
	}
380 381
	if (use_sideband)
		packet_flush(1);
382 383 384 385 386 387 388 389 390 391

	gettimeofday(&tv, NULL);
	tv.tv_sec -= start_tv.tv_sec;
	if (tv.tv_usec < start_tv.tv_usec) {
		tv.tv_sec--;
		tv.tv_usec += 1000000;
	}
	tv.tv_usec -= start_tv.tv_usec;
	if (run_post_upload_pack_hook(total_sz, &tv))
		warning("post-upload-hook failed");
392 393
	return;

394
 fail:
395
	send_client_data(3, abort_msg, sizeof(abort_msg));
396
	die("git upload-pack: %s", abort_msg);
397 398
}

399 400
static int got_sha1(char *hex, unsigned char *sha1)
{
401
	struct object *o;
402
	int we_knew_they_have = 0;
403

404
	if (get_sha1_hex(hex, sha1))
405
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
406
	if (!has_sha1_file(sha1))
407
		return -1;
408 409 410 411 412 413

	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 已提交
414
	if (o->type == OBJ_COMMIT) {
415
		struct commit_list *parents;
416
		struct commit *commit = (struct commit *)o;
417
		if (o->flags & THEY_HAVE)
418 419 420 421 422 423
			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;
424 425 426
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
427
	}
428 429 430 431 432 433 434 435 436 437 438 439 440 441 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 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
	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;

	insert_by_date(want, &work);
	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))
				insert_by_date(parent, &work);
		}
	}
	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;
	}
494
	return 1;
495 496 497 498 499
}

static int get_common_commits(void)
{
	static char line[1000];
500 501
	unsigned char sha1[20];
	char hex[41], last_hex[41];
502

503 504
	save_commit_buffer = 0;

505
	for (;;) {
506
		int len = packet_read_line(0, line, sizeof(line));
507
		reset_timeout();
508 509

		if (!len) {
510
			if (have_obj.nr == 0 || multi_ack)
511
				packet_write(1, "NAK\n");
512 513
			continue;
		}
514
		strip(line, len);
515
		if (!prefixcmp(line, "have ")) {
516 517 518 519 520 521 522
			switch (got_sha1(line+5, sha1)) {
			case -1: /* they have what we do not */
				if (multi_ack && ok_to_give_up())
					packet_write(1, "ACK %s continue\n",
						     sha1_to_hex(sha1));
				break;
			default:
523 524 525 526 527 528 529 530
				memcpy(hex, sha1_to_hex(sha1), 41);
				if (multi_ack) {
					const char *msg = "ACK %s continue\n";
					packet_write(1, msg, hex);
					memcpy(last_hex, hex, 41);
				}
				else if (have_obj.nr == 1)
					packet_write(1, "ACK %s\n", hex);
531
				break;
532
			}
533 534 535
			continue;
		}
		if (!strcmp(line, "done")) {
536
			if (have_obj.nr > 0) {
537
				if (multi_ack)
538
					packet_write(1, "ACK %s\n", last_hex);
539 540
				return 0;
			}
541 542 543
			packet_write(1, "NAK\n");
			return -1;
		}
544
		die("git upload-pack: expected SHA1 list, got '%s'", line);
545 546 547
	}
}

548
static void receive_needs(void)
549
{
550
	struct object_array shallows = {0, 0, NULL};
551
	static char line[1000];
552
	int len, depth = 0;
553

554
	shallow_nr = 0;
555 556
	if (debug_fd)
		write_in_full(debug_fd, "#S\n", 3);
557
	for (;;) {
558
		struct object *o;
559
		unsigned char sha1_buf[20];
560
		len = packet_read_line(0, line, sizeof(line));
561
		reset_timeout();
562
		if (!len)
563
			break;
564 565
		if (debug_fd)
			write_in_full(debug_fd, line, len);
566

567
		if (!prefixcmp(line, "shallow ")) {
568 569 570 571 572 573 574
			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);
575
			object->flags |= CLIENT_SHALLOW;
576 577 578
			add_object_array(object, NULL, &shallows);
			continue;
		}
579
		if (!prefixcmp(line, "deepen ")) {
580 581 582 583 584 585
			char *end;
			depth = strtol(line + 7, &end, 0);
			if (end == line + 7 || depth <= 0)
				die("Invalid deepen: %s", line);
			continue;
		}
586
		if (prefixcmp(line, "want ") ||
587
		    get_sha1_hex(line+5, sha1_buf))
588
			die("git upload-pack: protocol error, "
589
			    "expected to get sha, not '%s'", line);
590 591
		if (strstr(line+45, "multi_ack"))
			multi_ack = 1;
592 593
		if (strstr(line+45, "thin-pack"))
			use_thin_pack = 1;
594 595
		if (strstr(line+45, "ofs-delta"))
			use_ofs_delta = 1;
596 597 598 599
		if (strstr(line+45, "side-band-64k"))
			use_sideband = LARGE_PACKET_MAX;
		else if (strstr(line+45, "side-band"))
			use_sideband = DEFAULT_PACKET_MAX;
600 601
		if (strstr(line+45, "no-progress"))
			no_progress = 1;
602 603
		if (strstr(line+45, "include-tag"))
			use_include_tag = 1;
604 605 606 607 608 609 610 611 612 613 614

		/* We have sent all our refs already, and the other end
		 * should have chosen out of them; otherwise they are
		 * asking for nonsense.
		 *
		 * Hmph.  We may later want to allow "want" line that
		 * asks for something like "master~10" (symbolic)...
		 * would it make sense?  I don't know.
		 */
		o = lookup_object(sha1_buf);
		if (!o || !(o->flags & OUR_REF))
615
			die("git upload-pack: not our ref %s", line+5);
616 617
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
618
			add_object_array(o, NULL, &want_obj);
619
		}
620
	}
621 622
	if (debug_fd)
		write_in_full(debug_fd, "#E\n", 3);
623 624 625 626

	if (!use_sideband && daemon_mode)
		no_progress = 1;

627 628
	if (depth == 0 && shallows.nr == 0)
		return;
629 630
	if (depth > 0) {
		struct commit_list *result, *backup;
631 632 633
		int i;
		backup = result = get_shallow_commits(&want_obj, depth,
			SHALLOW, NOT_SHALLOW);
634
		while (result) {
635
			struct object *object = &result->item->object;
636
			if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
637 638 639
				packet_write(1, "shallow %s",
						sha1_to_hex(object->sha1));
				register_shallow(object->sha1);
640
				shallow_nr++;
641
			}
642 643 644
			result = result->next;
		}
		free_commit_list(backup);
645 646 647 648 649 650 651 652 653
		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);
654
				object->parsed = 0;
655 656
				if (parse_commit((struct commit *)object))
					die("invalid commit");
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
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
681
{
682
	static const char *capabilities = "multi_ack thin-pack side-band"
683 684
		" side-band-64k ofs-delta shallow no-progress"
		" include-tag";
685 686
	struct object *o = parse_object(sha1);

687
	if (!o)
688
		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
689

J
Johannes Schindelin 已提交
690 691 692 693 694 695
	if (capabilities)
		packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
			0, capabilities);
	else
		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
	capabilities = NULL;
696 697 698 699
	if (!(o->flags & OUR_REF)) {
		o->flags |= OUR_REF;
		nr_our_refs++;
	}
700
	if (o->type == OBJ_TAG) {
701
		o = deref_tag(o, refname, 0);
702 703
		if (o)
			packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
704
	}
705 706 707
	return 0;
}

708
static void upload_pack(void)
709
{
710
	reset_timeout();
711 712
	head_ref(send_ref, NULL);
	for_each_ref(send_ref, NULL);
713
	packet_flush(1);
714
	receive_needs();
715 716 717 718
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
719 720 721 722
}

int main(int argc, char **argv)
{
723
	char *dir;
724 725 726
	int i;
	int strict = 0;

727
	git_extract_argv0_path(argv[0]);
728
	read_replace_refs = 0;
729

730 731 732 733 734 735 736 737 738
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

		if (arg[0] != '-')
			break;
		if (!strcmp(arg, "--strict")) {
			strict = 1;
			continue;
		}
739
		if (!prefixcmp(arg, "--timeout=")) {
740
			timeout = atoi(arg+10);
741
			daemon_mode = 1;
742 743 744 745 746 747 748
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
	}
J
Junio C Hamano 已提交
749

750
	if (i != argc-1)
751
		usage(upload_pack_usage);
752

753
	setup_path();
754

755
	dir = argv[i];
756

757
	if (!enter_repo(dir, strict))
758
		die("'%s' does not appear to be a git repository", dir);
759 760
	if (is_repository_shallow())
		die("attempt to fetch/clone from a shallow repository");
761 762
	if (getenv("GIT_DEBUG_SEND_PACK"))
		debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
763 764 765
	upload_pack();
	return 0;
}