commit.c 46.0 KB
Newer Older
K
Kristian Høgsberg 已提交
1 2 3 4 5 6 7 8 9
/*
 * Builtin "git commit"
 *
 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
 */

#include "cache.h"
#include "cache-tree.h"
10
#include "color.h"
11
#include "dir.h"
K
Kristian Høgsberg 已提交
12 13 14 15 16 17 18 19 20 21 22 23
#include "builtin.h"
#include "diff.h"
#include "diffcore.h"
#include "commit.h"
#include "revision.h"
#include "wt-status.h"
#include "run-command.h"
#include "refs.h"
#include "log-tree.h"
#include "strbuf.h"
#include "utf8.h"
#include "parse-options.h"
24
#include "string-list.h"
25
#include "rerere.h"
26
#include "unpack-trees.h"
27
#include "quote.h"
28
#include "submodule.h"
J
Junio C Hamano 已提交
29
#include "gpg-interface.h"
N
Nguyễn Thái Ngọc Duy 已提交
30
#include "column.h"
K
Kristian Høgsberg 已提交
31 32

static const char * const builtin_commit_usage[] = {
33
	N_("git commit [options] [--] <filepattern>..."),
K
Kristian Høgsberg 已提交
34 35 36
	NULL
};

37
static const char * const builtin_status_usage[] = {
38
	N_("git status [options] [--] <filepattern>..."),
39 40 41
	NULL
};

42
static const char implicit_ident_advice[] =
43
N_("Your name and email address were configured automatically based\n"
44 45 46
"on your username and hostname. Please check that they are accurate.\n"
"You can suppress this message by setting them explicitly:\n"
"\n"
47
"    git config --global user.name \"Your Name\"\n"
48 49
"    git config --global user.email you@example.com\n"
"\n"
50
"After doing this, you may fix the identity used for this commit with:\n"
51
"\n"
52
"    git commit --amend --reset-author\n");
53

J
Jeff King 已提交
54
static const char empty_amend_advice[] =
55
N_("You asked to amend the most recent commit, but doing so would make\n"
J
Jeff King 已提交
56
"it empty. You can repeat your command with --allow-empty, or you can\n"
57
"remove the commit entirely with \"git reset HEAD^\".\n");
J
Jeff King 已提交
58

59
static const char empty_cherry_pick_advice[] =
J
Junio C Hamano 已提交
60
N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
61 62 63 64
"If you wish to commit it anyway, use:\n"
"\n"
"    git commit --allow-empty\n"
"\n"
J
Junio C Hamano 已提交
65
"Otherwise, please use 'git reset'\n");
66 67

static const char *use_message_buffer;
K
Kristian Høgsberg 已提交
68
static const char commit_editmsg[] = "COMMIT_EDITMSG";
69 70 71 72 73
static struct lock_file index_lock; /* real index */
static struct lock_file false_lock; /* used only for partial commits */
static enum {
	COMMIT_AS_IS = 1,
	COMMIT_NORMAL,
74
	COMMIT_PARTIAL
75
} commit_style;
K
Kristian Høgsberg 已提交
76

77
static const char *logfile, *force_author;
78
static const char *template_file;
79 80 81 82 83
/*
 * The _message variables are commit names from which to take
 * the commit message and/or authorship.
 */
static const char *author_message, *author_message_buffer;
K
Kristian Høgsberg 已提交
84
static char *edit_message, *use_message;
85
static char *fixup_message, *squash_message;
J
Junio C Hamano 已提交
86 87
static int all, also, interactive, patch_interactive, only, amend, signoff;
static int edit_flag = -1; /* unspecified */
88
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
89
static int no_post_rewrite, allow_empty_message;
90
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
J
Junio C Hamano 已提交
91 92
static char *sign_commit;

93 94 95 96 97 98 99 100 101 102
/*
 * The default commit message cleanup mode will remove the lines
 * beginning with # (shell comments) and leading and trailing
 * whitespaces (empty lines or containing only whitespaces)
 * if editor is used, and only the whitespaces if the message
 * is specified explicitly.
 */
static enum {
	CLEANUP_SPACE,
	CLEANUP_NONE,
103
	CLEANUP_ALL
104 105
} cleanup_mode;
static char *cleanup_arg;
K
Kristian Høgsberg 已提交
106

107
static enum commit_whence whence;
108
static int use_editor = 1, include_status = 1;
109
static int show_ignored_in_status;
110
static const char *only_include_assumed;
111
static struct strbuf message = STRBUF_INIT;
112

113 114 115
static enum {
	STATUS_FORMAT_LONG,
	STATUS_FORMAT_SHORT,
116
	STATUS_FORMAT_PORCELAIN
117 118
} status_format = STATUS_FORMAT_LONG;

119 120 121 122 123 124 125
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
	struct strbuf *buf = opt->value;
	if (unset)
		strbuf_setlen(buf, 0);
	else {
		strbuf_addstr(buf, arg);
126
		strbuf_addstr(buf, "\n\n");
127 128 129
	}
	return 0;
}
K
Kristian Høgsberg 已提交
130

131 132 133 134 135 136 137 138 139 140 141 142
static void determine_whence(struct wt_status *s)
{
	if (file_exists(git_path("MERGE_HEAD")))
		whence = FROM_MERGE;
	else if (file_exists(git_path("CHERRY_PICK_HEAD")))
		whence = FROM_CHERRY_PICK;
	else
		whence = FROM_COMMIT;
	if (s)
		s->whence = whence;
}

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
static void rollback_index_files(void)
{
	switch (commit_style) {
	case COMMIT_AS_IS:
		break; /* nothing to do */
	case COMMIT_NORMAL:
		rollback_lock_file(&index_lock);
		break;
	case COMMIT_PARTIAL:
		rollback_lock_file(&index_lock);
		rollback_lock_file(&false_lock);
		break;
	}
}

158
static int commit_index_files(void)
159
{
160 161
	int err = 0;

162 163 164 165
	switch (commit_style) {
	case COMMIT_AS_IS:
		break; /* nothing to do */
	case COMMIT_NORMAL:
166
		err = commit_lock_file(&index_lock);
167 168
		break;
	case COMMIT_PARTIAL:
169
		err = commit_lock_file(&index_lock);
170 171 172
		rollback_lock_file(&false_lock);
		break;
	}
173 174

	return err;
175 176 177 178 179 180
}

/*
 * Take a union of paths in the index and the named tree (typically, "HEAD"),
 * and return the paths that match the given pattern in list.
 */
181
static int list_paths(struct string_list *list, const char *with_tree,
182 183 184 185 186
		      const char *prefix, const char **pattern)
{
	int i;
	char *m;

187 188 189
	if (!pattern)
		return 0;

190 191 192 193
	for (i = 0; pattern[i]; i++)
		;
	m = xcalloc(1, i);

194
	if (with_tree) {
195
		char *max_prefix = common_prefix(pattern);
196 197
		overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
		free(max_prefix);
198
	}
199 200 201

	for (i = 0; i < active_nr; i++) {
		struct cache_entry *ce = active_cache[i];
202 203
		struct string_list_item *item;

204
		if (ce->ce_flags & CE_UPDATE)
205
			continue;
206
		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
207
			continue;
208
		item = string_list_insert(list, ce->name);
209 210
		if (ce_skip_worktree(ce))
			item->util = item; /* better a valid pointer than a fake one */
211 212
	}

213
	return report_path_error(m, pattern, prefix);
214 215
}

216
static void add_remove_files(struct string_list *list)
217 218 219
{
	int i;
	for (i = 0; i < list->nr; i++) {
220
		struct stat st;
221
		struct string_list_item *p = &(list->items[i]);
222

223 224
		/* p->util is skip-worktree */
		if (p->util)
225
			continue;
226

227 228
		if (!lstat(p->string, &st)) {
			if (add_to_cache(p->string, &st, 0))
229
				die(_("updating files failed"));
230
		} else
231
			remove_file_from_cache(p->string);
232 233 234
	}
}

235
static void create_base_index(const struct commit *current_head)
236 237 238 239 240
{
	struct tree *tree;
	struct unpack_trees_options opts;
	struct tree_desc t;

241
	if (!current_head) {
242 243 244 245 246 247 248 249
		discard_cache();
		return;
	}

	memset(&opts, 0, sizeof(opts));
	opts.head_idx = 1;
	opts.index_only = 1;
	opts.merge = 1;
250 251
	opts.src_index = &the_index;
	opts.dst_index = &the_index;
252 253

	opts.fn = oneway_merge;
254
	tree = parse_tree_indirect(current_head->object.sha1);
255
	if (!tree)
256
		die(_("failed to unpack HEAD tree object"));
257 258
	parse_tree(tree);
	init_tree_desc(&t, tree->buffer, tree->size);
259 260
	if (unpack_trees(1, &t, &opts))
		exit(128); /* We've already reported the error, finish dying */
261 262
}

263 264 265 266 267 268 269 270 271 272
static void refresh_cache_or_die(int refresh_flags)
{
	/*
	 * refresh_flags contains REFRESH_QUIET, so the only errors
	 * are for unmerged entries.
	 */
	if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
		die_resolve_conflict("commit");
}

273 274
static char *prepare_index(int argc, const char **argv, const char *prefix,
			   const struct commit *current_head, int is_status)
K
Kristian Høgsberg 已提交
275 276
{
	int fd;
277
	struct string_list partial;
278
	const char **pathspec = NULL;
279
	char *old_index_env = NULL;
280
	int refresh_flags = REFRESH_QUIET;
K
Kristian Høgsberg 已提交
281

282 283
	if (is_status)
		refresh_flags |= REFRESH_UNMERGED;
K
Kristian Høgsberg 已提交
284

285 286
	if (*argv)
		pathspec = get_pathspec(prefix, argv);
287

L
Linus Torvalds 已提交
288
	if (read_cache_preload(pathspec) < 0)
289
		die(_("index file corrupt"));
L
Linus Torvalds 已提交
290

291 292 293 294 295 296 297 298 299 300 301 302
	if (interactive) {
		fd = hold_locked_index(&index_lock, 1);

		refresh_cache_or_die(refresh_flags);

		if (write_cache(fd, active_cache, active_nr) ||
		    close_lock_file(&index_lock))
			die(_("unable to create temporary index"));

		old_index_env = getenv(INDEX_ENVIRONMENT);
		setenv(INDEX_ENVIRONMENT, index_lock.filename, 1);

303
		if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
304 305 306 307 308 309 310 311 312 313 314 315 316 317
			die(_("interactive add failed"));

		if (old_index_env && *old_index_env)
			setenv(INDEX_ENVIRONMENT, old_index_env, 1);
		else
			unsetenv(INDEX_ENVIRONMENT);

		discard_cache();
		read_cache_from(index_lock.filename);

		commit_style = COMMIT_NORMAL;
		return index_lock.filename;
	}

318 319 320 321 322 323 324 325 326 327 328 329 330
	/*
	 * Non partial, non as-is commit.
	 *
	 * (1) get the real index;
	 * (2) update the_index as necessary;
	 * (3) write the_index out to the real index (still locked);
	 * (4) return the name of the locked index file.
	 *
	 * The caller should run hooks on the locked real index, and
	 * (A) if all goes well, commit the real index;
	 * (B) on failure, rollback the real index.
	 */
	if (all || (also && pathspec && *pathspec)) {
331
		fd = hold_locked_index(&index_lock, 1);
332
		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
333
		refresh_cache_or_die(refresh_flags);
334
		update_main_cache_tree(WRITE_TREE_SILENT);
B
Brandon Casey 已提交
335 336
		if (write_cache(fd, active_cache, active_nr) ||
		    close_lock_file(&index_lock))
337
			die(_("unable to write new_index file"));
338 339
		commit_style = COMMIT_NORMAL;
		return index_lock.filename;
K
Kristian Høgsberg 已提交
340 341
	}

342 343 344 345 346
	/*
	 * As-is commit.
	 *
	 * (1) return the name of the real index file.
	 *
347 348
	 * The caller should run hooks on the real index,
	 * and create commit from the_index.
349 350
	 * We still need to refresh the index here.
	 */
351
	if (!only && (!pathspec || !*pathspec)) {
352
		fd = hold_locked_index(&index_lock, 1);
353
		refresh_cache_or_die(refresh_flags);
354
		if (active_cache_changed) {
355
			update_main_cache_tree(WRITE_TREE_SILENT);
356 357
			if (write_cache(fd, active_cache, active_nr) ||
			    commit_locked_index(&index_lock))
358
				die(_("unable to write new_index file"));
359 360 361
		} else {
			rollback_lock_file(&index_lock);
		}
362
		commit_style = COMMIT_AS_IS;
K
Kristian Høgsberg 已提交
363 364 365
		return get_index_file();
	}

366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
	/*
	 * A partial commit.
	 *
	 * (0) find the set of affected paths;
	 * (1) get lock on the real index file;
	 * (2) update the_index with the given paths;
	 * (3) write the_index out to the real index (still locked);
	 * (4) get lock on the false index file;
	 * (5) reset the_index from HEAD;
	 * (6) update the_index the same way as (2);
	 * (7) write the_index out to the false index file;
	 * (8) return the name of the false index file (still locked);
	 *
	 * The caller should run hooks on the locked false index, and
	 * create commit from it.  Then
	 * (A) if all goes well, commit the real index;
	 * (B) on failure, rollback the real index;
	 * In either case, rollback the false index.
	 */
	commit_style = COMMIT_PARTIAL;

387 388 389 390 391 392
	if (whence != FROM_COMMIT) {
		if (whence == FROM_MERGE)
			die(_("cannot do a partial commit during a merge."));
		else if (whence == FROM_CHERRY_PICK)
			die(_("cannot do a partial commit during a cherry-pick."));
	}
393 394

	memset(&partial, 0, sizeof(partial));
395
	partial.strdup_strings = 1;
396
	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
397 398 399 400
		exit(1);

	discard_cache();
	if (read_cache() < 0)
401
		die(_("cannot read the index"));
402 403 404

	fd = hold_locked_index(&index_lock, 1);
	add_remove_files(&partial);
405
	refresh_cache(REFRESH_QUIET);
B
Brandon Casey 已提交
406 407
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&index_lock))
408
		die(_("unable to write new_index file"));
K
Kristian Høgsberg 已提交
409

410
	fd = hold_lock_file_for_update(&false_lock,
J
Junio C Hamano 已提交
411 412
				       git_path("next-index-%"PRIuMAX,
						(uintmax_t) getpid()),
413
				       LOCK_DIE_ON_ERROR);
414

415
	create_base_index(current_head);
416
	add_remove_files(&partial);
417
	refresh_cache(REFRESH_QUIET);
K
Kristian Høgsberg 已提交
418

B
Brandon Casey 已提交
419 420
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&false_lock))
421
		die(_("unable to write temporary index file"));
422 423 424 425

	discard_cache();
	read_cache_from(false_lock.filename);

426
	return false_lock.filename;
K
Kristian Høgsberg 已提交
427 428
}

429 430
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
		      struct wt_status *s)
K
Kristian Høgsberg 已提交
431
{
432 433
	unsigned char sha1[20];

434 435
	if (s->relative_paths)
		s->prefix = prefix;
K
Kristian Høgsberg 已提交
436 437

	if (amend) {
438 439
		s->amend = 1;
		s->reference = "HEAD^1";
K
Kristian Høgsberg 已提交
440
	}
441 442 443 444
	s->verbose = verbose;
	s->index_file = index_file;
	s->fp = fp;
	s->nowarn = nowarn;
445
	s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
K
Kristian Høgsberg 已提交
446

447
	wt_status_collect(s);
448 449 450

	switch (status_format) {
	case STATUS_FORMAT_SHORT:
451
		wt_shortstatus_print(s);
452 453
		break;
	case STATUS_FORMAT_PORCELAIN:
454
		wt_porcelain_print(s);
455 456 457 458 459
		break;
	case STATUS_FORMAT_LONG:
		wt_status_print(s);
		break;
	}
K
Kristian Høgsberg 已提交
460

461
	return s->commitable;
K
Kristian Høgsberg 已提交
462 463
}

464
static int is_a_merge(const struct commit *current_head)
465
{
466
	return !!(current_head->parents && current_head->parents->next);
467 468
}

K
Kristian Høgsberg 已提交
469 470
static const char sign_off_header[] = "Signed-off-by: ";

471 472 473 474 475 476 477 478 479 480
static void export_one(const char *var, const char *s, const char *e, int hack)
{
	struct strbuf buf = STRBUF_INIT;
	if (hack)
		strbuf_addch(&buf, hack);
	strbuf_addf(&buf, "%.*s", (int)(e - s), s);
	setenv(var, buf.buf, 1);
	strbuf_release(&buf);
}

481 482 483 484 485 486 487 488 489 490 491 492 493 494
static int sane_ident_split(struct ident_split *person)
{
	if (!person->name_begin || !person->name_end ||
	    person->name_begin == person->name_end)
		return 0; /* no human readable name */
	if (!person->mail_begin || !person->mail_end ||
	    person->mail_begin == person->mail_end)
		return 0; /* no usable mail */
	if (!person->date_begin || !person->date_end ||
	    !person->tz_begin || !person->tz_end)
		return 0;
	return 1;
}

495
static void determine_author_info(struct strbuf *author_ident)
496 497
{
	char *name, *email, *date;
498
	struct ident_split author;
499 500 501 502 503

	name = getenv("GIT_AUTHOR_NAME");
	email = getenv("GIT_AUTHOR_EMAIL");
	date = getenv("GIT_AUTHOR_DATE");

504
	if (author_message) {
505
		const char *a, *lb, *rb, *eol;
506
		size_t len;
507

508
		a = strstr(author_message_buffer, "\nauthor ");
509
		if (!a)
J
Junio C Hamano 已提交
510
			die(_("invalid commit: %s"), author_message);
511

512 513 514 515
		lb = strchrnul(a + strlen("\nauthor "), '<');
		rb = strchrnul(lb, '>');
		eol = strchrnul(rb, '\n');
		if (!*lb || !*rb || !*eol)
J
Junio C Hamano 已提交
516
			die(_("invalid commit: %s"), author_message);
517

518 519 520 521 522 523 524 525 526
		if (lb == a + strlen("\nauthor "))
			/* \nauthor <foo@example.com> */
			name = xcalloc(1, 1);
		else
			name = xmemdupz(a + strlen("\nauthor "),
					(lb - strlen(" ") -
					 (a + strlen("\nauthor "))));
		email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
		date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
527 528 529 530 531
		len = eol - (rb + strlen("> "));
		date = xmalloc(len + 2);
		*date = '@';
		memcpy(date + 1, rb + strlen("> "), len);
		date[len + 1] = '\0';
532 533 534 535 536 537 538
	}

	if (force_author) {
		const char *lb = strstr(force_author, " <");
		const char *rb = strchr(force_author, '>');

		if (!lb || !rb)
539
			die(_("malformed --author parameter"));
540 541 542 543
		name = xstrndup(force_author, lb - force_author);
		email = xstrndup(lb + 2, rb - (lb + 2));
	}

M
Miklos Vajna 已提交
544 545
	if (force_date)
		date = force_date;
546
	strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));
547 548
	if (!split_ident_line(&author, author_ident->buf, author_ident->len) &&
	    sane_ident_split(&author)) {
549 550 551 552
		export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0);
		export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0);
		export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@');
	}
553 554
}

555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
static int ends_rfc2822_footer(struct strbuf *sb)
{
	int ch;
	int hit = 0;
	int i, j, k;
	int len = sb->len;
	int first = 1;
	const char *buf = sb->buf;

	for (i = len - 1; i > 0; i--) {
		if (hit && buf[i] == '\n')
			break;
		hit = (buf[i] == '\n');
	}

	while (i < len - 1 && buf[i] == '\n')
		i++;

	for (; i < len; i = k) {
		for (k = i; k < len && buf[k] != '\n'; k++)
			; /* do nothing */
		k++;

		if ((buf[k] == ' ' || buf[k] == '\t') && !first)
			continue;

		first = 0;

		for (j = 0; i + j < len; j++) {
			ch = buf[i + j];
			if (ch == ':')
				break;
			if (isalnum(ch) ||
			    (ch == '-'))
				continue;
			return 0;
		}
	}
	return 1;
}

596 597 598 599
static char *cut_ident_timestamp_part(char *string)
{
	char *ket = strrchr(string, '>');
	if (!ket || ket[1] != ' ')
600
		die(_("Malformed ident string: '%s'"), string);
601 602 603 604
	*++ket = '\0';
	return ket;
}

605
static int prepare_to_commit(const char *index_file, const char *prefix,
606
			     struct commit *current_head,
607 608
			     struct wt_status *s,
			     struct strbuf *author_ident)
K
Kristian Høgsberg 已提交
609 610
{
	struct stat statbuf;
611
	struct strbuf committer_ident = STRBUF_INIT;
612
	int commitable, saved_color_setting;
613
	struct strbuf sb = STRBUF_INIT;
K
Kristian Høgsberg 已提交
614
	char *buffer;
615 616
	const char *hook_arg1 = NULL;
	const char *hook_arg2 = NULL;
617
	int ident_shown = 0;
618
	int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
K
Kristian Høgsberg 已提交
619

620 621 622
	/* This checks and barfs if author is badly specified */
	determine_author_info(author_ident);

623 624
	if (!no_verify && run_hook(index_file, "pre-commit", NULL))
		return 0;
K
Kristian Høgsberg 已提交
625

626 627 628 629 630 631 632 633 634 635 636 637
	if (squash_message) {
		/*
		 * Insert the proper subject line before other commit
		 * message options add their content.
		 */
		if (use_message && !strcmp(use_message, squash_message))
			strbuf_addstr(&sb, "squash! ");
		else {
			struct pretty_print_context ctx = {0};
			struct commit *c;
			c = lookup_commit_reference_by_name(squash_message);
			if (!c)
638
				die(_("could not lookup commit %s"), squash_message);
639 640 641 642 643 644
			ctx.output_encoding = get_commit_output_encoding();
			format_commit_message(c, "squash! %s\n\n", &sb,
					      &ctx);
		}
	}

645 646
	if (message.len) {
		strbuf_addbuf(&sb, &message);
647
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
648 649
	} else if (logfile && !strcmp(logfile, "-")) {
		if (isatty(0))
650
			fprintf(stderr, _("(reading log message from standard input)\n"));
K
Kristian Høgsberg 已提交
651
		if (strbuf_read(&sb, 0, 0) < 0)
652
			die_errno(_("could not read log from standard input"));
653
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
654 655
	} else if (logfile) {
		if (strbuf_read_file(&sb, logfile, 0) < 0)
656
			die_errno(_("could not read log file '%s'"),
657
				  logfile);
658
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
659 660
	} else if (use_message) {
		buffer = strstr(use_message_buffer, "\n\n");
661
		if (!use_editor && (!buffer || buffer[2] == '\0'))
662
			die(_("commit has empty message"));
K
Kristian Høgsberg 已提交
663
		strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
664 665
		hook_arg1 = "commit";
		hook_arg2 = use_message;
666 667 668 669 670
	} else if (fixup_message) {
		struct pretty_print_context ctx = {0};
		struct commit *commit;
		commit = lookup_commit_reference_by_name(fixup_message);
		if (!commit)
671
			die(_("could not lookup commit %s"), fixup_message);
672 673 674 675
		ctx.output_encoding = get_commit_output_encoding();
		format_commit_message(commit, "fixup! %s\n\n",
				      &sb, &ctx);
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
676 677
	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
678
			die_errno(_("could not read MERGE_MSG"));
679
		hook_arg1 = "merge";
K
Kristian Høgsberg 已提交
680 681
	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
682
			die_errno(_("could not read SQUASH_MSG"));
683
		hook_arg1 = "squash";
684
	} else if (template_file) {
K
Kristian Høgsberg 已提交
685
		if (strbuf_read_file(&sb, template_file, 0) < 0)
686
			die_errno(_("could not read '%s'"), template_file);
687
		hook_arg1 = "template";
688
		clean_message_contents = 0;
K
Kristian Høgsberg 已提交
689 690
	}

691
	/*
692 693
	 * The remaining cases don't modify the template message, but
	 * just set the argument(s) to the prepare-commit-msg hook.
694
	 */
695
	else if (whence == FROM_MERGE)
696
		hook_arg1 = "merge";
697 698 699 700
	else if (whence == FROM_CHERRY_PICK) {
		hook_arg1 = "commit";
		hook_arg2 = "CHERRY_PICK_HEAD";
	}
701

702 703 704 705 706 707 708 709 710 711
	if (squash_message) {
		/*
		 * If squash_commit was used for the commit subject,
		 * then we're possibly hijacking other commit log options.
		 * Reset the hook args to tell the real story.
		 */
		hook_arg1 = "message";
		hook_arg2 = "";
	}

712 713
	s->fp = fopen(git_path(commit_editmsg), "w");
	if (s->fp == NULL)
714
		die_errno(_("could not open '%s'"), git_path(commit_editmsg));
K
Kristian Høgsberg 已提交
715

716
	if (clean_message_contents)
717
		stripspace(&sb, 0);
K
Kristian Høgsberg 已提交
718 719

	if (signoff) {
720
		struct strbuf sob = STRBUF_INIT;
721 722 723
		int i;

		strbuf_addstr(&sob, sign_off_header);
724 725
		strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
					     getenv("GIT_COMMITTER_EMAIL")));
726 727 728
		strbuf_addch(&sob, '\n');
		for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
			; /* do nothing */
729
		if (prefixcmp(sb.buf + i, sob.buf)) {
730
			if (!i || !ends_rfc2822_footer(&sb))
731
				strbuf_addch(&sb, '\n');
732
			strbuf_addbuf(&sb, &sob);
733
		}
734
		strbuf_release(&sob);
K
Kristian Høgsberg 已提交
735 736
	}

737
	if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
738
		die_errno(_("could not write commit template"));
739

K
Kristian Høgsberg 已提交
740 741
	strbuf_release(&sb);

742
	/* This checks if committer ident is explicitly given */
743
	strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT));
744
	if (use_editor && include_status) {
745
		char *ai_tmp, *ci_tmp;
746
		if (whence != FROM_COMMIT)
747
			status_printf_ln(s, GIT_COLOR_NORMAL,
748 749 750 751 752 753 754 755 756 757 758
			    whence == FROM_MERGE
				? _("\n"
					"It looks like you may be committing a merge.\n"
					"If this is not correct, please remove the file\n"
					"	%s\n"
					"and try again.\n")
				: _("\n"
					"It looks like you may be committing a cherry-pick.\n"
					"If this is not correct, please remove the file\n"
					"	%s\n"
					"and try again.\n"),
759 760 761
				git_path(whence == FROM_MERGE
					 ? "MERGE_HEAD"
					 : "CHERRY_PICK_HEAD"));
762

763
		fprintf(s->fp, "\n");
764
		if (cleanup_mode == CLEANUP_ALL)
765 766 767
			status_printf(s, GIT_COLOR_NORMAL,
				_("Please enter the commit message for your changes."
				" Lines starting\nwith '#' will be ignored, and an empty"
768
				" message aborts the commit.\n"));
769
		else /* CLEANUP_SPACE, that is. */
770 771 772
			status_printf(s, GIT_COLOR_NORMAL,
				_("Please enter the commit message for your changes."
				" Lines starting\n"
773
				"with '#' will be kept; you may remove them"
J
Jeff King 已提交
774
				" yourself if you want to.\n"
775
				"An empty message aborts the commit.\n"));
776
		if (only_include_assumed)
777 778
			status_printf_ln(s, GIT_COLOR_NORMAL,
					"%s", only_include_assumed);
779

780 781 782
		ai_tmp = cut_ident_timestamp_part(author_ident->buf);
		ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
		if (strcmp(author_ident->buf, committer_ident.buf))
783
			status_printf_ln(s, GIT_COLOR_NORMAL,
784 785
				_("%s"
				"Author:    %s"),
786
				ident_shown++ ? "" : "\n",
787
				author_ident->buf);
788

789
		if (!user_ident_sufficiently_given())
790
			status_printf_ln(s, GIT_COLOR_NORMAL,
791 792
				_("%s"
				"Committer: %s"),
793
				ident_shown++ ? "" : "\n",
794
				committer_ident.buf);
795 796

		if (ident_shown)
797
			status_printf_ln(s, GIT_COLOR_NORMAL, "");
798

799 800
		saved_color_setting = s->use_color;
		s->use_color = 0;
801
		commitable = run_status(s->fp, index_file, prefix, 1, s);
802
		s->use_color = saved_color_setting;
803 804 805

		*ai_tmp = ' ';
		*ci_tmp = ' ';
806
	} else {
807
		unsigned char sha1[20];
808
		const char *parent = "HEAD";
809 810

		if (!active_nr && read_cache() < 0)
811
			die(_("Cannot read index"));
812

813 814 815
		if (amend)
			parent = "HEAD^1";

816
		if (get_sha1(parent, sha1))
817
			commitable = !!active_nr;
818 819
		else
			commitable = index_differs_from(parent, 0);
820
	}
821
	strbuf_release(&committer_ident);
822

823
	fclose(s->fp);
824

825 826 827 828 829 830
	/*
	 * Reject an attempt to record a non-merge empty commit without
	 * explicit --allow-empty. In the cherry-pick case, it may be
	 * empty due to conflict resolution, which the user should okay.
	 */
	if (!commitable && whence != FROM_MERGE && !allow_empty &&
831
	    !(amend && is_a_merge(current_head))) {
832
		run_status(stdout, index_file, prefix, 0, s);
J
Jeff King 已提交
833
		if (amend)
834
			fputs(_(empty_amend_advice), stderr);
835
		else if (whence == FROM_CHERRY_PICK)
J
Junio C Hamano 已提交
836
			fputs(_(empty_cherry_pick_advice), stderr);
837
		return 0;
838 839
	}

840 841 842 843 844 845 846
	/*
	 * Re-read the index as pre-commit hook could have updated it,
	 * and write it out as a tree.  We must do this before we invoke
	 * the editor and after we invoke run_status above.
	 */
	discard_cache();
	read_cache_from(index_file);
847
	if (update_main_cache_tree(0)) {
848
		error(_("Error building trees"));
849
		return 0;
850
	}
K
Kristian Høgsberg 已提交
851

852 853 854
	if (run_hook(index_file, "prepare-commit-msg",
		     git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
		return 0;
K
Kristian Høgsberg 已提交
855

856 857
	if (use_editor) {
		char index[PATH_MAX];
858 859
		const char *env[2] = { NULL };
		env[0] =  index;
860
		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
S
Stephan Beyer 已提交
861 862
		if (launch_editor(git_path(commit_editmsg), NULL, env)) {
			fprintf(stderr,
863
			_("Please supply the message using either -m or -F option.\n"));
S
Stephan Beyer 已提交
864 865
			exit(1);
		}
866
	}
K
Kristian Høgsberg 已提交
867

868 869 870 871
	if (!no_verify &&
	    run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
		return 0;
	}
K
Kristian Høgsberg 已提交
872

873
	return 1;
K
Kristian Høgsberg 已提交
874 875
}

876
static int rest_is_empty(struct strbuf *sb, int start)
K
Kristian Høgsberg 已提交
877
{
878
	int i, eol;
K
Kristian Høgsberg 已提交
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
	const char *nl;

	/* Check if the rest is just whitespace and Signed-of-by's. */
	for (i = start; i < sb->len; i++) {
		nl = memchr(sb->buf + i, '\n', sb->len - i);
		if (nl)
			eol = nl - sb->buf;
		else
			eol = sb->len;

		if (strlen(sign_off_header) <= eol - i &&
		    !prefixcmp(sb->buf + i, sign_off_header)) {
			i = eol;
			continue;
		}
		while (i < eol)
			if (!isspace(sb->buf[i++]))
				return 0;
	}

	return 1;
}

902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
/*
 * Find out if the message in the strbuf contains only whitespace and
 * Signed-off-by lines.
 */
static int message_is_empty(struct strbuf *sb)
{
	if (cleanup_mode == CLEANUP_NONE && sb->len)
		return 0;
	return rest_is_empty(sb, 0);
}

/*
 * See if the user edited the message in the editor or left what
 * was in the template intact
 */
static int template_untouched(struct strbuf *sb)
{
	struct strbuf tmpl = STRBUF_INIT;
	char *start;

	if (cleanup_mode == CLEANUP_NONE && sb->len)
		return 0;

	if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
		return 0;

	stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
	start = (char *)skip_prefix(sb->buf, tmpl.buf);
	if (!start)
		start = sb->buf;
	strbuf_release(&tmpl);
	return rest_is_empty(sb, start - sb->buf);
}

936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
static const char *find_author_by_nickname(const char *name)
{
	struct rev_info revs;
	struct commit *commit;
	struct strbuf buf = STRBUF_INIT;
	const char *av[20];
	int ac = 0;

	init_revisions(&revs, NULL);
	strbuf_addf(&buf, "--author=%s", name);
	av[++ac] = "--all";
	av[++ac] = "-i";
	av[++ac] = buf.buf;
	av[++ac] = NULL;
	setup_revisions(ac, av, &revs, NULL);
	prepare_revision_walk(&revs);
	commit = get_revision(&revs);
	if (commit) {
954 955
		struct pretty_print_context ctx = {0};
		ctx.date_mode = DATE_NORMAL;
956
		strbuf_release(&buf);
957
		format_commit_message(commit, "%an <%ae>", &buf, &ctx);
958 959
		return strbuf_detach(&buf, NULL);
	}
960
	die(_("No existing author found with '%s'"), name);
961 962
}

963 964 965 966 967 968 969 970 971 972 973 974

static void handle_untracked_files_arg(struct wt_status *s)
{
	if (!untracked_files_arg)
		; /* default already initialized */
	else if (!strcmp(untracked_files_arg, "no"))
		s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
	else if (!strcmp(untracked_files_arg, "normal"))
		s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
	else if (!strcmp(untracked_files_arg, "all"))
		s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
	else
975
		die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
976 977
}

978 979 980 981 982 983 984
static const char *read_commit_message(const char *name)
{
	const char *out_enc, *out;
	struct commit *commit;

	commit = lookup_commit_reference_by_name(name);
	if (!commit)
J
Junio C Hamano 已提交
985
		die(_("could not lookup commit %s"), name);
986 987 988 989 990 991 992 993 994 995 996 997 998 999
	out_enc = get_commit_output_encoding();
	out = logmsg_reencode(commit, out_enc);

	/*
	 * If we failed to reencode the buffer, just copy it
	 * byte for byte so the user can try to fix it up.
	 * This also handles the case where input and output
	 * encodings are identical.
	 */
	if (out == NULL)
		out = xstrdup(commit->buffer);
	return out;
}

1000
static int parse_and_validate_options(int argc, const char *argv[],
J
Jeff King 已提交
1001
				      const struct option *options,
1002
				      const char * const usage[],
1003
				      const char *prefix,
1004
				      struct commit *current_head,
1005
				      struct wt_status *s)
K
Kristian Høgsberg 已提交
1006 1007 1008
{
	int f = 0;

J
Jeff King 已提交
1009
	argc = parse_options(argc, argv, prefix, options, usage, 0);
K
Kristian Høgsberg 已提交
1010

1011 1012 1013
	if (force_author && !strchr(force_author, '>'))
		force_author = find_author_by_nickname(force_author);

1014
	if (force_author && renew_authorship)
1015
		die(_("Using both --reset-author and --author does not make sense"));
1016

1017
	if (logfile || message.len || use_message || fixup_message)
1018
		use_editor = 0;
J
Junio C Hamano 已提交
1019 1020
	if (0 <= edit_flag)
		use_editor = edit_flag;
1021 1022
	if (!use_editor)
		setenv("GIT_EDITOR", ":", 1);
K
Kristian Høgsberg 已提交
1023 1024

	/* Sanity check options */
1025
	if (amend && !current_head)
1026
		die(_("You have nothing to amend."));
1027 1028 1029 1030 1031 1032
	if (amend && whence != FROM_COMMIT) {
		if (whence == FROM_MERGE)
			die(_("You are in the middle of a merge -- cannot amend."));
		else if (whence == FROM_CHERRY_PICK)
			die(_("You are in the middle of a cherry-pick -- cannot amend."));
	}
1033
	if (fixup_message && squash_message)
1034
		die(_("Options --squash and --fixup cannot be used together"));
K
Kristian Høgsberg 已提交
1035 1036 1037 1038
	if (use_message)
		f++;
	if (edit_message)
		f++;
1039 1040
	if (fixup_message)
		f++;
K
Kristian Høgsberg 已提交
1041 1042 1043
	if (logfile)
		f++;
	if (f > 1)
1044
		die(_("Only one of -c/-C/-F/--fixup can be used."));
1045
	if (message.len && f > 0)
1046
		die((_("Option -m cannot be combined with -c/-C/-F/--fixup.")));
1047 1048
	if (f || message.len)
		template_file = NULL;
K
Kristian Høgsberg 已提交
1049 1050
	if (edit_message)
		use_message = edit_message;
1051
	if (amend && !use_message && !fixup_message)
K
Kristian Høgsberg 已提交
1052
		use_message = "HEAD";
1053
	if (!use_message && whence != FROM_CHERRY_PICK && renew_authorship)
1054
		die(_("--reset-author can be used only with -C, -c or --amend."));
K
Kristian Høgsberg 已提交
1055
	if (use_message) {
1056 1057 1058 1059 1060 1061 1062 1063 1064
		use_message_buffer = read_commit_message(use_message);
		if (!renew_authorship) {
			author_message = use_message;
			author_message_buffer = use_message_buffer;
		}
	}
	if (whence == FROM_CHERRY_PICK && !renew_authorship) {
		author_message = "CHERRY_PICK_HEAD";
		author_message_buffer = read_commit_message(author_message);
K
Kristian Høgsberg 已提交
1065 1066
	}

1067 1068 1069
	if (patch_interactive)
		interactive = 1;

K
Kristian Høgsberg 已提交
1070
	if (!!also + !!only + !!all + !!interactive > 1)
1071
		die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
K
Kristian Høgsberg 已提交
1072
	if (argc == 0 && (also || (only && !amend)))
1073
		die(_("No paths with --include/--only does not make sense."));
K
Kristian Høgsberg 已提交
1074
	if (argc == 0 && only && amend)
1075
		only_include_assumed = _("Clever... amending the last one with dirty index.");
1076
	if (argc > 0 && !also && !only)
1077
		only_include_assumed = _("Explicit paths specified without -i nor -o; assuming --only paths...");
1078 1079 1080 1081 1082 1083 1084 1085 1086
	if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
		cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
	else if (!strcmp(cleanup_arg, "verbatim"))
		cleanup_mode = CLEANUP_NONE;
	else if (!strcmp(cleanup_arg, "whitespace"))
		cleanup_mode = CLEANUP_SPACE;
	else if (!strcmp(cleanup_arg, "strip"))
		cleanup_mode = CLEANUP_ALL;
	else
1087
		die(_("Invalid cleanup mode %s"), cleanup_arg);
K
Kristian Høgsberg 已提交
1088

1089
	handle_untracked_files_arg(s);
1090

K
Kristian Høgsberg 已提交
1091
	if (all && argc > 0)
1092
		die(_("Paths with -a does not make sense."));
K
Kristian Høgsberg 已提交
1093

1094
	if (s->null_termination && status_format == STATUS_FORMAT_LONG)
1095 1096 1097 1098
		status_format = STATUS_FORMAT_PORCELAIN;
	if (status_format != STATUS_FORMAT_LONG)
		dry_run = 1;

K
Kristian Høgsberg 已提交
1099 1100 1101
	return argc;
}

1102
static int dry_run_commit(int argc, const char **argv, const char *prefix,
1103
			  const struct commit *current_head, struct wt_status *s)
K
Kristian Høgsberg 已提交
1104 1105
{
	int commitable;
J
Junio C Hamano 已提交
1106
	const char *index_file;
K
Kristian Høgsberg 已提交
1107

1108
	index_file = prepare_index(argc, argv, prefix, current_head, 1);
1109
	commitable = run_status(stdout, index_file, prefix, 0, s);
J
Junio C Hamano 已提交
1110
	rollback_index_files();
K
Kristian Høgsberg 已提交
1111

J
Junio C Hamano 已提交
1112 1113 1114
	return commitable ? 0 : 1;
}

1115 1116 1117 1118
static int parse_status_slot(const char *var, int offset)
{
	if (!strcasecmp(var+offset, "header"))
		return WT_STATUS_HEADER;
1119 1120
	if (!strcasecmp(var+offset, "branch"))
		return WT_STATUS_ONBRANCH;
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
	if (!strcasecmp(var+offset, "updated")
		|| !strcasecmp(var+offset, "added"))
		return WT_STATUS_UPDATED;
	if (!strcasecmp(var+offset, "changed"))
		return WT_STATUS_CHANGED;
	if (!strcasecmp(var+offset, "untracked"))
		return WT_STATUS_UNTRACKED;
	if (!strcasecmp(var+offset, "nobranch"))
		return WT_STATUS_NOBRANCH;
	if (!strcasecmp(var+offset, "unmerged"))
		return WT_STATUS_UNMERGED;
J
Jeff King 已提交
1132
	return -1;
1133 1134 1135 1136 1137 1138
}

static int git_status_config(const char *k, const char *v, void *cb)
{
	struct wt_status *s = cb;

N
Nguyễn Thái Ngọc Duy 已提交
1139
	if (!prefixcmp(k, "column."))
J
Jeff King 已提交
1140
		return git_column_config(k, v, "status", &s->colopts);
1141 1142 1143 1144 1145 1146 1147 1148
	if (!strcmp(k, "status.submodulesummary")) {
		int is_bool;
		s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
		if (is_bool && s->submodule_summary)
			s->submodule_summary = -1;
		return 0;
	}
	if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
1149
		s->use_color = git_config_colorbool(k, v);
1150 1151 1152 1153
		return 0;
	}
	if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
		int slot = parse_status_slot(k, 13);
J
Jeff King 已提交
1154 1155
		if (slot < 0)
			return 0;
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
		if (!v)
			return config_error_nonbool(k);
		color_parse(v, k, s->color_palette[slot]);
		return 0;
	}
	if (!strcmp(k, "status.relativepaths")) {
		s->relative_paths = git_config_bool(k, v);
		return 0;
	}
	if (!strcmp(k, "status.showuntrackedfiles")) {
		if (!v)
			return config_error_nonbool(k);
		else if (!strcmp(v, "no"))
			s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
		else if (!strcmp(v, "normal"))
			s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
		else if (!strcmp(v, "all"))
			s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
		else
1175
			return error(_("Invalid untracked files mode '%s'"), v);
1176 1177 1178 1179 1180
		return 0;
	}
	return git_diff_ui_config(k, v, NULL);
}

J
Junio C Hamano 已提交
1181 1182
int cmd_status(int argc, const char **argv, const char *prefix)
{
J
Jeff King 已提交
1183
	static struct wt_status s;
1184
	int fd;
1185
	unsigned char sha1[20];
1186
	static struct option builtin_status_options[] = {
1187
		OPT__VERBOSE(&verbose, N_("be verbose")),
1188
		OPT_SET_INT('s', "short", &status_format,
1189
			    N_("show status concisely"), STATUS_FORMAT_SHORT),
1190
		OPT_BOOLEAN('b', "branch", &s.show_branch,
1191
			    N_("show branch information")),
1192
		OPT_SET_INT(0, "porcelain", &status_format,
1193
			    N_("machine-readable output"),
1194
			    STATUS_FORMAT_PORCELAIN),
1195
		OPT_BOOLEAN('z', "null", &s.null_termination,
1196
			    N_("terminate entries with NUL")),
1197
		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1198 1199
		  N_("mode"),
		  N_("show untracked files, optional modes: all, normal, no. (Default: all)"),
1200
		  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1201
		OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
1202 1203 1204
			    N_("show ignored files")),
		{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"),
		  N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
1205
		  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1206
		OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
1207 1208 1209
		OPT_END(),
	};

1210 1211 1212
	if (argc == 2 && !strcmp(argv[1], "-h"))
		usage_with_options(builtin_status_usage, builtin_status_options);

1213
	wt_status_prepare(&s);
1214
	gitmodules_config();
1215
	git_config(git_status_config, &s);
1216
	determine_whence(&s);
1217
	argc = parse_options(argc, argv, prefix,
1218 1219
			     builtin_status_options,
			     builtin_status_usage, 0);
J
Jeff King 已提交
1220
	finalize_colopts(&s.colopts, -1);
1221

1222
	if (s.null_termination && status_format == STATUS_FORMAT_LONG)
1223 1224
		status_format = STATUS_FORMAT_PORCELAIN;

1225
	handle_untracked_files_arg(&s);
1226 1227
	if (show_ignored_in_status)
		s.show_ignored_files = 1;
1228 1229 1230
	if (*argv)
		s.pathspec = get_pathspec(prefix, argv);

1231
	read_cache_preload(s.pathspec);
1232
	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1233 1234

	fd = hold_locked_index(&index_lock, 0);
1235 1236
	if (0 <= fd)
		update_index_if_able(&the_index, &index_lock);
1237

1238
	s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1239
	s.ignore_submodule_arg = ignore_submodule_arg;
1240 1241
	wt_status_collect(&s);

J
Jeff King 已提交
1242 1243
	if (s.relative_paths)
		s.prefix = prefix;
1244

1245 1246
	switch (status_format) {
	case STATUS_FORMAT_SHORT:
1247
		wt_shortstatus_print(&s);
1248
		break;
1249
	case STATUS_FORMAT_PORCELAIN:
1250
		wt_porcelain_print(&s);
1251
		break;
1252
	case STATUS_FORMAT_LONG:
1253
		s.verbose = verbose;
1254
		s.ignore_submodule_arg = ignore_submodule_arg;
1255
		wt_status_print(&s);
1256
		break;
1257
	}
1258
	return 0;
K
Kristian Høgsberg 已提交
1259 1260
}

1261 1262
static void print_summary(const char *prefix, const unsigned char *sha1,
			  int initial_commit)
K
Kristian Høgsberg 已提交
1263 1264 1265
{
	struct rev_info rev;
	struct commit *commit;
1266
	struct strbuf format = STRBUF_INIT;
J
Jeff King 已提交
1267
	unsigned char junk_sha1[20];
1268
	const char *head;
1269 1270 1271
	struct pretty_print_context pctx = {0};
	struct strbuf author_ident = STRBUF_INIT;
	struct strbuf committer_ident = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1272 1273 1274

	commit = lookup_commit(sha1);
	if (!commit)
1275
		die(_("couldn't look up newly created commit"));
K
Kristian Høgsberg 已提交
1276
	if (!commit || parse_commit(commit))
1277
		die(_("could not parse newly created commit"));
K
Kristian Høgsberg 已提交
1278

1279 1280 1281 1282 1283 1284 1285 1286
	strbuf_addstr(&format, "format:%h] %s");

	format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
	format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
	if (strbuf_cmp(&author_ident, &committer_ident)) {
		strbuf_addstr(&format, "\n Author: ");
		strbuf_addbuf_percentquote(&format, &author_ident);
	}
1287
	if (!user_ident_sufficiently_given()) {
1288 1289
		strbuf_addstr(&format, "\n Committer: ");
		strbuf_addbuf_percentquote(&format, &committer_ident);
1290 1291
		if (advice_implicit_identity) {
			strbuf_addch(&format, '\n');
1292
			strbuf_addstr(&format, _(implicit_ident_advice));
1293
		}
1294 1295 1296 1297
	}
	strbuf_release(&author_ident);
	strbuf_release(&committer_ident);

K
Kristian Høgsberg 已提交
1298 1299 1300 1301 1302 1303 1304 1305 1306
	init_revisions(&rev, prefix);
	setup_revisions(0, NULL, &rev, NULL);

	rev.diff = 1;
	rev.diffopt.output_format =
		DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;

	rev.verbose_header = 1;
	rev.show_root_diff = 1;
1307
	get_commit_format(format.buf, &rev);
1308
	rev.always_show_header = 0;
1309 1310
	rev.diffopt.detect_rename = 1;
	rev.diffopt.break_opt = 0;
1311
	diff_setup_done(&rev.diffopt);
K
Kristian Høgsberg 已提交
1312

1313
	head = resolve_ref_unsafe("HEAD", junk_sha1, 0, NULL);
1314
	printf("[%s%s ",
J
Jeff King 已提交
1315 1316 1317
		!prefixcmp(head, "refs/heads/") ?
			head + 11 :
			!strcmp(head, "HEAD") ?
1318
				_("detached HEAD") :
J
Jeff King 已提交
1319
				head,
1320
		initial_commit ? _(" (root-commit)") : "");
K
Kristian Høgsberg 已提交
1321

1322
	if (!log_tree_commit(&rev, commit)) {
1323 1324 1325
		rev.always_show_header = 1;
		rev.use_terminator = 1;
		log_tree_commit(&rev, commit);
1326
	}
1327

1328
	strbuf_release(&format);
K
Kristian Høgsberg 已提交
1329 1330
}

1331
static int git_commit_config(const char *k, const char *v, void *cb)
K
Kristian Høgsberg 已提交
1332
{
1333
	struct wt_status *s = cb;
J
Junio C Hamano 已提交
1334
	int status;
1335

1336
	if (!strcmp(k, "commit.template"))
1337
		return git_config_pathname(&template_file, k, v);
1338 1339 1340 1341
	if (!strcmp(k, "commit.status")) {
		include_status = git_config_bool(k, v);
		return 0;
	}
K
Kristian Høgsberg 已提交
1342

J
Junio C Hamano 已提交
1343 1344 1345
	status = git_gpg_config(k, v, NULL);
	if (status)
		return status;
1346
	return git_status_config(k, v, s);
K
Kristian Høgsberg 已提交
1347 1348
}

1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
static const char post_rewrite_hook[] = "hooks/post-rewrite";

static int run_rewrite_hook(const unsigned char *oldsha1,
			    const unsigned char *newsha1)
{
	/* oldsha1 SP newsha1 LF NUL */
	static char buf[2*40 + 3];
	struct child_process proc;
	const char *argv[3];
	int code;
	size_t n;

	if (access(git_path(post_rewrite_hook), X_OK) < 0)
		return 0;

	argv[0] = git_path(post_rewrite_hook);
	argv[1] = "amend";
	argv[2] = NULL;

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

	code = start_command(&proc);
	if (code)
		return code;
	n = snprintf(buf, sizeof(buf), "%s %s\n",
		     sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
	write_in_full(proc.in, buf, n);
	close(proc.in);
	return finish_command(&proc);
}

K
Kristian Høgsberg 已提交
1383 1384
int cmd_commit(int argc, const char **argv, const char *prefix)
{
J
Jeff King 已提交
1385 1386
	static struct wt_status s;
	static struct option builtin_commit_options[] = {
1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
		OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
		OPT__VERBOSE(&verbose, N_("show diff in commit message template")),

		OPT_GROUP(N_("Commit message options")),
		OPT_FILENAME('F', "file", &logfile, N_("read message from file")),
		OPT_STRING(0, "author", &force_author, N_("author"), N_("override author for commit")),
		OPT_STRING(0, "date", &force_date, N_("date"), N_("override date for commit")),
		OPT_CALLBACK('m', "message", &message, N_("message"), N_("commit message"), opt_parse_m),
		OPT_STRING('c', "reedit-message", &edit_message, N_("commit"), N_("reuse and edit message from specified commit")),
		OPT_STRING('C', "reuse-message", &use_message, N_("commit"), N_("reuse message from specified commit")),
		OPT_STRING(0, "fixup", &fixup_message, N_("commit"), N_("use autosquash formatted message to fixup specified commit")),
		OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")),
		OPT_BOOLEAN(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
		OPT_BOOLEAN('s', "signoff", &signoff, N_("add Signed-off-by:")),
		OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
		OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
		OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")),
		OPT_BOOLEAN(0, "status", &include_status, N_("include status in commit message template")),
		{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
		  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
J
Jeff King 已提交
1407 1408
		/* end commit message options */

1409 1410 1411 1412 1413 1414 1415 1416 1417
		OPT_GROUP(N_("Commit contents options")),
		OPT_BOOLEAN('a', "all", &all, N_("commit all changed files")),
		OPT_BOOLEAN('i', "include", &also, N_("add specified files to index for commit")),
		OPT_BOOLEAN(0, "interactive", &interactive, N_("interactively add files")),
		OPT_BOOLEAN('p', "patch", &patch_interactive, N_("interactively add changes")),
		OPT_BOOLEAN('o', "only", &only, N_("commit only specified files")),
		OPT_BOOLEAN('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
		OPT_BOOLEAN(0, "dry-run", &dry_run, N_("show what would be committed")),
		OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
J
Jeff King 已提交
1418
			    STATUS_FORMAT_SHORT),
1419
		OPT_BOOLEAN(0, "branch", &s.show_branch, N_("show branch information")),
J
Jeff King 已提交
1420
		OPT_SET_INT(0, "porcelain", &status_format,
1421
			    N_("machine-readable output"), STATUS_FORMAT_PORCELAIN),
1422
		OPT_BOOLEAN('z', "null", &s.null_termination,
1423 1424 1425 1426
			    N_("terminate entries with NUL")),
		OPT_BOOLEAN(0, "amend", &amend, N_("amend previous commit")),
		OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
J
Jeff King 已提交
1427 1428 1429
		/* end commit contents options */

		{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
1430
		  N_("ok to record an empty change"),
J
Jeff King 已提交
1431 1432
		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
		{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
1433
		  N_("ok to record a change with an empty message"),
J
Jeff King 已提交
1434 1435 1436 1437 1438
		  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },

		OPT_END()
	};

1439
	struct strbuf sb = STRBUF_INIT;
1440
	struct strbuf author_ident = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1441
	const char *index_file, *reflog_msg;
1442
	char *nl, *p;
1443
	unsigned char sha1[20];
K
Kristian Høgsberg 已提交
1444
	struct ref_lock *ref_lock;
M
Miklos Vajna 已提交
1445
	struct commit_list *parents = NULL, **pptr = &parents;
1446 1447
	struct stat statbuf;
	int allow_fast_forward = 1;
1448
	struct commit *current_head = NULL;
1449
	struct commit_extra_header *extra = NULL;
K
Kristian Høgsberg 已提交
1450

1451 1452 1453
	if (argc == 2 && !strcmp(argv[1], "-h"))
		usage_with_options(builtin_commit_usage, builtin_commit_options);

1454 1455
	wt_status_prepare(&s);
	git_config(git_commit_config, &s);
1456
	determine_whence(&s);
J
Jeff King 已提交
1457
	s.colopts = 0;
K
Kristian Høgsberg 已提交
1458

1459 1460 1461
	if (get_sha1("HEAD", sha1))
		current_head = NULL;
	else {
1462
		current_head = lookup_commit_or_die(sha1, "HEAD");
1463 1464 1465
		if (!current_head || parse_commit(current_head))
			die(_("could not parse HEAD commit"));
	}
J
Jeff King 已提交
1466 1467
	argc = parse_and_validate_options(argc, argv, builtin_commit_options,
					  builtin_commit_usage,
1468
					  prefix, current_head, &s);
1469
	if (dry_run)
1470 1471
		return dry_run_commit(argc, argv, prefix, current_head, &s);
	index_file = prepare_index(argc, argv, prefix, current_head, 0);
K
Kristian Høgsberg 已提交
1472

1473 1474
	/* Set up everything for writing the commit object.  This includes
	   running hooks, writing the trees, and interacting with the user.  */
1475 1476
	if (!prepare_to_commit(index_file, prefix,
			       current_head, &s, &author_ident)) {
1477
		rollback_index_files();
K
Kristian Høgsberg 已提交
1478 1479 1480 1481
		return 1;
	}

	/* Determine parents */
1482
	reflog_msg = getenv("GIT_REFLOG_ACTION");
1483
	if (!current_head) {
1484 1485
		if (!reflog_msg)
			reflog_msg = "commit (initial)";
K
Kristian Høgsberg 已提交
1486 1487 1488
	} else if (amend) {
		struct commit_list *c;

1489 1490
		if (!reflog_msg)
			reflog_msg = "commit (amend)";
1491
		for (c = current_head->parents; c; c = c->next)
M
Miklos Vajna 已提交
1492
			pptr = &commit_list_insert(c->item, pptr)->next;
1493
	} else if (whence == FROM_MERGE) {
1494
		struct strbuf m = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1495 1496
		FILE *fp;

1497 1498
		if (!reflog_msg)
			reflog_msg = "commit (merge)";
1499
		pptr = &commit_list_insert(current_head, pptr)->next;
K
Kristian Høgsberg 已提交
1500 1501
		fp = fopen(git_path("MERGE_HEAD"), "r");
		if (fp == NULL)
1502
			die_errno(_("could not open '%s' for reading"),
1503
				  git_path("MERGE_HEAD"));
1504
		while (strbuf_getline(&m, fp, '\n') != EOF) {
1505 1506 1507 1508
			struct commit *parent;

			parent = get_merge_parent(m.buf);
			if (!parent)
1509
				die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
1510
			pptr = &commit_list_insert(parent, pptr)->next;
1511
		}
K
Kristian Høgsberg 已提交
1512 1513
		fclose(fp);
		strbuf_release(&m);
1514 1515
		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1516
				die_errno(_("could not read MERGE_MODE"));
1517 1518 1519 1520 1521
			if (!strcmp(sb.buf, "no-ff"))
				allow_fast_forward = 0;
		}
		if (allow_fast_forward)
			parents = reduce_heads(parents);
K
Kristian Høgsberg 已提交
1522
	} else {
1523
		if (!reflog_msg)
1524 1525 1526
			reflog_msg = (whence == FROM_CHERRY_PICK)
					? "commit (cherry-pick)"
					: "commit";
1527
		pptr = &commit_list_insert(current_head, pptr)->next;
K
Kristian Høgsberg 已提交
1528 1529
	}

1530
	/* Finally, get the commit message */
1531
	strbuf_reset(&sb);
1532
	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1533
		int saved_errno = errno;
1534
		rollback_index_files();
1535
		die(_("could not read commit message: %s"), strerror(saved_errno));
1536
	}
1537 1538

	/* Truncate the message just before the diff, if any. */
1539 1540 1541 1542 1543
	if (verbose) {
		p = strstr(sb.buf, "\ndiff --git ");
		if (p != NULL)
			strbuf_setlen(&sb, p - sb.buf + 1);
	}
1544

1545 1546
	if (cleanup_mode != CLEANUP_NONE)
		stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1547 1548 1549 1550 1551
	if (template_untouched(&sb) && !allow_empty_message) {
		rollback_index_files();
		fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
		exit(1);
	}
1552
	if (message_is_empty(&sb) && !allow_empty_message) {
1553
		rollback_index_files();
1554
		fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
J
Jeff King 已提交
1555
		exit(1);
1556
	}
K
Kristian Høgsberg 已提交
1557

1558
	if (amend) {
1559 1560
		const char *exclude_gpgsig[2] = { "gpgsig", NULL };
		extra = read_commit_extra_headers(current_head, exclude_gpgsig);
1561 1562 1563 1564
	} else {
		struct commit_extra_header **tail = &extra;
		append_merge_tag_headers(parents, &tail);
	}
1565

1566
	if (commit_tree_extended(&sb, active_cache_tree->sha1, parents, sha1,
J
Junio C Hamano 已提交
1567
				 author_ident.buf, sign_commit, extra)) {
1568
		rollback_index_files();
1569
		die(_("failed to write commit object"));
1570
	}
1571
	strbuf_release(&author_ident);
1572
	free_commit_extra_headers(extra);
K
Kristian Høgsberg 已提交
1573 1574

	ref_lock = lock_any_ref_for_update("HEAD",
1575 1576 1577
					   !current_head
					   ? NULL
					   : current_head->object.sha1,
K
Kristian Høgsberg 已提交
1578 1579
					   0);

M
Miklos Vajna 已提交
1580
	nl = strchr(sb.buf, '\n');
1581 1582 1583 1584 1585 1586
	if (nl)
		strbuf_setlen(&sb, nl + 1 - sb.buf);
	else
		strbuf_addch(&sb, '\n');
	strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
	strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
K
Kristian Høgsberg 已提交
1587

1588 1589
	if (!ref_lock) {
		rollback_index_files();
1590
		die(_("cannot lock HEAD ref"));
1591
	}
1592
	if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) {
1593
		rollback_index_files();
1594
		die(_("cannot update HEAD ref"));
1595
	}
K
Kristian Høgsberg 已提交
1596

J
Jay Soffian 已提交
1597
	unlink(git_path("CHERRY_PICK_HEAD"));
1598
	unlink(git_path("REVERT_HEAD"));
K
Kristian Høgsberg 已提交
1599 1600
	unlink(git_path("MERGE_HEAD"));
	unlink(git_path("MERGE_MSG"));
1601
	unlink(git_path("MERGE_MODE"));
1602
	unlink(git_path("SQUASH_MSG"));
K
Kristian Høgsberg 已提交
1603

1604
	if (commit_index_files())
1605
		die (_("Repository has been updated, but unable to write\n"
1606
		     "new_index file. Check that disk is not full or quota is\n"
1607
		     "not exceeded, and then \"git reset HEAD\" to recover."));
K
Kristian Høgsberg 已提交
1608

1609
	rerere(0);
1610
	run_hook(get_index_file(), "post-commit", NULL);
1611
	if (amend && !no_post_rewrite) {
1612 1613 1614
		struct notes_rewrite_cfg *cfg;
		cfg = init_copy_notes_for_rewrite("amend");
		if (cfg) {
1615 1616
			/* we are amending, so current_head is not NULL */
			copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
1617 1618
			finish_copy_notes_for_rewrite(cfg);
		}
1619
		run_rewrite_hook(current_head->object.sha1, sha1);
1620
	}
K
Kristian Høgsberg 已提交
1621
	if (!quiet)
1622
		print_summary(prefix, sha1, !current_head);
K
Kristian Høgsberg 已提交
1623 1624 1625

	return 0;
}