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
		struct rev_info revs;

122
		close(lp_pipe[0]);
123
		pack_pipe = fdopen(lp_pipe[1], "w");
124

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

	if (pipe(pu_pipe) < 0)
		die("git-upload-pack: unable to create pipe");
159 160
	if (pipe(pe_pipe) < 0)
		die("git-upload-pack: unable to create pipe");
161 162 163 164 165 166 167
	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) {
168 169 170
		const char *argv[10];
		int i = 0;

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

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

		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);
191 192 193 194 195 196 197
		kill(pid_rev_list, SIGKILL);
		die("git-upload-pack: unable to exec git-pack-objects");
	}

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

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

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

212 213
		reset_timeout();

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

		if (0 <= pu_pipe[0]) {
			pfd[pollsize].fd = pu_pipe[0];
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
223 224 225 226 227 228
		if (0 <= pe_pipe[0]) {
			pfd[pollsize].fd = pe_pipe[0];
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
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 256

		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++;
				}
257
				sz = xread(pu_pipe[0], cp,
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
					  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;
274
				sz = send_client_data(1, data, sz);
275 276 277
				if (sz < 0)
					goto fail;
			}
278
			if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
279 280
				/* Status ready; we ship that in the side-band
				 * or dump to the standard error.
281
				 */
282
				sz = xread(pe_pipe[0], progress,
283 284
					  sizeof(progress));
				if (0 < sz)
285
					send_client_data(2, progress, sz);
286 287 288 289 290 291 292
				else if (sz == 0) {
					close(pe_pipe[0]);
					pe_pipe[0] = -1;
				}
				else
					goto fail;
			}
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 332
		}

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

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

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

	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 已提交
366
	if (o->type == OBJ_COMMIT) {
367
		struct commit_list *parents;
368
		struct commit *commit = (struct commit *)o;
369
		if (o->flags & THEY_HAVE)
370 371 372 373 374 375
			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;
376 377 378
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
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 445
	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;
	}
446
	return 1;
447 448 449 450 451
}

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

456 457 458
	track_object_refs = 0;
	save_commit_buffer = 0;

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

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

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

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

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

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

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

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

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

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

int main(int argc, char **argv)
{
659
	char *dir;
660 661 662 663 664 665 666 667 668 669 670 671
	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;
		}
672
		if (!prefixcmp(arg, "--timeout=")) {
673 674 675 676 677 678 679 680 681 682
			timeout = atoi(arg+10);
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
	}
	
	if (i != argc-1)
683
		usage(upload_pack_usage);
684
	dir = argv[i];
685

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