upload-pack.c 17.4 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
static int advertise_refs;
static int stateless_rpc;
44 45 46 47 48

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

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

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

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

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

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

108
static int do_rev_list(int in, int out, void *user_data)
109 110 111 112
{
	int i;
	struct rev_info revs;

113
	pack_pipe = xfdopen(out, "w");
114 115 116 117 118 119 120
	init_revisions(&revs, NULL);
	revs.tag_objects = 1;
	revs.tree_objects = 1;
	revs.blob_objects = 1;
	if (use_thin_pack)
		revs.edge_hint = 1;

121 122 123 124 125
	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);
126
	}
127 128 129 130 131 132
	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);
133 134
	if (prepare_revision_walk(&revs))
		die("revision walk setup failed");
135
	mark_edges_uninteresting(revs.commits, &revs, show_edge);
136 137 138 139
	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));
140
	traverse_commit_list(&revs, show_commit, show_object, NULL);
141 142
	fflush(pack_pipe);
	fclose(pack_pipe);
143
	return 0;
144 145
}

146 147
static void create_pack_file(void)
{
148
	struct async rev_list;
149
	struct child_process pack_objects;
150
	int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr);
151
	char data[8193], progress[128];
152 153
	char abort_msg[] = "aborting due to possible repository "
		"corruption on the remote side.";
154
	int buffered = -1;
J
Junio C Hamano 已提交
155
	ssize_t sz;
156 157
	const char *argv[10];
	int arg = 0;
158

159
	if (shallow_nr) {
160
		memset(&rev_list, 0, sizeof(rev_list));
161
		rev_list.proc = do_rev_list;
162
		rev_list.out = -1;
163 164 165 166 167 168 169 170 171 172 173
		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";
	}
174

175 176 177 178 179
	argv[arg++] = "--stdout";
	if (!no_progress)
		argv[arg++] = "--progress";
	if (use_ofs_delta)
		argv[arg++] = "--delta-base-offset";
180 181
	if (use_include_tag)
		argv[arg++] = "--include-tag";
182 183 184
	argv[arg++] = NULL;

	memset(&pack_objects, 0, sizeof(pack_objects));
185
	pack_objects.in = shallow_nr ? rev_list.out : -1;
186 187 188 189
	pack_objects.out = -1;
	pack_objects.err = -1;
	pack_objects.git_cmd = 1;
	pack_objects.argv = argv;
190

191
	if (start_command(&pack_objects))
192
		die("git upload-pack: unable to fork git-pack-objects");
193

194 195
	/* pass on revisions we (don't) want */
	if (!shallow_nr) {
196
		FILE *pipe_fd = xfdopen(pack_objects.in, "w");
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
		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);
	}


212 213
	/* We read from pack_objects.err to capture stderr output for
	 * progress bar, and pack_objects.out to capture the pack data.
214 215 216 217
	 */

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

220 221
		reset_timeout();

222
		pollsize = 0;
223
		pe = pu = -1;
224

225 226
		if (0 <= pack_objects.out) {
			pfd[pollsize].fd = pack_objects.out;
227 228 229 230
			pfd[pollsize].events = POLLIN;
			pu = pollsize;
			pollsize++;
		}
231 232
		if (0 <= pack_objects.err) {
			pfd[pollsize].fd = pack_objects.err;
233 234 235 236
			pfd[pollsize].events = POLLIN;
			pe = pollsize;
			pollsize++;
		}
237

238 239 240 241 242 243 244 245
		if (!pollsize)
			break;

		if (poll(pfd, pollsize, -1) < 0) {
			if (errno != EINTR) {
				error("poll failed, resuming: %s",
				      strerror(errno));
				sleep(1);
246
			}
247 248
			continue;
		}
N
Nicolas Pitre 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
		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;
		}
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
		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++;
281
			}
282 283 284
			sz = xread(pack_objects.out, cp,
				  sizeof(data) - outsz);
			if (0 < sz)
J
Junio C Hamano 已提交
285
				;
286 287 288
			else if (sz == 0) {
				close(pack_objects.out);
				pack_objects.out = -1;
289
			}
290 291 292 293 294 295
			else
				goto fail;
			sz += outsz;
			if (1 < sz) {
				buffered = data[sz-1] & 0xFF;
				sz--;
296
			}
297 298 299 300
			else
				buffered = -1;
			sz = send_client_data(1, data, sz);
			if (sz < 0)
301
				goto fail;
302 303
		}
	}
304

305
	if (finish_command(&pack_objects)) {
306
		error("git upload-pack: git-pack-objects died with error.");
307 308
		goto fail;
	}
309
	if (shallow_nr && finish_async(&rev_list))
310
		goto fail;	/* error was already reported */
311

312 313 314 315 316 317 318
	/* 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");
319
	}
320 321 322 323
	if (use_sideband)
		packet_flush(1);
	return;

324
 fail:
325
	send_client_data(3, abort_msg, sizeof(abort_msg));
326
	die("git upload-pack: %s", abort_msg);
327 328
}

329 330
static int got_sha1(char *hex, unsigned char *sha1)
{
331
	struct object *o;
332
	int we_knew_they_have = 0;
333

334
	if (get_sha1_hex(hex, sha1))
335
		die("git upload-pack: expected SHA1 object, got '%s'", hex);
336
	if (!has_sha1_file(sha1))
337
		return -1;
338 339 340 341 342 343

	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 已提交
344
	if (o->type == OBJ_COMMIT) {
345
		struct commit_list *parents;
346
		struct commit *commit = (struct commit *)o;
347
		if (o->flags & THEY_HAVE)
348 349 350 351 352 353
			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;
354 355 356
		     parents;
		     parents = parents->next)
			parents->item->object.flags |= THEY_HAVE;
357
	}
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 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
	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;
	}
424
	return 1;
425 426 427 428 429
}

static int get_common_commits(void)
{
	static char line[1000];
430
	unsigned char sha1[20];
431
	char last_hex[41];
432

433 434
	save_commit_buffer = 0;

435
	for (;;) {
436
		int len = packet_read_line(0, line, sizeof(line));
437
		reset_timeout();
438 439

		if (!len) {
440
			if (have_obj.nr == 0 || multi_ack)
441
				packet_write(1, "NAK\n");
442 443
			if (stateless_rpc)
				exit(0);
444 445
			continue;
		}
446
		strip(line, len);
447
		if (!prefixcmp(line, "have ")) {
448 449
			switch (got_sha1(line+5, sha1)) {
			case -1: /* they have what we do not */
450 451 452 453 454 455 456
				if (multi_ack && ok_to_give_up()) {
					const char *hex = sha1_to_hex(sha1);
					if (multi_ack == 2)
						packet_write(1, "ACK %s ready\n", hex);
					else
						packet_write(1, "ACK %s continue\n", hex);
				}
457 458
				break;
			default:
459 460 461 462 463
				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);
464
				else if (have_obj.nr == 1)
465
					packet_write(1, "ACK %s\n", last_hex);
466
				break;
467
			}
468 469 470
			continue;
		}
		if (!strcmp(line, "done")) {
471
			if (have_obj.nr > 0) {
472
				if (multi_ack)
473
					packet_write(1, "ACK %s\n", last_hex);
474 475
				return 0;
			}
476 477 478
			packet_write(1, "NAK\n");
			return -1;
		}
479
		die("git upload-pack: expected SHA1 list, got '%s'", line);
480 481 482
	}
}

483
static void receive_needs(void)
484
{
485
	struct object_array shallows = {0, 0, NULL};
486
	static char line[1000];
487
	int len, depth = 0;
488

489
	shallow_nr = 0;
490
	if (debug_fd)
491
		write_str_in_full(debug_fd, "#S\n");
492
	for (;;) {
493
		struct object *o;
494
		unsigned char sha1_buf[20];
495
		len = packet_read_line(0, line, sizeof(line));
496
		reset_timeout();
497
		if (!len)
498
			break;
499 500
		if (debug_fd)
			write_in_full(debug_fd, line, len);
501

502
		if (!prefixcmp(line, "shallow ")) {
503 504 505 506 507 508 509
			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);
510
			object->flags |= CLIENT_SHALLOW;
511 512 513
			add_object_array(object, NULL, &shallows);
			continue;
		}
514
		if (!prefixcmp(line, "deepen ")) {
515 516 517 518 519 520
			char *end;
			depth = strtol(line + 7, &end, 0);
			if (end == line + 7 || depth <= 0)
				die("Invalid deepen: %s", line);
			continue;
		}
521
		if (prefixcmp(line, "want ") ||
522
		    get_sha1_hex(line+5, sha1_buf))
523
			die("git upload-pack: protocol error, "
524
			    "expected to get sha, not '%s'", line);
525 526 527
		if (strstr(line+45, "multi_ack_detailed"))
			multi_ack = 2;
		else if (strstr(line+45, "multi_ack"))
528
			multi_ack = 1;
529 530
		if (strstr(line+45, "thin-pack"))
			use_thin_pack = 1;
531 532
		if (strstr(line+45, "ofs-delta"))
			use_ofs_delta = 1;
533 534 535 536
		if (strstr(line+45, "side-band-64k"))
			use_sideband = LARGE_PACKET_MAX;
		else if (strstr(line+45, "side-band"))
			use_sideband = DEFAULT_PACKET_MAX;
537 538
		if (strstr(line+45, "no-progress"))
			no_progress = 1;
539 540
		if (strstr(line+45, "include-tag"))
			use_include_tag = 1;
541 542 543 544 545 546 547 548 549 550 551

		/* 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))
552
			die("git upload-pack: not our ref %s", line+5);
553 554
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
555
			add_object_array(o, NULL, &want_obj);
556
		}
557
	}
558
	if (debug_fd)
559
		write_str_in_full(debug_fd, "#E\n");
560 561 562 563

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

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

	shallow_nr += shallows.nr;
614
	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
		" include-tag multi_ack_detailed";
622 623
	struct object *o = parse_object(sha1);

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

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
		if (o)
			packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
641
	}
642 643 644
	return 0;
}

645 646 647 648 649 650 651 652 653 654 655 656
static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
	struct object *o = parse_object(sha1);
	if (!o)
		die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
	if (!(o->flags & OUR_REF)) {
		o->flags |= OUR_REF;
		nr_our_refs++;
	}
	return 0;
}

657
static void upload_pack(void)
658
{
659 660 661 662 663 664 665 666 667 668 669 670
	if (advertise_refs || !stateless_rpc) {
		reset_timeout();
		head_ref(send_ref, NULL);
		for_each_ref(send_ref, NULL);
		packet_flush(1);
	} else {
		head_ref(mark_our_ref, NULL);
		for_each_ref(mark_our_ref, NULL);
	}
	if (advertise_refs)
		return;

671
	receive_needs();
672 673 674 675
	if (want_obj.nr) {
		get_common_commits();
		create_pack_file();
	}
676 677 678 679
}

int main(int argc, char **argv)
{
680
	char *dir;
681 682 683
	int i;
	int strict = 0;

684
	git_extract_argv0_path(argv[0]);
685
	read_replace_refs = 0;
686

687 688 689 690 691
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

		if (arg[0] != '-')
			break;
692 693 694 695 696 697 698 699
		if (!strcmp(arg, "--advertise-refs")) {
			advertise_refs = 1;
			continue;
		}
		if (!strcmp(arg, "--stateless-rpc")) {
			stateless_rpc = 1;
			continue;
		}
700 701 702 703
		if (!strcmp(arg, "--strict")) {
			strict = 1;
			continue;
		}
704
		if (!prefixcmp(arg, "--timeout=")) {
705
			timeout = atoi(arg+10);
706
			daemon_mode = 1;
707 708 709 710 711 712 713
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			break;
		}
	}
J
Junio C Hamano 已提交
714

715
	if (i != argc-1)
716
		usage(upload_pack_usage);
717

718
	setup_path();
719

720
	dir = argv[i];
721

722
	if (!enter_repo(dir, strict))
723
		die("'%s' does not appear to be a git repository", dir);
724 725
	if (is_repository_shallow())
		die("attempt to fetch/clone from a shallow repository");
726 727
	if (getenv("GIT_DEBUG_SEND_PACK"))
		debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
728 729 730
	upload_pack();
	return 0;
}