commit.c 37.3 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"
K
Kristian Høgsberg 已提交
28 29

static const char * const builtin_commit_usage[] = {
S
Stephan Beyer 已提交
30
	"git commit [options] [--] <filepattern>...",
K
Kristian Høgsberg 已提交
31 32 33
	NULL
};

34
static const char * const builtin_status_usage[] = {
S
Stephan Beyer 已提交
35
	"git status [options] [--] <filepattern>...",
36 37 38
	NULL
};

39 40 41 42 43
static const char implicit_ident_advice[] =
"Your name and email address were configured automatically based\n"
"on your username and hostname. Please check that they are accurate.\n"
"You can suppress this message by setting them explicitly:\n"
"\n"
44
"    git config --global user.name \"Your Name\"\n"
45 46 47 48 49 50
"    git config --global user.email you@example.com\n"
"\n"
"If the identity used for this commit is wrong, you can fix it with:\n"
"\n"
"    git commit --amend --author='Your Name <you@example.com>'\n";

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

56
static unsigned char head_sha1[20];
57

K
Kristian Høgsberg 已提交
58 59
static char *use_message_buffer;
static const char commit_editmsg[] = "COMMIT_EDITMSG";
60 61 62 63 64 65 66
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,
	COMMIT_PARTIAL,
} commit_style;
K
Kristian Høgsberg 已提交
67

68
static const char *logfile, *force_author;
69
static const char *template_file;
K
Kristian Høgsberg 已提交
70
static char *edit_message, *use_message;
71
static char *author_name, *author_email, *author_date;
K
Kristian Høgsberg 已提交
72
static int all, edit_flag, also, interactive, only, amend, signoff;
73
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
74
static int no_post_rewrite;
M
Miklos Vajna 已提交
75
static char *untracked_files_arg, *force_date;
76 77 78 79 80 81 82 83 84 85 86 87 88
/*
 * 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,
	CLEANUP_ALL,
} cleanup_mode;
static char *cleanup_arg;
K
Kristian Høgsberg 已提交
89

90
static int use_editor = 1, initial_commit, in_merge, include_status = 1;
91 92
static const char *only_include_assumed;
static struct strbuf message;
93

94 95 96 97 98 99 100
static int null_termination;
static enum {
	STATUS_FORMAT_LONG,
	STATUS_FORMAT_SHORT,
	STATUS_FORMAT_PORCELAIN,
} status_format = STATUS_FORMAT_LONG;

101 102 103 104 105 106 107
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);
108
		strbuf_addstr(buf, "\n\n");
109 110 111
	}
	return 0;
}
K
Kristian Høgsberg 已提交
112 113 114 115 116

static struct option builtin_commit_options[] = {
	OPT__QUIET(&quiet),
	OPT__VERBOSE(&verbose),

G
Greg Price 已提交
117
	OPT_GROUP("Commit message options"),
118
	OPT_FILENAME('F', "file", &logfile, "read log from file"),
K
Kristian Høgsberg 已提交
119
	OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
M
Miklos Vajna 已提交
120
	OPT_STRING(0, "date", &force_date, "DATE", "override date for commit"),
121
	OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
122
	OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
K
Kristian Høgsberg 已提交
123
	OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
124
	OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
125
	OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
126
	OPT_FILENAME('t', "template", &template_file, "use specified template file"),
K
Kristian Høgsberg 已提交
127
	OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
G
Greg Price 已提交
128
	OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
129
	OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
G
Greg Price 已提交
130
	/* end commit message options */
K
Kristian Høgsberg 已提交
131 132 133 134 135

	OPT_GROUP("Commit contents options"),
	OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
	OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
	OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
136
	OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
K
Kristian Høgsberg 已提交
137
	OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
J
Junio C Hamano 已提交
138
	OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
139 140 141 142 143 144
	OPT_SET_INT(0, "short", &status_format, "show status concisely",
		    STATUS_FORMAT_SHORT),
	OPT_SET_INT(0, "porcelain", &status_format,
		    "show porcelain output format", STATUS_FORMAT_PORCELAIN),
	OPT_BOOLEAN('z', "null", &null_termination,
		    "terminate entries with NUL"),
K
Kristian Høgsberg 已提交
145
	OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
146
	OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
147
	{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
J
Junio C Hamano 已提交
148
	OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
G
Greg Price 已提交
149
	/* end commit contents options */
K
Kristian Høgsberg 已提交
150 151 152 153

	OPT_END()
};

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
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;
	}
}

169
static int commit_index_files(void)
170
{
171 172
	int err = 0;

173 174 175 176
	switch (commit_style) {
	case COMMIT_AS_IS:
		break; /* nothing to do */
	case COMMIT_NORMAL:
177
		err = commit_lock_file(&index_lock);
178 179
		break;
	case COMMIT_PARTIAL:
180
		err = commit_lock_file(&index_lock);
181 182 183
		rollback_lock_file(&false_lock);
		break;
	}
184 185

	return err;
186 187 188 189 190 191
}

/*
 * 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.
 */
192
static int list_paths(struct string_list *list, const char *with_tree,
193 194 195 196 197 198 199 200 201 202 203 204 205 206
		      const char *prefix, const char **pattern)
{
	int i;
	char *m;

	for (i = 0; pattern[i]; i++)
		;
	m = xcalloc(1, i);

	if (with_tree)
		overlay_tree_on_cache(with_tree, prefix);

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

209
		if (ce->ce_flags & CE_UPDATE)
210
			continue;
211
		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
212
			continue;
213 214 215
		item = string_list_insert(ce->name, list);
		if (ce_skip_worktree(ce))
			item->util = item; /* better a valid pointer than a fake one */
216 217 218 219 220
	}

	return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
}

221
static void add_remove_files(struct string_list *list)
222 223 224
{
	int i;
	for (i = 0; i < list->nr; i++) {
225
		struct stat st;
226
		struct string_list_item *p = &(list->items[i]);
227

228 229
		/* p->util is skip-worktree */
		if (p->util)
230
			continue;
231

232 233
		if (!lstat(p->string, &st)) {
			if (add_to_cache(p->string, &st, 0))
234 235
				die("updating files failed");
		} else
236
			remove_file_from_cache(p->string);
237 238 239
	}
}

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
static void create_base_index(void)
{
	struct tree *tree;
	struct unpack_trees_options opts;
	struct tree_desc t;

	if (initial_commit) {
		discard_cache();
		return;
	}

	memset(&opts, 0, sizeof(opts));
	opts.head_idx = 1;
	opts.index_only = 1;
	opts.merge = 1;
255 256
	opts.src_index = &the_index;
	opts.dst_index = &the_index;
257 258 259 260 261 262 263

	opts.fn = oneway_merge;
	tree = parse_tree_indirect(head_sha1);
	if (!tree)
		die("failed to unpack HEAD tree object");
	parse_tree(tree);
	init_tree_desc(&t, tree->buffer, tree->size);
264 265
	if (unpack_trees(1, &t, &opts))
		exit(128); /* We've already reported the error, finish dying */
266 267
}

268 269 270 271 272 273 274 275 276 277
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");
}

278
static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
K
Kristian Høgsberg 已提交
279 280
{
	int fd;
281
	struct string_list partial;
282
	const char **pathspec = NULL;
283
	int refresh_flags = REFRESH_QUIET;
K
Kristian Høgsberg 已提交
284

285 286
	if (is_status)
		refresh_flags |= REFRESH_UNMERGED;
K
Kristian Høgsberg 已提交
287
	if (interactive) {
288 289
		if (interactive_add(argc, argv, prefix) != 0)
			die("interactive add failed");
L
Linus Torvalds 已提交
290
		if (read_cache_preload(NULL) < 0)
291
			die("index file corrupt");
292
		commit_style = COMMIT_AS_IS;
K
Kristian Høgsberg 已提交
293 294 295
		return get_index_file();
	}

296 297
	if (*argv)
		pathspec = get_pathspec(prefix, argv);
298

L
Linus Torvalds 已提交
299 300 301
	if (read_cache_preload(pathspec) < 0)
		die("index file corrupt");

302 303 304 305 306 307 308 309 310 311 312 313 314
	/*
	 * 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)) {
315
		fd = hold_locked_index(&index_lock, 1);
316
		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
317
		refresh_cache_or_die(refresh_flags);
B
Brandon Casey 已提交
318 319
		if (write_cache(fd, active_cache, active_nr) ||
		    close_lock_file(&index_lock))
K
Kristian Høgsberg 已提交
320
			die("unable to write new_index file");
321 322
		commit_style = COMMIT_NORMAL;
		return index_lock.filename;
K
Kristian Høgsberg 已提交
323 324
	}

325 326 327 328 329
	/*
	 * As-is commit.
	 *
	 * (1) return the name of the real index file.
	 *
330 331
	 * The caller should run hooks on the real index,
	 * and create commit from the_index.
332 333 334 335
	 * We still need to refresh the index here.
	 */
	if (!pathspec || !*pathspec) {
		fd = hold_locked_index(&index_lock, 1);
336
		refresh_cache_or_die(refresh_flags);
337
		if (write_cache(fd, active_cache, active_nr) ||
338
		    commit_locked_index(&index_lock))
339 340
			die("unable to write new_index file");
		commit_style = COMMIT_AS_IS;
K
Kristian Høgsberg 已提交
341 342 343
		return get_index_file();
	}

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
	/*
	 * 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;

365
	if (in_merge)
366 367 368
		die("cannot do a partial commit during a merge.");

	memset(&partial, 0, sizeof(partial));
369
	partial.strdup_strings = 1;
370 371 372 373 374 375 376 377 378
	if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
		exit(1);

	discard_cache();
	if (read_cache() < 0)
		die("cannot read the index");

	fd = hold_locked_index(&index_lock, 1);
	add_remove_files(&partial);
379
	refresh_cache(REFRESH_QUIET);
B
Brandon Casey 已提交
380 381
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&index_lock))
K
Kristian Høgsberg 已提交
382 383
		die("unable to write new_index file");

384
	fd = hold_lock_file_for_update(&false_lock,
J
Junio C Hamano 已提交
385 386
				       git_path("next-index-%"PRIuMAX,
						(uintmax_t) getpid()),
387
				       LOCK_DIE_ON_ERROR);
388 389

	create_base_index();
390
	add_remove_files(&partial);
391
	refresh_cache(REFRESH_QUIET);
K
Kristian Høgsberg 已提交
392

B
Brandon Casey 已提交
393 394
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&false_lock))
395
		die("unable to write temporary index file");
396 397 398 399

	discard_cache();
	read_cache_from(false_lock.filename);

400
	return false_lock.filename;
K
Kristian Høgsberg 已提交
401 402
}

403 404
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
		      struct wt_status *s)
K
Kristian Høgsberg 已提交
405
{
406 407
	unsigned char sha1[20];

408 409
	if (s->relative_paths)
		s->prefix = prefix;
K
Kristian Høgsberg 已提交
410 411

	if (amend) {
412 413
		s->amend = 1;
		s->reference = "HEAD^1";
K
Kristian Høgsberg 已提交
414
	}
415 416 417 418
	s->verbose = verbose;
	s->index_file = index_file;
	s->fp = fp;
	s->nowarn = nowarn;
419
	s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
K
Kristian Høgsberg 已提交
420

421
	wt_status_collect(s);
422 423 424

	switch (status_format) {
	case STATUS_FORMAT_SHORT:
425
		wt_shortstatus_print(s, null_termination);
426 427
		break;
	case STATUS_FORMAT_PORCELAIN:
428
		wt_porcelain_print(s, null_termination);
429 430 431 432 433
		break;
	case STATUS_FORMAT_LONG:
		wt_status_print(s);
		break;
	}
K
Kristian Høgsberg 已提交
434

435
	return s->commitable;
K
Kristian Høgsberg 已提交
436 437
}

438 439 440 441 442 443 444 445
static int is_a_merge(const unsigned char *sha1)
{
	struct commit *commit = lookup_commit(sha1);
	if (!commit || parse_commit(commit))
		die("could not parse HEAD commit");
	return !!(commit->parents && commit->parents->next);
}

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

448
static void determine_author_info(void)
449 450 451 452 453 454 455
{
	char *name, *email, *date;

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

456
	if (use_message && !renew_authorship) {
457 458 459 460 461 462
		const char *a, *lb, *rb, *eol;

		a = strstr(use_message_buffer, "\nauthor ");
		if (!a)
			die("invalid commit: %s", use_message);

463 464 465 466
		lb = strchrnul(a + strlen("\nauthor "), '<');
		rb = strchrnul(lb, '>');
		eol = strchrnul(rb, '\n');
		if (!*lb || !*rb || !*eol)
467 468
			die("invalid commit: %s", use_message);

469 470 471 472 473 474 475 476 477
		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("> ")));
478 479 480 481 482 483 484 485 486 487 488 489
	}

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

		if (!lb || !rb)
			die("malformed --author parameter");
		name = xstrndup(force_author, lb - force_author);
		email = xstrndup(lb + 2, rb - (lb + 2));
	}

M
Miklos Vajna 已提交
490 491 492
	if (force_date)
		date = force_date;

493 494 495
	author_name = name;
	author_email = email;
	author_date = date;
496 497
}

498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
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;
}

539 540
static int prepare_to_commit(const char *index_file, const char *prefix,
			     struct wt_status *s)
K
Kristian Høgsberg 已提交
541 542
{
	struct stat statbuf;
543
	int commitable, saved_color_setting;
544
	struct strbuf sb = STRBUF_INIT;
K
Kristian Høgsberg 已提交
545 546
	char *buffer;
	FILE *fp;
547 548
	const char *hook_arg1 = NULL;
	const char *hook_arg2 = NULL;
549
	int ident_shown = 0;
K
Kristian Høgsberg 已提交
550

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

554 555
	if (message.len) {
		strbuf_addbuf(&sb, &message);
556
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
557 558 559 560
	} else if (logfile && !strcmp(logfile, "-")) {
		if (isatty(0))
			fprintf(stderr, "(reading log message from standard input)\n");
		if (strbuf_read(&sb, 0, 0) < 0)
561
			die_errno("could not read log from standard input");
562
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
563 564
	} else if (logfile) {
		if (strbuf_read_file(&sb, logfile, 0) < 0)
565 566
			die_errno("could not read log file '%s'",
				  logfile);
567
		hook_arg1 = "message";
K
Kristian Høgsberg 已提交
568 569 570 571 572
	} else if (use_message) {
		buffer = strstr(use_message_buffer, "\n\n");
		if (!buffer || buffer[2] == '\0')
			die("commit has empty message");
		strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
573 574
		hook_arg1 = "commit";
		hook_arg2 = use_message;
K
Kristian Høgsberg 已提交
575 576
	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
577
			die_errno("could not read MERGE_MSG");
578
		hook_arg1 = "merge";
K
Kristian Høgsberg 已提交
579 580
	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
581
			die_errno("could not read SQUASH_MSG");
582
		hook_arg1 = "squash";
K
Kristian Høgsberg 已提交
583 584
	} else if (template_file && !stat(template_file, &statbuf)) {
		if (strbuf_read_file(&sb, template_file, 0) < 0)
585
			die_errno("could not read '%s'", template_file);
586
		hook_arg1 = "template";
K
Kristian Høgsberg 已提交
587 588
	}

589 590 591 592 593 594 595
	/*
	 * This final case does not modify the template message,
	 * it just sets the argument to the prepare-commit-msg hook.
	 */
	else if (in_merge)
		hook_arg1 = "merge";

K
Kristian Høgsberg 已提交
596 597
	fp = fopen(git_path(commit_editmsg), "w");
	if (fp == NULL)
598
		die_errno("could not open '%s'", git_path(commit_editmsg));
K
Kristian Høgsberg 已提交
599

600 601
	if (cleanup_mode != CLEANUP_NONE)
		stripspace(&sb, 0);
K
Kristian Høgsberg 已提交
602 603

	if (signoff) {
604
		struct strbuf sob = STRBUF_INIT;
605 606 607
		int i;

		strbuf_addstr(&sob, sign_off_header);
608 609
		strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
					     getenv("GIT_COMMITTER_EMAIL")));
610 611 612
		strbuf_addch(&sob, '\n');
		for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
			; /* do nothing */
613
		if (prefixcmp(sb.buf + i, sob.buf)) {
614
			if (!i || !ends_rfc2822_footer(&sb))
615
				strbuf_addch(&sb, '\n');
616
			strbuf_addbuf(&sb, &sob);
617
		}
618
		strbuf_release(&sob);
K
Kristian Høgsberg 已提交
619 620
	}

621
	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
622
		die_errno("could not write commit template");
623

K
Kristian Høgsberg 已提交
624 625
	strbuf_release(&sb);

626 627
	determine_author_info();

628 629
	/* This checks if committer ident is explicitly given */
	git_committer_info(0);
630
	if (use_editor && include_status) {
631 632 633
		char *author_ident;
		const char *committer_ident;

634 635 636 637 638 639 640 641 642 643 644 645
		if (in_merge)
			fprintf(fp,
				"#\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",
				git_path("MERGE_HEAD"));

		fprintf(fp,
			"\n"
J
Jeff King 已提交
646
			"# Please enter the commit message for your changes.");
647
		if (cleanup_mode == CLEANUP_ALL)
J
Jeff King 已提交
648 649 650 651
			fprintf(fp,
				" Lines starting\n"
				"# with '#' will be ignored, and an empty"
				" message aborts the commit.\n");
652
		else /* CLEANUP_SPACE, that is. */
J
Jeff King 已提交
653 654 655 656 657
			fprintf(fp,
				" Lines starting\n"
				"# with '#' will be kept; you may remove them"
				" yourself if you want to.\n"
				"# An empty message aborts the commit.\n");
658 659 660
		if (only_include_assumed)
			fprintf(fp, "# %s\n", only_include_assumed);

661 662 663 664 665
		author_ident = xstrdup(fmt_name(author_name, author_email));
		committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
					   getenv("GIT_COMMITTER_EMAIL"));
		if (strcmp(author_ident, committer_ident))
			fprintf(fp,
666 667 668
				"%s"
				"# Author:    %s\n",
				ident_shown++ ? "" : "#\n",
669 670 671
				author_ident);
		free(author_ident);

672
		if (!user_ident_sufficiently_given())
673 674 675 676 677 678 679 680 681
			fprintf(fp,
				"%s"
				"# Committer: %s\n",
				ident_shown++ ? "" : "#\n",
				committer_ident);

		if (ident_shown)
			fprintf(fp, "#\n");

682 683 684 685
		saved_color_setting = s->use_color;
		s->use_color = 0;
		commitable = run_status(fp, index_file, prefix, 1, s);
		s->use_color = saved_color_setting;
686
	} else {
687
		unsigned char sha1[20];
688
		const char *parent = "HEAD";
689 690 691 692

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

693 694 695
		if (amend)
			parent = "HEAD^1";

696
		if (get_sha1(parent, sha1))
697
			commitable = !!active_nr;
698 699
		else
			commitable = index_differs_from(parent, 0);
700
	}
701

702
	fclose(fp);
703

704 705
	if (!commitable && !in_merge && !allow_empty &&
	    !(amend && is_a_merge(head_sha1))) {
706
		run_status(stdout, index_file, prefix, 0, s);
J
Jeff King 已提交
707 708
		if (amend)
			fputs(empty_amend_advice, stderr);
709
		return 0;
710 711
	}

712 713 714 715 716 717 718 719 720 721 722
	/*
	 * 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);
	if (!active_cache_tree)
		active_cache_tree = cache_tree();
	if (cache_tree_update(active_cache_tree,
			      active_cache, active_nr, 0, 0) < 0) {
723
		error("Error building trees");
724
		return 0;
725
	}
K
Kristian Høgsberg 已提交
726

727 728 729
	if (run_hook(index_file, "prepare-commit-msg",
		     git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
		return 0;
K
Kristian Høgsberg 已提交
730

731 732 733 734
	if (use_editor) {
		char index[PATH_MAX];
		const char *env[2] = { index, NULL };
		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
S
Stephan Beyer 已提交
735 736 737 738 739
		if (launch_editor(git_path(commit_editmsg), NULL, env)) {
			fprintf(stderr,
			"Please supply the message using either -m or -F option.\n");
			exit(1);
		}
740
	}
K
Kristian Høgsberg 已提交
741

742 743 744 745
	if (!no_verify &&
	    run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
		return 0;
	}
K
Kristian Høgsberg 已提交
746

747
	return 1;
K
Kristian Høgsberg 已提交
748 749 750
}

/*
M
Miklos Vajna 已提交
751 752
 * Find out if the message in the strbuf contains only whitespace and
 * Signed-off-by lines.
K
Kristian Høgsberg 已提交
753
 */
M
Miklos Vajna 已提交
754
static int message_is_empty(struct strbuf *sb)
K
Kristian Høgsberg 已提交
755
{
756
	struct strbuf tmpl = STRBUF_INIT;
K
Kristian Høgsberg 已提交
757
	const char *nl;
M
Miklos Vajna 已提交
758
	int eol, i, start = 0;
K
Kristian Høgsberg 已提交
759

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

K
Kristian Høgsberg 已提交
763 764
	/* See if the template is just a prefix of the message. */
	if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
765
		stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
K
Kristian Høgsberg 已提交
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
		if (start + tmpl.len <= sb->len &&
		    memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
			start += tmpl.len;
	}
	strbuf_release(&tmpl);

	/* 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;
}

793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
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) {
811 812
		struct pretty_print_context ctx = {0};
		ctx.date_mode = DATE_NORMAL;
813
		strbuf_release(&buf);
814
		format_commit_message(commit, "%an <%ae>", &buf, &ctx);
815 816 817 818 819
		return strbuf_detach(&buf, NULL);
	}
	die("No existing author found with '%s'", name);
}

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834

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
		die("Invalid untracked files mode '%s'", untracked_files_arg);
}

835
static int parse_and_validate_options(int argc, const char *argv[],
836
				      const char * const usage[],
837 838
				      const char *prefix,
				      struct wt_status *s)
K
Kristian Høgsberg 已提交
839 840 841
{
	int f = 0;

842 843
	argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
			     0);
K
Kristian Høgsberg 已提交
844

845 846 847
	if (force_author && !strchr(force_author, '>'))
		force_author = find_author_by_nickname(force_author);

848 849 850
	if (force_author && renew_authorship)
		die("Using both --reset-author and --author does not make sense");

851
	if (logfile || message.len || use_message)
852
		use_editor = 0;
K
Kristian Høgsberg 已提交
853
	if (edit_flag)
854
		use_editor = 1;
855 856
	if (!use_editor)
		setenv("GIT_EDITOR", ":", 1);
K
Kristian Høgsberg 已提交
857 858 859 860 861 862 863 864

	if (get_sha1("HEAD", head_sha1))
		initial_commit = 1;

	/* Sanity check options */
	if (amend && initial_commit)
		die("You have nothing to amend.");
	if (amend && in_merge)
J
Jeff King 已提交
865
		die("You are in the middle of a merge -- cannot amend.");
K
Kristian Høgsberg 已提交
866 867 868 869 870 871 872 873 874

	if (use_message)
		f++;
	if (edit_message)
		f++;
	if (logfile)
		f++;
	if (f > 1)
		die("Only one of -c/-C/-F can be used.");
875
	if (message.len && f > 0)
K
Kristian Høgsberg 已提交
876 877 878
		die("Option -m cannot be combined with -c/-C/-F.");
	if (edit_message)
		use_message = edit_message;
879
	if (amend && !use_message)
K
Kristian Høgsberg 已提交
880
		use_message = "HEAD";
881 882
	if (!use_message && renew_authorship)
		die("--reset-author can be used only with -C, -c or --amend.");
K
Kristian Høgsberg 已提交
883 884 885 886 887 888 889 890 891
	if (use_message) {
		unsigned char sha1[20];
		static char utf8[] = "UTF-8";
		const char *out_enc;
		char *enc, *end;
		struct commit *commit;

		if (get_sha1(use_message, sha1))
			die("could not lookup commit %s", use_message);
J
Junio C Hamano 已提交
892
		commit = lookup_commit_reference(sha1);
K
Kristian Høgsberg 已提交
893 894 895 896 897 898 899 900 901 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
		if (!commit || parse_commit(commit))
			die("could not parse commit %s", use_message);

		enc = strstr(commit->buffer, "\nencoding");
		if (enc) {
			end = strchr(enc + 10, '\n');
			enc = xstrndup(enc + 10, end - (enc + 10));
		} else {
			enc = utf8;
		}
		out_enc = git_commit_encoding ? git_commit_encoding : utf8;

		if (strcmp(out_enc, enc))
			use_message_buffer =
				reencode_string(commit->buffer, out_enc, 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 (use_message_buffer == NULL)
			use_message_buffer = xstrdup(commit->buffer);
		if (enc != utf8)
			free(enc);
	}

	if (!!also + !!only + !!all + !!interactive > 1)
		die("Only one of --include/--only/--all/--interactive can be used.");
	if (argc == 0 && (also || (only && !amend)))
		die("No paths with --include/--only does not make sense.");
	if (argc == 0 && only && amend)
		only_include_assumed = "Clever... amending the last one with dirty index.";
927
	if (argc > 0 && !also && !only)
K
Kristian Høgsberg 已提交
928
		only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
929 930 931 932 933 934 935 936 937 938
	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
		die("Invalid cleanup mode %s", cleanup_arg);
K
Kristian Høgsberg 已提交
939

940
	handle_untracked_files_arg(s);
941

K
Kristian Høgsberg 已提交
942 943 944 945 946
	if (all && argc > 0)
		die("Paths with -a does not make sense.");
	else if (interactive && argc > 0)
		die("Paths with --interactive does not make sense.");

947 948 949 950 951
	if (null_termination && status_format == STATUS_FORMAT_LONG)
		status_format = STATUS_FORMAT_PORCELAIN;
	if (status_format != STATUS_FORMAT_LONG)
		dry_run = 1;

K
Kristian Høgsberg 已提交
952 953 954
	return argc;
}

955 956
static int dry_run_commit(int argc, const char **argv, const char *prefix,
			  struct wt_status *s)
K
Kristian Høgsberg 已提交
957 958
{
	int commitable;
J
Junio C Hamano 已提交
959
	const char *index_file;
K
Kristian Høgsberg 已提交
960

J
Junio C Hamano 已提交
961
	index_file = prepare_index(argc, argv, prefix, 1);
962
	commitable = run_status(stdout, index_file, prefix, 0, s);
J
Junio C Hamano 已提交
963
	rollback_index_files();
K
Kristian Høgsberg 已提交
964

J
Junio C Hamano 已提交
965 966 967
	return commitable ? 0 : 1;
}

968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
static int parse_status_slot(const char *var, int offset)
{
	if (!strcasecmp(var+offset, "header"))
		return WT_STATUS_HEADER;
	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 已提交
983
	return -1;
984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
}

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

	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")) {
		s->use_color = git_config_colorbool(k, v, -1);
		return 0;
	}
	if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
		int slot = parse_status_slot(k, 13);
J
Jeff King 已提交
1003 1004
		if (slot < 0)
			return 0;
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
		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
			return error("Invalid untracked files mode '%s'", v);
		return 0;
	}
	return git_diff_ui_config(k, v, NULL);
}

J
Junio C Hamano 已提交
1030 1031
int cmd_status(int argc, const char **argv, const char *prefix)
{
1032
	struct wt_status s;
1033
	int fd;
1034
	unsigned char sha1[20];
1035
	static struct option builtin_status_options[] = {
1036
		OPT__VERBOSE(&verbose),
1037 1038
		OPT_SET_INT('s', "short", &status_format,
			    "show status concisely", STATUS_FORMAT_SHORT),
1039 1040 1041
		OPT_SET_INT(0, "porcelain", &status_format,
			    "show porcelain output format",
			    STATUS_FORMAT_PORCELAIN),
1042 1043
		OPT_BOOLEAN('z', "null", &null_termination,
			    "terminate entries with NUL"),
1044 1045 1046 1047 1048 1049 1050
		{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
		  "mode",
		  "show untracked files, optional modes: all, normal, no. (Default: all)",
		  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
		OPT_END(),
	};

1051
	if (null_termination && status_format == STATUS_FORMAT_LONG)
1052
		status_format = STATUS_FORMAT_PORCELAIN;
1053 1054 1055

	wt_status_prepare(&s);
	git_config(git_status_config, &s);
1056
	in_merge = file_exists(git_path("MERGE_HEAD"));
1057
	argc = parse_options(argc, argv, prefix,
1058 1059
			     builtin_status_options,
			     builtin_status_usage, 0);
1060 1061 1062 1063 1064
	handle_untracked_files_arg(&s);

	if (*argv)
		s.pathspec = get_pathspec(prefix, argv);

1065
	read_cache_preload(s.pathspec);
1066
	refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1067 1068 1069 1070 1071 1072 1073 1074

	fd = hold_locked_index(&index_lock, 0);
	if (0 <= fd) {
		if (!write_cache(fd, active_cache, active_nr))
			commit_locked_index(&index_lock);
		rollback_lock_file(&index_lock);
	}

1075
	s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1076
	s.in_merge = in_merge;
1077 1078
	wt_status_collect(&s);

J
Jeff King 已提交
1079 1080
	if (s.relative_paths)
		s.prefix = prefix;
1081 1082
	if (s.use_color == -1)
		s.use_color = git_use_color_default;
1083 1084 1085
	if (diff_use_color_default == -1)
		diff_use_color_default = git_use_color_default;

1086 1087
	switch (status_format) {
	case STATUS_FORMAT_SHORT:
1088
		wt_shortstatus_print(&s, null_termination);
1089
		break;
1090
	case STATUS_FORMAT_PORCELAIN:
1091
		wt_porcelain_print(&s, null_termination);
1092
		break;
1093
	case STATUS_FORMAT_LONG:
1094 1095
		s.verbose = verbose;
		wt_status_print(&s);
1096
		break;
1097
	}
1098
	return 0;
K
Kristian Høgsberg 已提交
1099 1100 1101 1102 1103 1104
}

static void print_summary(const char *prefix, const unsigned char *sha1)
{
	struct rev_info rev;
	struct commit *commit;
1105
	struct strbuf format = STRBUF_INIT;
J
Jeff King 已提交
1106 1107
	unsigned char junk_sha1[20];
	const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
1108 1109 1110
	struct pretty_print_context pctx = {0};
	struct strbuf author_ident = STRBUF_INIT;
	struct strbuf committer_ident = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1111 1112 1113

	commit = lookup_commit(sha1);
	if (!commit)
J
Jeff King 已提交
1114
		die("couldn't look up newly created commit");
K
Kristian Høgsberg 已提交
1115 1116 1117
	if (!commit || parse_commit(commit))
		die("could not parse newly created commit");

1118 1119 1120 1121 1122 1123 1124 1125
	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);
	}
1126
	if (!user_ident_sufficiently_given()) {
1127 1128
		strbuf_addstr(&format, "\n Committer: ");
		strbuf_addbuf_percentquote(&format, &committer_ident);
1129 1130 1131 1132
		if (advice_implicit_identity) {
			strbuf_addch(&format, '\n');
			strbuf_addstr(&format, implicit_ident_advice);
		}
1133 1134 1135 1136
	}
	strbuf_release(&author_ident);
	strbuf_release(&committer_ident);

K
Kristian Høgsberg 已提交
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
	init_revisions(&rev, prefix);
	setup_revisions(0, NULL, &rev, NULL);

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

	rev.verbose_header = 1;
	rev.show_root_diff = 1;
1147
	get_commit_format(format.buf, &rev);
1148
	rev.always_show_header = 0;
1149 1150 1151
	rev.diffopt.detect_rename = 1;
	rev.diffopt.rename_limit = 100;
	rev.diffopt.break_opt = 0;
1152
	diff_setup_done(&rev.diffopt);
K
Kristian Høgsberg 已提交
1153

1154
	printf("[%s%s ",
J
Jeff King 已提交
1155 1156 1157 1158 1159 1160
		!prefixcmp(head, "refs/heads/") ?
			head + 11 :
			!strcmp(head, "HEAD") ?
				"detached HEAD" :
				head,
		initial_commit ? " (root-commit)" : "");
K
Kristian Høgsberg 已提交
1161

1162
	if (!log_tree_commit(&rev, commit)) {
1163 1164 1165
		rev.always_show_header = 1;
		rev.use_terminator = 1;
		log_tree_commit(&rev, commit);
1166
	}
1167

1168
	strbuf_release(&format);
K
Kristian Høgsberg 已提交
1169 1170
}

1171
static int git_commit_config(const char *k, const char *v, void *cb)
K
Kristian Høgsberg 已提交
1172
{
1173 1174
	struct wt_status *s = cb;

1175
	if (!strcmp(k, "commit.template"))
1176
		return git_config_pathname(&template_file, k, v);
1177 1178 1179 1180
	if (!strcmp(k, "commit.status")) {
		include_status = git_config_bool(k, v);
		return 0;
	}
K
Kristian Høgsberg 已提交
1181

1182
	return git_status_config(k, v, s);
K
Kristian Høgsberg 已提交
1183 1184
}

1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
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 已提交
1219 1220
int cmd_commit(int argc, const char **argv, const char *prefix)
{
1221
	struct strbuf sb = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1222
	const char *index_file, *reflog_msg;
1223
	char *nl, *p;
K
Kristian Høgsberg 已提交
1224 1225
	unsigned char commit_sha1[20];
	struct ref_lock *ref_lock;
M
Miklos Vajna 已提交
1226
	struct commit_list *parents = NULL, **pptr = &parents;
1227 1228
	struct stat statbuf;
	int allow_fast_forward = 1;
1229
	struct wt_status s;
K
Kristian Høgsberg 已提交
1230

1231 1232
	wt_status_prepare(&s);
	git_config(git_commit_config, &s);
1233
	in_merge = file_exists(git_path("MERGE_HEAD"));
1234
	s.in_merge = in_merge;
K
Kristian Høgsberg 已提交
1235

1236 1237 1238 1239
	if (s.use_color == -1)
		s.use_color = git_use_color_default;
	argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
					  prefix, &s);
1240 1241 1242
	if (dry_run) {
		if (diff_use_color_default == -1)
			diff_use_color_default = git_use_color_default;
1243
		return dry_run_commit(argc, argv, prefix, &s);
1244
	}
1245
	index_file = prepare_index(argc, argv, prefix, 0);
K
Kristian Høgsberg 已提交
1246

1247 1248
	/* Set up everything for writing the commit object.  This includes
	   running hooks, writing the trees, and interacting with the user.  */
1249
	if (!prepare_to_commit(index_file, prefix, &s)) {
1250
		rollback_index_files();
K
Kristian Høgsberg 已提交
1251 1252 1253 1254
		return 1;
	}

	/* Determine parents */
1255
	reflog_msg = getenv("GIT_REFLOG_ACTION");
K
Kristian Høgsberg 已提交
1256
	if (initial_commit) {
1257 1258
		if (!reflog_msg)
			reflog_msg = "commit (initial)";
K
Kristian Høgsberg 已提交
1259 1260 1261 1262
	} else if (amend) {
		struct commit_list *c;
		struct commit *commit;

1263 1264
		if (!reflog_msg)
			reflog_msg = "commit (amend)";
K
Kristian Høgsberg 已提交
1265 1266 1267 1268 1269
		commit = lookup_commit(head_sha1);
		if (!commit || parse_commit(commit))
			die("could not parse HEAD commit");

		for (c = commit->parents; c; c = c->next)
M
Miklos Vajna 已提交
1270
			pptr = &commit_list_insert(c->item, pptr)->next;
K
Kristian Høgsberg 已提交
1271
	} else if (in_merge) {
1272
		struct strbuf m = STRBUF_INIT;
K
Kristian Høgsberg 已提交
1273 1274
		FILE *fp;

1275 1276
		if (!reflog_msg)
			reflog_msg = "commit (merge)";
M
Miklos Vajna 已提交
1277
		pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
K
Kristian Høgsberg 已提交
1278 1279
		fp = fopen(git_path("MERGE_HEAD"), "r");
		if (fp == NULL)
1280 1281
			die_errno("could not open '%s' for reading",
				  git_path("MERGE_HEAD"));
1282 1283 1284 1285
		while (strbuf_getline(&m, fp, '\n') != EOF) {
			unsigned char sha1[20];
			if (get_sha1_hex(m.buf, sha1) < 0)
				die("Corrupt MERGE_HEAD file (%s)", m.buf);
M
Miklos Vajna 已提交
1286
			pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1287
		}
K
Kristian Høgsberg 已提交
1288 1289
		fclose(fp);
		strbuf_release(&m);
1290 1291
		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1292
				die_errno("could not read MERGE_MODE");
1293 1294 1295 1296 1297
			if (!strcmp(sb.buf, "no-ff"))
				allow_fast_forward = 0;
		}
		if (allow_fast_forward)
			parents = reduce_heads(parents);
K
Kristian Høgsberg 已提交
1298
	} else {
1299 1300
		if (!reflog_msg)
			reflog_msg = "commit";
M
Miklos Vajna 已提交
1301
		pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
K
Kristian Høgsberg 已提交
1302 1303
	}

1304
	/* Finally, get the commit message */
1305
	strbuf_reset(&sb);
1306
	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1307
		int saved_errno = errno;
1308
		rollback_index_files();
1309
		die("could not read commit message: %s", strerror(saved_errno));
1310
	}
1311 1312

	/* Truncate the message just before the diff, if any. */
1313 1314 1315 1316 1317
	if (verbose) {
		p = strstr(sb.buf, "\ndiff --git ");
		if (p != NULL)
			strbuf_setlen(&sb, p - sb.buf + 1);
	}
1318

1319 1320
	if (cleanup_mode != CLEANUP_NONE)
		stripspace(&sb, cleanup_mode == CLEANUP_ALL);
M
Miklos Vajna 已提交
1321
	if (message_is_empty(&sb)) {
1322
		rollback_index_files();
J
Jeff King 已提交
1323 1324
		fprintf(stderr, "Aborting commit due to empty commit message.\n");
		exit(1);
1325
	}
K
Kristian Høgsberg 已提交
1326

M
Miklos Vajna 已提交
1327 1328 1329
	if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
			fmt_ident(author_name, author_email, author_date,
				IDENT_ERROR_ON_NO_NAME))) {
1330
		rollback_index_files();
K
Kristian Høgsberg 已提交
1331
		die("failed to write commit object");
1332
	}
K
Kristian Høgsberg 已提交
1333 1334 1335 1336 1337

	ref_lock = lock_any_ref_for_update("HEAD",
					   initial_commit ? NULL : head_sha1,
					   0);

M
Miklos Vajna 已提交
1338
	nl = strchr(sb.buf, '\n');
1339 1340 1341 1342 1343 1344
	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 已提交
1345

1346 1347
	if (!ref_lock) {
		rollback_index_files();
K
Kristian Høgsberg 已提交
1348
		die("cannot lock HEAD ref");
1349 1350 1351
	}
	if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
		rollback_index_files();
K
Kristian Høgsberg 已提交
1352
		die("cannot update HEAD ref");
1353
	}
K
Kristian Høgsberg 已提交
1354 1355 1356

	unlink(git_path("MERGE_HEAD"));
	unlink(git_path("MERGE_MSG"));
1357
	unlink(git_path("MERGE_MODE"));
1358
	unlink(git_path("SQUASH_MSG"));
K
Kristian Høgsberg 已提交
1359

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

1365
	rerere(0);
1366
	run_hook(get_index_file(), "post-commit", NULL);
1367
	if (amend && !no_post_rewrite) {
1368 1369 1370 1371 1372 1373
		struct notes_rewrite_cfg *cfg;
		cfg = init_copy_notes_for_rewrite("amend");
		if (cfg) {
			copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
			finish_copy_notes_for_rewrite(cfg);
		}
1374 1375
		run_rewrite_hook(head_sha1, commit_sha1);
	}
K
Kristian Høgsberg 已提交
1376 1377 1378 1379 1380
	if (!quiet)
		print_summary(prefix, commit_sha1);

	return 0;
}