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

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

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

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

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

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

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

43 44 45 46 47 48 49
static int strip(char *line, int len)
{
	if (len && line[len-1] == '\n')
		line[--len] = 0;
	return len;
}

50 51
static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
{
52
	if (use_sideband)
53
		return send_sideband(1, fd, data, sz, use_sideband);
54 55 56 57
	if (fd == 3)
		/* emergency quit */
		fd = 2;
	if (fd == 2) {
58
		/* XXX: are we happy to lose stuff here? */
59 60
		xwrite(fd, data, sz);
		return sz;
61
	}
62
	return safe_write(fd, data, sz);
63 64
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
FILE *pack_pipe = NULL;
static void show_commit(struct commit *commit)
{
	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;
}

static void show_object(struct object_array_entry *p)
{
	/* An object with name "foo\n0000000..." can be used to
	 * confuse downstream git-pack-objects very badly.
	 */
	const char *ep = strchr(p->name, '\n');
	if (ep) {
		fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(p->item->sha1),
		       (int) (ep - p->name),
		       p->name);
	}
	else
		fprintf(pack_pipe, "%s %s\n",
				sha1_to_hex(p->item->sha1), p->name);
}

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

99 100
static void create_pack_file(void)
{
101 102 103 104
	/* Pipes between rev-list to pack-objects, pack-objects to us
	 * and pack-objects error stream for progress bar.
	 */
	int lp_pipe[2], pu_pipe[2], pe_pipe[2];
105
	pid_t pid_rev_list, pid_pack_objects;
106
	int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr);
107
	char data[8193], progress[128];
108 109
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
110
	int buffered = -1;
111

112
	if (pipe(lp_pipe) < 0)
113
		die("git-upload-pack: unable to create pipe");
114 115
	pid_rev_list = fork();
	if (pid_rev_list < 0)
116 117
		die("git-upload-pack: unable to fork git-rev-list");

118
	if (!pid_rev_list) {
119
		int i;
120 121 122
		struct rev_info revs;

		pack_pipe = fdopen(lp_pipe[1], "w");
123

124
		if (create_full_pack)
125 126 127 128 129 130 131 132 133 134 135 136
			use_thin_pack = 0; /* no point doing it */
		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 {
137 138
			for (i = 0; i < want_obj.nr; i++) {
				struct object *o = want_obj.objects[i].item;
139
				/* why??? */
140
				o->flags &= ~UNINTERESTING;
141
				add_pending_object(&revs, o, NULL);
142
			}
143 144
			for (i = 0; i < have_obj.nr; i++) {
				struct object *o = have_obj.objects[i].item;
145 146
				o->flags |= UNINTERESTING;
				add_pending_object(&revs, o, NULL);
147
			}
148 149 150 151 152 153
			setup_revisions(0, NULL, &revs, NULL);
		}
		prepare_revision_walk(&revs);
		mark_edges_uninteresting(revs.commits, &revs, show_edge);
		traverse_commit_list(&revs, show_commit, show_object);
		exit(0);
154
	}
155 156 157

	if (pipe(pu_pipe) < 0)
		die("git-upload-pack: unable to create pipe");
158 159
	if (pipe(pe_pipe) < 0)
		die("git-upload-pack: unable to create pipe");
160 161 162 163 164 165 166
	pid_pack_objects = fork();
	if (pid_pack_objects < 0) {
		/* daemon sets things up to ignore TERM */
		kill(pid_rev_list, SIGKILL);
		die("git-upload-pack: unable to fork git-pack-objects");
	}
	if (!pid_pack_objects) {
167 168 169
		const char *argv[10];
		int i = 0;

170 171
		dup2(lp_pipe[0], 0);
		dup2(pu_pipe[1], 1);
172
		dup2(pe_pipe[1], 2);
173 174 175 176 177

		close(lp_pipe[0]);
		close(lp_pipe[1]);
		close(pu_pipe[0]);
		close(pu_pipe[1]);
178 179
		close(pe_pipe[0]);
		close(pe_pipe[1]);
180 181 182 183 184 185 186 187 188 189

		argv[i++] = "pack-objects";
		argv[i++] = "--stdout";
		if (!no_progress)
			argv[i++] = "--progress";
		if (use_ofs_delta)
			argv[i++] = "--delta-base-offset";
		argv[i++] = NULL;

		execv_git_cmd(argv);
190 191 192 193 194 195 196
		kill(pid_rev_list, SIGKILL);
		die("git-upload-pack: unable to exec git-pack-objects");
	}

	close(lp_pipe[0]);
	close(lp_pipe[1]);

197 198
	/* We read from pe_pipe[0] to capture stderr output for
	 * progress bar, and pu_pipe[0] to capture the pack data.
199
	 */
200
	close(pe_pipe[1]);
201 202 203 204 205 206 207 208
	close(pu_pipe[1]);

	while (1) {
		const char *who;
		struct pollfd pfd[2];
		pid_t pid;
		int status;
		ssize_t sz;
209
		int pe, pu, pollsize;
210

211 212
		reset_timeout();

213
		pollsize = 0;
214
		pe = pu = -1;
215 216 217 218 219 220 221

		if (0 <= pu_pipe[0]) {
			pfd[pollsize].fd = pu_pipe[0];
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
222 223 224 225 226 227
		if (0 <= pe_pipe[0]) {
			pfd[pollsize].fd = pe_pipe[0];
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255

		if (pollsize) {
			if (poll(pfd, pollsize, -1) < 0) {
				if (errno != EINTR) {
					error("poll failed, resuming: %s",
					      strerror(errno));
					sleep(1);
				}
				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 pack
				 * data 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++;
				}
256
				sz = xread(pu_pipe[0], cp,
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
					  sizeof(data) - outsz);
				if (0 < sz)
						;
				else if (sz == 0) {
					close(pu_pipe[0]);
					pu_pipe[0] = -1;
				}
				else
					goto fail;
				sz += outsz;
				if (1 < sz) {
					buffered = data[sz-1] & 0xFF;
					sz--;
				}
				else
					buffered = -1;
273
				sz = send_client_data(1, data, sz);
274 275 276
				if (sz < 0)
					goto fail;
			}
277
			if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
278 279
				/* Status ready; we ship that in the side-band
				 * or dump to the standard error.
280
				 */
281
				sz = xread(pe_pipe[0], progress,
282 283
					  sizeof(progress));
				if (0 < sz)
284
					send_client_data(2, progress, sz);
285 286 287 288 289 290 291
				else if (sz == 0) {
					close(pe_pipe[0]);
					pe_pipe[0] = -1;
				}
				else
					goto fail;
			}
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
		}

		/* See if the children are still there */
		if (pid_rev_list || pid_pack_objects) {
			pid = waitpid(-1, &status, WNOHANG);
			if (!pid)
				continue;
			who = ((pid == pid_rev_list) ? "git-rev-list" :
			       (pid == pid_pack_objects) ? "git-pack-objects" :
			       NULL);
			if (!who) {
				if (pid < 0) {
					error("git-upload-pack: %s",
					      strerror(errno));
					goto fail;
				}
				error("git-upload-pack: we weren't "
				      "waiting for %d", pid);
				continue;
			}
			if (!WIFEXITED(status) || WEXITSTATUS(status) > 0) {
				error("git-upload-pack: %s died with error.",
				      who);
				goto fail;
			}
			if (pid == pid_rev_list)
				pid_rev_list = 0;
			if (pid == pid_pack_objects)
				pid_pack_objects = 0;
			if (pid_rev_list || pid_pack_objects)
				continue;
		}

		/* both died happily */
		if (pollsize)
			continue;

		/* flush the data */
		if (0 <= buffered) {
			data[0] = buffered;
332
			sz = send_client_data(1, data, 1);
333 334 335 336
			if (sz < 0)
				goto fail;
			fprintf(stderr, "flushed.\n");
		}
337 338
		if (use_sideband)
			packet_flush(1);
339 340 341 342 343 344 345
		return;
	}
 fail:
	if (pid_pack_objects)
		kill(pid_pack_objects, SIGKILL);
	if (pid_rev_list)
		kill(pid_rev_list, SIGKILL);
346 347
	send_client_data(3, abort_msg, sizeof(abort_msg));
	die("git-upload-pack: %s", abort_msg);
348 349
}

350 351
static int got_sha1(char *hex, unsigned char *sha1)
{
352
	struct object *o;
353
	int we_knew_they_have = 0;
354

355 356
	if (get_sha1_hex(hex, sha1))
		die("git-upload-pack: expected SHA1 object, got '%s'", hex);
357
	if (!has_sha1_file(sha1))
358
		return -1;
359 360 361 362 363 364

	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 已提交
365
	if (o->type == OBJ_COMMIT) {
366
		struct commit_list *parents;
367
		struct commit *commit = (struct commit *)o;
368
		if (o->flags & THEY_HAVE)
369 370 371 372 373 374
			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;
375 376 377
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
378
	}
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
	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;
	}
445
	return 1;
446 447 448 449 450
}

static int get_common_commits(void)
{
	static char line[1000];
451 452
	unsigned char sha1[20];
	char hex[41], last_hex[41];
453 454
	int len;

455 456 457
	track_object_refs = 0;
	save_commit_buffer = 0;

458 459
	for(;;) {
		len = packet_read_line(0, line, sizeof(line));
460
		reset_timeout();
461 462

		if (!len) {
463
			if (have_obj.nr == 0 || multi_ack)
464
				packet_write(1, "NAK\n");
465 466
			continue;
		}
467
		len = strip(line, len);
468
		if (!prefixcmp(line, "have ")) {
469 470 471 472 473 474 475
			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:
476 477 478 479 480 481 482 483
				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);
484
				break;
485
			}
486 487 488
			continue;
		}
		if (!strcmp(line, "done")) {
489
			if (have_obj.nr > 0) {
490
				if (multi_ack)
491
					packet_write(1, "ACK %s\n", last_hex);
492 493
				return 0;
			}
494 495 496 497 498 499 500
			packet_write(1, "NAK\n");
			return -1;
		}
		die("git-upload-pack: expected SHA1 list, got '%s'", line);
	}
}

501
static void receive_needs(void)
502
{
503
	struct object_array shallows = {0, 0, NULL};
504
	static char line[1000];
505
	int len, depth = 0;
506 507

	for (;;) {
508
		struct object *o;
509
		unsigned char sha1_buf[20];
510
		len = packet_read_line(0, line, sizeof(line));
511
		reset_timeout();
512
		if (!len)
513
			break;
514

515
		if (!prefixcmp(line, "shallow ")) {
516 517
			unsigned char sha1[20];
			struct object *object;
518
			use_thin_pack = 0;
519 520 521 522 523
			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);
524
			object->flags |= CLIENT_SHALLOW;
525 526 527
			add_object_array(object, NULL, &shallows);
			continue;
		}
528
		if (!prefixcmp(line, "deepen ")) {
529
			char *end;
530
			use_thin_pack = 0;
531 532 533 534 535
			depth = strtol(line + 7, &end, 0);
			if (end == line + 7 || depth <= 0)
				die("Invalid deepen: %s", line);
			continue;
		}
536
		if (prefixcmp(line, "want ") ||
537
		    get_sha1_hex(line+5, sha1_buf))
538 539
			die("git-upload-pack: protocol error, "
			    "expected to get sha, not '%s'", line);
540 541
		if (strstr(line+45, "multi_ack"))
			multi_ack = 1;
542 543
		if (strstr(line+45, "thin-pack"))
			use_thin_pack = 1;
544 545
		if (strstr(line+45, "ofs-delta"))
			use_ofs_delta = 1;
546 547 548 549
		if (strstr(line+45, "side-band-64k"))
			use_sideband = LARGE_PACKET_MAX;
		else if (strstr(line+45, "side-band"))
			use_sideband = DEFAULT_PACKET_MAX;
550 551
		if (strstr(line+45, "no-progress"))
			no_progress = 1;
552 553 554 555 556 557 558 559 560 561 562 563 564 565

		/* 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))
			die("git-upload-pack: not our ref %s", line+5);
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
566
			add_object_array(o, NULL, &want_obj);
567
		}
568
	}
569 570
	if (depth == 0 && shallows.nr == 0)
		return;
571 572
	if (depth > 0) {
		struct commit_list *result, *backup;
573 574 575
		int i;
		backup = result = get_shallow_commits(&want_obj, depth,
			SHALLOW, NOT_SHALLOW);
576
		while (result) {
577
			struct object *object = &result->item->object;
578
			if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
579 580 581 582
				packet_write(1, "shallow %s",
						sha1_to_hex(object->sha1));
				register_shallow(object->sha1);
			}
583 584 585
			result = result->next;
		}
		free_commit_list(backup);
586 587 588 589 590 591 592 593 594
		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);
595
				object->parsed = 0;
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
				parse_commit((struct commit *)object);
				parents = ((struct commit *)object)->parents;
				while (parents) {
					add_object_array(&parents->item->object,
							NULL, &want_obj);
					parents = parents->next;
				}
			}
			/* 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);
		}
	free(shallows.objects);
615 616
}

617
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
618
{
619
	static const char *capabilities = "multi_ack thin-pack side-band"
620
		" side-band-64k ofs-delta shallow no-progress";
621 622
	struct object *o = parse_object(sha1);

623 624 625
	if (!o)
		die("git-upload-pack: cannot find object %s:", sha1_to_hex(sha1));

J
Johannes Schindelin 已提交
626 627 628 629 630 631
	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;
632 633 634 635
	if (!(o->flags & OUR_REF)) {
		o->flags |= OUR_REF;
		nr_our_refs++;
	}
636
	if (o->type == OBJ_TAG) {
637
		o = deref_tag(o, refname, 0);
638 639
		packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
	}
640 641 642
	return 0;
}

643
static void upload_pack(void)
644
{
645
	reset_timeout();
646 647
	head_ref(send_ref, NULL);
	for_each_ref(send_ref, NULL);
648
	packet_flush(1);
649
	receive_needs();
650 651 652 653
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
654 655 656 657
}

int main(int argc, char **argv)
{
658
	char *dir;
659 660 661 662 663 664 665 666 667 668 669 670
	int i;
	int strict = 0;

	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

		if (arg[0] != '-')
			break;
		if (!strcmp(arg, "--strict")) {
			strict = 1;
			continue;
		}
671
		if (!prefixcmp(arg, "--timeout=")) {
672 673 674 675 676 677 678 679 680 681
			timeout = atoi(arg+10);
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
	}
	
	if (i != argc-1)
682
		usage(upload_pack_usage);
683
	dir = argv[i];
684

685 686
	if (!enter_repo(dir, strict))
		die("'%s': unable to chdir or not a git archive", dir);
687 688
	if (is_repository_shallow())
		die("attempt to fetch/clone from a shallow repository");
689 690 691
	upload_pack();
	return 0;
}