receive-pack.c 20.3 KB
Newer Older
1
#include "builtin.h"
2
#include "pack.h"
3
#include "refs.h"
4
#include "pkt-line.h"
5
#include "sideband.h"
6
#include "run-command.h"
7
#include "exec_cmd.h"
8 9
#include "commit.h"
#include "object.h"
10 11
#include "remote.h"
#include "transport.h"
12
#include "string-list.h"
13
#include "sha1-array.h"
14

15
static const char receive_pack_usage[] = "git receive-pack <git-dir>";
16

17
enum deny_action {
18
	DENY_UNCONFIGURED,
19 20
	DENY_IGNORE,
	DENY_WARN,
21
	DENY_REFUSE
22 23
};

24 25
static int deny_deletes;
static int deny_non_fast_forwards;
26
static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
27
static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
28
static int receive_fsck_objects;
29 30
static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
31
static int unpack_limit = 100;
32
static int report_status;
33
static int use_sideband;
34
static int prefer_ofs_delta = 1;
35 36
static int auto_update_server_info;
static int auto_gc = 1;
37
static const char *head_name;
38
static int sent_capabilities;
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
static enum deny_action parse_deny_action(const char *var, const char *value)
{
	if (value) {
		if (!strcasecmp(value, "ignore"))
			return DENY_IGNORE;
		if (!strcasecmp(value, "warn"))
			return DENY_WARN;
		if (!strcasecmp(value, "refuse"))
			return DENY_REFUSE;
	}
	if (git_config_bool(var, value))
		return DENY_REFUSE;
	return DENY_IGNORE;
}

55
static int receive_pack_config(const char *var, const char *value, void *cb)
56
{
J
Jan Krüger 已提交
57 58 59 60 61
	if (strcmp(var, "receive.denydeletes") == 0) {
		deny_deletes = git_config_bool(var, value);
		return 0;
	}

62
	if (strcmp(var, "receive.denynonfastforwards") == 0) {
63 64 65 66
		deny_non_fast_forwards = git_config_bool(var, value);
		return 0;
	}

67 68
	if (strcmp(var, "receive.unpacklimit") == 0) {
		receive_unpack_limit = git_config_int(var, value);
69 70 71
		return 0;
	}

72 73 74 75 76
	if (strcmp(var, "transfer.unpacklimit") == 0) {
		transfer_unpack_limit = git_config_int(var, value);
		return 0;
	}

77 78 79 80 81
	if (strcmp(var, "receive.fsckobjects") == 0) {
		receive_fsck_objects = git_config_bool(var, value);
		return 0;
	}

82 83 84 85 86
	if (!strcmp(var, "receive.denycurrentbranch")) {
		deny_current_branch = parse_deny_action(var, value);
		return 0;
	}

87 88 89 90 91
	if (strcmp(var, "receive.denydeletecurrent") == 0) {
		deny_delete_current = parse_deny_action(var, value);
		return 0;
	}

92 93 94 95 96
	if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
		prefer_ofs_delta = git_config_bool(var, value);
		return 0;
	}

97 98 99 100 101 102 103 104 105 106
	if (strcmp(var, "receive.updateserverinfo") == 0) {
		auto_update_server_info = git_config_bool(var, value);
		return 0;
	}

	if (strcmp(var, "receive.autogc") == 0) {
		auto_gc = git_config_bool(var, value);
		return 0;
	}

107
	return git_default_config(var, value, cb);
108 109
}

110
static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
111
{
112
	if (sent_capabilities)
113 114
		packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
	else
115 116
		packet_write(1, "%s %s%c%s%s\n",
			     sha1_to_hex(sha1), path, 0,
117
			     " report-status delete-refs side-band-64k",
118 119
			     prefer_ofs_delta ? " ofs-delta" : "");
	sent_capabilities = 1;
120
	return 0;
121 122
}

123
static void write_head_info(void)
124
{
125
	for_each_ref(show_ref, NULL);
126
	if (!sent_capabilities)
127
		show_ref("capabilities^{}", null_sha1, 0, NULL);
128

129 130
}

131 132
struct command {
	struct command *next;
133
	const char *error_string;
134
	unsigned int skip_update;
135 136
	unsigned char old_sha1[20];
	unsigned char new_sha1[20];
137
	char ref_name[FLEX_ARRAY]; /* more */
138 139
};

140 141
static const char pre_receive_hook[] = "hooks/pre-receive";
static const char post_receive_hook[] = "hooks/post-receive";
142

143 144 145 146 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
static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));

static void report_message(const char *prefix, const char *err, va_list params)
{
	int sz = strlen(prefix);
	char msg[4096];

	strncpy(msg, prefix, sz);
	sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
	if (sz > (sizeof(msg) - 1))
		sz = sizeof(msg) - 1;
	msg[sz++] = '\n';

	if (use_sideband)
		send_sideband(1, 2, msg, sz, use_sideband);
	else
		xwrite(2, msg, sz);
}

static void rp_warning(const char *err, ...)
{
	va_list params;
	va_start(params, err);
	report_message("warning: ", err, params);
	va_end(params);
}

static void rp_error(const char *err, ...)
{
	va_list params;
	va_start(params, err);
	report_message("error: ", err, params);
	va_end(params);
}

179 180 181 182 183 184 185 186 187 188 189 190 191
static int copy_to_sideband(int in, int out, void *arg)
{
	char data[128];
	while (1) {
		ssize_t sz = xread(in, data, sizeof(data));
		if (sz <= 0)
			break;
		send_sideband(1, 2, data, sz, use_sideband);
	}
	close(in);
	return 0;
}

192
static int run_receive_hook(struct command *commands, const char *hook_name)
193
{
194
	static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
195
	struct command *cmd;
196
	struct child_process proc;
197
	struct async muxer;
198 199
	const char *argv[2];
	int have_input = 0, code;
200

201
	for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
202
		if (!cmd->error_string)
203
			have_input = 1;
204
	}
205

206
	if (!have_input || access(hook_name, X_OK) < 0)
207
		return 0;
208 209

	argv[0] = hook_name;
210 211 212 213 214 215 216
	argv[1] = NULL;

	memset(&proc, 0, sizeof(proc));
	proc.argv = argv;
	proc.in = -1;
	proc.stdout_to_stderr = 1;

217 218 219 220 221 222 223 224 225 226
	if (use_sideband) {
		memset(&muxer, 0, sizeof(muxer));
		muxer.proc = copy_to_sideband;
		muxer.in = -1;
		code = start_async(&muxer);
		if (code)
			return code;
		proc.err = muxer.in;
	}

227
	code = start_command(&proc);
228 229 230
	if (code) {
		if (use_sideband)
			finish_async(&muxer);
231
		return code;
232 233
	}

234
	for (cmd = commands; cmd; cmd = cmd->next) {
235
		if (!cmd->error_string) {
236 237 238 239 240 241
			size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
				sha1_to_hex(cmd->old_sha1),
				sha1_to_hex(cmd->new_sha1),
				cmd->ref_name);
			if (write_in_full(proc.in, buf, n) != n)
				break;
242 243
		}
	}
244
	close(proc.in);
245 246
	if (use_sideband)
		finish_async(&muxer);
247
	return finish_command(&proc);
248 249
}

250 251 252 253
static int run_update_hook(struct command *cmd)
{
	static const char update_hook[] = "hooks/update";
	const char *argv[5];
254 255
	struct child_process proc;
	int code;
256 257 258 259 260 261 262 263 264 265

	if (access(update_hook, X_OK) < 0)
		return 0;

	argv[0] = update_hook;
	argv[1] = cmd->ref_name;
	argv[2] = sha1_to_hex(cmd->old_sha1);
	argv[3] = sha1_to_hex(cmd->new_sha1);
	argv[4] = NULL;

266 267 268 269 270 271 272 273 274 275 276 277
	memset(&proc, 0, sizeof(proc));
	proc.no_stdin = 1;
	proc.stdout_to_stderr = 1;
	proc.err = use_sideband ? -1 : 0;
	proc.argv = argv;

	code = start_command(&proc);
	if (code)
		return code;
	if (use_sideband)
		copy_to_sideband(proc.err, -1, NULL);
	return finish_command(&proc);
278 279
}

280 281 282 283 284
static int is_ref_checked_out(const char *ref)
{
	if (is_bare_repository())
		return 0;

285
	if (!head_name)
286
		return 0;
287
	return !strcmp(head_name, ref);
288 289
}

290 291 292 293 294
static char *refuse_unconfigured_deny_msg[] = {
	"By default, updating the current branch in a non-bare repository",
	"is denied, because it will make the index and work tree inconsistent",
	"with what you pushed, and will require 'git reset --hard' to match",
	"the work tree to HEAD.",
295 296
	"",
	"You can set 'receive.denyCurrentBranch' configuration variable to",
297 298 299 300
	"'ignore' or 'warn' in the remote repository to allow pushing into",
	"its current branch; however, this is not recommended unless you",
	"arranged to update its work tree to match what you pushed in some",
	"other way.",
301
	"",
302 303
	"To squelch this message and still keep the default behaviour, set",
	"'receive.denyCurrentBranch' configuration variable to 'refuse'."
304 305
};

306
static void refuse_unconfigured_deny(void)
307 308
{
	int i;
309
	for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
310
		rp_error("%s", refuse_unconfigured_deny_msg[i]);
311 312
}

313 314 315
static char *refuse_unconfigured_deny_delete_current_msg[] = {
	"By default, deleting the current branch is denied, because the next",
	"'git clone' won't result in any file checked out, causing confusion.",
316 317
	"",
	"You can set 'receive.denyDeleteCurrent' configuration variable to",
318 319
	"'warn' or 'ignore' in the remote repository to allow deleting the",
	"current branch, with or without a warning message.",
320
	"",
321
	"To squelch this message, you can set it to 'refuse'."
322 323
};

324
static void refuse_unconfigured_deny_delete_current(void)
325 326 327
{
	int i;
	for (i = 0;
328
	     i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
329
	     i++)
330
		rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
331 332
}

333
static const char *update(struct command *cmd)
334
{
335 336 337
	const char *name = cmd->ref_name;
	unsigned char *old_sha1 = cmd->old_sha1;
	unsigned char *new_sha1 = cmd->new_sha1;
338
	struct ref_lock *lock;
339

340 341
	/* only refs/... are allowed */
	if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
342
		rp_error("refusing to create funny ref '%s' remotely", name);
343
		return "funny refname";
344
	}
345

346 347 348
	if (is_ref_checked_out(name)) {
		switch (deny_current_branch) {
		case DENY_IGNORE:
349
			break;
350
		case DENY_WARN:
351
			rp_warning("updating the current branch");
352
			break;
353
		case DENY_REFUSE:
354
		case DENY_UNCONFIGURED:
355
			rp_error("refusing to update checked out branch: %s", name);
356 357
			if (deny_current_branch == DENY_UNCONFIGURED)
				refuse_unconfigured_deny();
358 359
			return "branch is currently checked out";
		}
360 361
	}

362
	if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
363 364 365
		error("unpack should have generated %s, "
		      "but I can't find it!", sha1_to_hex(new_sha1));
		return "bad pack";
366
	}
367 368 369

	if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
		if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
370
			rp_error("denying ref deletion for %s", name);
371 372 373 374 375 376 377 378
			return "deletion prohibited";
		}

		if (!strcmp(name, head_name)) {
			switch (deny_delete_current) {
			case DENY_IGNORE:
				break;
			case DENY_WARN:
379
				rp_warning("deleting the current branch");
380 381
				break;
			case DENY_REFUSE:
382 383 384
			case DENY_UNCONFIGURED:
				if (deny_delete_current == DENY_UNCONFIGURED)
					refuse_unconfigured_deny_delete_current();
385
				rp_error("refusing to delete the current branch: %s", name);
386 387 388
				return "deletion of the current branch prohibited";
			}
		}
J
Jan Krüger 已提交
389
	}
390

391
	if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
J
Junio C Hamano 已提交
392
	    !is_null_sha1(old_sha1) &&
393
	    !prefixcmp(name, "refs/heads/")) {
394
		struct object *old_object, *new_object;
395
		struct commit *old_commit, *new_commit;
396
		struct commit_list *bases, *ent;
397

398 399 400 401 402 403 404 405 406 407 408
		old_object = parse_object(old_sha1);
		new_object = parse_object(new_sha1);

		if (!old_object || !new_object ||
		    old_object->type != OBJ_COMMIT ||
		    new_object->type != OBJ_COMMIT) {
			error("bad sha1 objects for %s", name);
			return "bad ref";
		}
		old_commit = (struct commit *)old_object;
		new_commit = (struct commit *)new_object;
409 410 411
		bases = get_merge_bases(old_commit, new_commit, 1);
		for (ent = bases; ent; ent = ent->next)
			if (!hashcmp(old_sha1, ent->item->object.sha1))
412
				break;
413
		free_commit_list(bases);
414
		if (!ent) {
415 416
			rp_error("denying non-fast-forward %s"
				 " (you should pull first)", name);
417
			return "non-fast-forward";
418
		}
419
	}
420
	if (run_update_hook(cmd)) {
421
		rp_error("hook declined to update %s", name);
422
		return "hook declined";
423
	}
424

425
	if (is_null_sha1(new_sha1)) {
426
		if (!parse_object(old_sha1)) {
427
			rp_warning("Allowing deletion of corrupt ref.");
428 429
			old_sha1 = NULL;
		}
M
Miklos Vajna 已提交
430
		if (delete_ref(name, old_sha1, 0)) {
431
			rp_error("failed to delete %s", name);
432
			return "failed to delete";
433
		}
434
		return NULL; /* good */
435 436
	}
	else {
437
		lock = lock_any_ref_for_update(name, old_sha1, 0);
438
		if (!lock) {
439
			rp_error("failed to lock %s", name);
440
			return "failed to lock";
441
		}
442
		if (write_ref_sha1(lock, new_sha1, "push")) {
443
			return "failed to write"; /* error() already called */
444
		}
445
		return NULL; /* good */
J
Junio C Hamano 已提交
446
	}
447 448
}

J
Junio C Hamano 已提交
449 450
static char update_post_hook[] = "hooks/post-update";

451
static void run_update_post_hook(struct command *commands)
J
Junio C Hamano 已提交
452
{
453
	struct command *cmd;
454
	int argc;
J
Junio C Hamano 已提交
455
	const char **argv;
456
	struct child_process proc;
J
Junio C Hamano 已提交
457

458 459
	for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {
		if (cmd->error_string)
J
Junio C Hamano 已提交
460 461 462
			continue;
		argc++;
	}
463 464 465
	if (!argc || access(update_post_hook, X_OK) < 0)
		return;
	argv = xmalloc(sizeof(*argv) * (2 + argc));
J
Junio C Hamano 已提交
466 467
	argv[0] = update_post_hook;

468
	for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
J
Junio C Hamano 已提交
469
		char *p;
470
		if (cmd->error_string)
J
Junio C Hamano 已提交
471
			continue;
472 473
		p = xmalloc(strlen(cmd->ref_name) + 1);
		strcpy(p, cmd->ref_name);
J
Junio C Hamano 已提交
474
		argv[argc] = p;
J
Junio C Hamano 已提交
475 476 477
		argc++;
	}
	argv[argc] = NULL;
478 479 480 481 482 483 484 485 486 487 488 489

	memset(&proc, 0, sizeof(proc));
	proc.no_stdin = 1;
	proc.stdout_to_stderr = 1;
	proc.err = use_sideband ? -1 : 0;
	proc.argv = argv;

	if (!start_command(&proc)) {
		if (use_sideband)
			copy_to_sideband(proc.err, -1, NULL);
		finish_command(&proc);
	}
J
Junio C Hamano 已提交
490
}
491

492 493 494 495 496 497 498 499 500 501 502 503 504
static void check_aliased_update(struct command *cmd, struct string_list *list)
{
	struct string_list_item *item;
	struct command *dst_cmd;
	unsigned char sha1[20];
	char cmd_oldh[41], cmd_newh[41], dst_oldh[41], dst_newh[41];
	int flag;

	const char *dst_name = resolve_ref(cmd->ref_name, sha1, 0, &flag);

	if (!(flag & REF_ISSYMREF))
		return;

505
	if ((item = string_list_lookup(list, dst_name)) == NULL)
506 507 508 509 510 511 512 513 514 515 516 517 518
		return;

	cmd->skip_update = 1;

	dst_cmd = (struct command *) item->util;

	if (!hashcmp(cmd->old_sha1, dst_cmd->old_sha1) &&
	    !hashcmp(cmd->new_sha1, dst_cmd->new_sha1))
		return;

	dst_cmd->skip_update = 1;

	strcpy(cmd_oldh, find_unique_abbrev(cmd->old_sha1, DEFAULT_ABBREV));
519
	strcpy(cmd_newh, find_unique_abbrev(cmd->new_sha1, DEFAULT_ABBREV));
520
	strcpy(dst_oldh, find_unique_abbrev(dst_cmd->old_sha1, DEFAULT_ABBREV));
521
	strcpy(dst_newh, find_unique_abbrev(dst_cmd->new_sha1, DEFAULT_ABBREV));
522 523 524 525 526 527 528 529 530 531 532 533
	rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
		 " its target '%s' (%s..%s)",
		 cmd->ref_name, cmd_oldh, cmd_newh,
		 dst_cmd->ref_name, dst_oldh, dst_newh);

	cmd->error_string = dst_cmd->error_string =
		"inconsistent aliased update";
}

static void check_aliased_updates(struct command *commands)
{
	struct command *cmd;
534
	struct string_list ref_list = STRING_LIST_INIT_NODUP;
535 536 537

	for (cmd = commands; cmd; cmd = cmd->next) {
		struct string_list_item *item =
538
			string_list_append(&ref_list, cmd->ref_name);
539 540 541 542 543 544 545 546 547 548
		item->util = (void *)cmd;
	}
	sort_string_list(&ref_list);

	for (cmd = commands; cmd; cmd = cmd->next)
		check_aliased_update(cmd, &ref_list);

	string_list_clear(&ref_list, 0);
}

549
static void execute_commands(struct command *commands, const char *unpacker_error)
550
{
551
	struct command *cmd;
552
	unsigned char sha1[20];
553 554

	if (unpacker_error) {
555
		for (cmd = commands; cmd; cmd = cmd->next)
556 557 558 559
			cmd->error_string = "n/a (unpacker error)";
		return;
	}

560 561
	if (run_receive_hook(commands, pre_receive_hook)) {
		for (cmd = commands; cmd; cmd = cmd->next)
562 563 564 565
			cmd->error_string = "pre-receive hook declined";
		return;
	}

566 567
	check_aliased_updates(commands);

568 569
	head_name = resolve_ref("HEAD", sha1, 0, NULL);

570
	for (cmd = commands; cmd; cmd = cmd->next)
571 572
		if (!cmd->skip_update)
			cmd->error_string = update(cmd);
573 574
}

575
static struct command *read_head_info(void)
576
{
577
	struct command *commands = NULL;
578
	struct command **p = &commands;
579 580
	for (;;) {
		static char line[1000];
581 582
		unsigned char old_sha1[20], new_sha1[20];
		struct command *cmd;
583 584
		char *refname;
		int len, reflen;
585 586

		len = packet_read_line(0, line, sizeof(line));
587 588
		if (!len)
			break;
589 590 591 592 593 594 595
		if (line[len-1] == '\n')
			line[--len] = 0;
		if (len < 83 ||
		    line[40] != ' ' ||
		    line[81] != ' ' ||
		    get_sha1_hex(line, old_sha1) ||
		    get_sha1_hex(line + 41, new_sha1))
596 597 598 599 600 601 602 603
			die("protocol error: expected old/new/ref, got '%s'",
			    line);

		refname = line + 82;
		reflen = strlen(refname);
		if (reflen + 82 < len) {
			if (strstr(refname + reflen + 1, "report-status"))
				report_status = 1;
604 605
			if (strstr(refname + reflen + 1, "side-band-64k"))
				use_sideband = LARGE_PACKET_MAX;
606
		}
607
		cmd = xcalloc(1, sizeof(struct command) + len - 80);
608 609
		hashcpy(cmd->old_sha1, old_sha1);
		hashcpy(cmd->new_sha1, new_sha1);
610 611 612
		memcpy(cmd->ref_name, line + 82, len - 81);
		*p = cmd;
		p = &cmd->next;
613
	}
614
	return commands;
615 616
}

617 618
static const char *parse_pack_header(struct pack_header *hdr)
{
619 620 621 622 623
	switch (read_pack_header(0, hdr)) {
	case PH_ERROR_EOF:
		return "eof before pack header was fully read";

	case PH_ERROR_PACK_SIGNATURE:
624
		return "protocol error (pack signature mismatch detected)";
625 626

	case PH_ERROR_PROTOCOL:
627
		return "protocol error (pack version unsupported)";
628 629 630 631 632 633 634

	default:
		return "unknown error in parse_pack_header";

	case 0:
		return NULL;
	}
635 636
}

637 638
static const char *pack_lockfile;

639
static const char *unpack(void)
640
{
641 642 643 644 645 646 647
	struct pack_header hdr;
	const char *hdr_err;
	char hdr_arg[38];

	hdr_err = parse_pack_header(&hdr);
	if (hdr_err)
		return hdr_err;
648 649
	snprintf(hdr_arg, sizeof(hdr_arg),
			"--pack_header=%"PRIu32",%"PRIu32,
650 651 652
			ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));

	if (ntohl(hdr.hdr_entries) < unpack_limit) {
653 654 655 656 657 658 659
		int code, i = 0;
		const char *unpacker[4];
		unpacker[i++] = "unpack-objects";
		if (receive_fsck_objects)
			unpacker[i++] = "--strict";
		unpacker[i++] = hdr_arg;
		unpacker[i++] = NULL;
660
		code = run_command_v_opt(unpacker, RUN_GIT_CMD);
661
		if (!code)
662
			return NULL;
663
		return "unpack-objects abnormal exit";
664
	} else {
665 666
		const char *keeper[7];
		int s, status, i = 0;
667
		char keep_arg[256];
668
		struct child_process ip;
669

670
		s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
671 672 673
		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
			strcpy(keep_arg + s, "localhost");

674 675 676 677 678 679 680 681
		keeper[i++] = "index-pack";
		keeper[i++] = "--stdin";
		if (receive_fsck_objects)
			keeper[i++] = "--strict";
		keeper[i++] = "--fix-thin";
		keeper[i++] = hdr_arg;
		keeper[i++] = keep_arg;
		keeper[i++] = NULL;
682 683 684 685
		memset(&ip, 0, sizeof(ip));
		ip.argv = keeper;
		ip.out = -1;
		ip.git_cmd = 1;
686 687
		status = start_command(&ip);
		if (status) {
688
			return "index-pack fork failed";
689
		}
690
		pack_lockfile = index_pack_lockfile(ip.out);
691
		close(ip.out);
692 693
		status = finish_command(&ip);
		if (!status) {
694 695 696 697
			reprepare_packed_git();
			return NULL;
		}
		return "index-pack abnormal exit";
698 699 700
	}
}

701
static void report(struct command *commands, const char *unpack_status)
702 703
{
	struct command *cmd;
704 705 706 707
	struct strbuf buf = STRBUF_INIT;

	packet_buf_write(&buf, "unpack %s\n",
			 unpack_status ? unpack_status : "ok");
708 709
	for (cmd = commands; cmd; cmd = cmd->next) {
		if (!cmd->error_string)
710 711
			packet_buf_write(&buf, "ok %s\n",
					 cmd->ref_name);
712
		else
713 714
			packet_buf_write(&buf, "ng %s %s\n",
					 cmd->ref_name, cmd->error_string);
715
	}
716 717 718 719 720 721 722
	packet_buf_flush(&buf);

	if (use_sideband)
		send_sideband(1, 1, buf.buf, buf.len, use_sideband);
	else
		safe_write(1, buf.buf, buf.len);
	strbuf_release(&buf);
723 724
}

725
static int delete_only(struct command *commands)
726
{
727 728
	struct command *cmd;
	for (cmd = commands; cmd; cmd = cmd->next) {
729 730 731 732 733 734
		if (!is_null_sha1(cmd->new_sha1))
			return 0;
	}
	return 1;
}

735
static void add_one_alternate_sha1(const unsigned char sha1[20], void *unused)
736
{
737 738 739 740 741 742 743
	add_extra_ref(".have", sha1, 0);
}

static void collect_one_alternate_ref(const struct ref *ref, void *data)
{
	struct sha1_array *sa = data;
	sha1_array_append(sa, ref->old_sha1);
744 745 746 747
}

static void add_alternate_refs(void)
{
748 749 750 751
	struct sha1_array sa = SHA1_ARRAY_INIT;
	for_each_alternate_ref(collect_one_alternate_ref, &sa);
	sha1_array_for_each_unique(&sa, add_one_alternate_sha1, NULL);
	sha1_array_clear(&sa);
752 753
}

J
Junio C Hamano 已提交
754
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
755
{
756 757
	int advertise_refs = 0;
	int stateless_rpc = 0;
758
	int i;
759
	char *dir = NULL;
760
	struct command *commands;
761

J
Jeff King 已提交
762 763
	packet_trace_identity("receive-pack");

764 765
	argv++;
	for (i = 1; i < argc; i++) {
J
Junio C Hamano 已提交
766
		const char *arg = *argv++;
767 768

		if (*arg == '-') {
769 770 771 772 773 774 775 776 777
			if (!strcmp(arg, "--advertise-refs")) {
				advertise_refs = 1;
				continue;
			}
			if (!strcmp(arg, "--stateless-rpc")) {
				stateless_rpc = 1;
				continue;
			}

778 779
			usage(receive_pack_usage);
		}
780 781
		if (dir)
			usage(receive_pack_usage);
J
Junio C Hamano 已提交
782
		dir = xstrdup(arg);
783 784 785 786
	}
	if (!dir)
		usage(receive_pack_usage);

787
	setup_path();
788

789
	if (!enter_repo(dir, 0))
790
		die("'%s' does not appear to be a git repository", dir);
791

792 793 794
	if (is_repository_shallow())
		die("attempt to push into a shallow repository");

795
	git_config(receive_pack_config, NULL);
796

797 798 799 800 801
	if (0 <= transfer_unpack_limit)
		unpack_limit = transfer_unpack_limit;
	else if (0 <= receive_unpack_limit)
		unpack_limit = receive_unpack_limit;

802 803 804 805
	if (advertise_refs || !stateless_rpc) {
		add_alternate_refs();
		write_head_info();
		clear_extra_refs();
806

807 808 809 810 811
		/* EOF */
		packet_flush(1);
	}
	if (advertise_refs)
		return 0;
812

813
	if ((commands = read_head_info()) != NULL) {
814 815 816 817
		const char *unpack_status = NULL;

		if (!delete_only(commands))
			unpack_status = unpack();
818
		execute_commands(commands, unpack_status);
819
		if (pack_lockfile)
820
			unlink_or_warn(pack_lockfile);
821
		if (report_status)
822 823
			report(commands, unpack_status);
		run_receive_hook(commands, post_receive_hook);
824
		run_update_post_hook(commands);
825 826 827 828 829 830 831 832
		if (auto_gc) {
			const char *argv_gc_auto[] = {
				"gc", "--auto", "--quiet", NULL,
			};
			run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
		}
		if (auto_update_server_info)
			update_server_info(0);
833
	}
834 835
	if (use_sideband)
		packet_flush(1);
836 837
	return 0;
}