commit.c 43.7 KB
Newer Older
Kristian Høgsberg's avatar
Kristian Høgsberg committed
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"
Kristian Høgsberg's avatar
Kristian Høgsberg committed
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"
29
#include "gpg-interface.h"
Kristian Høgsberg's avatar
Kristian Høgsberg committed
30 31

static const char * const builtin_commit_usage[] = {
Stephan Beyer's avatar
Stephan Beyer committed
32
	"git commit [options] [--] <filepattern>...",
Kristian Høgsberg's avatar
Kristian Høgsberg committed
33 34 35
	NULL
};

36
static const char * const builtin_status_usage[] = {
Stephan Beyer's avatar
Stephan Beyer committed
37
	"git status [options] [--] <filepattern>...",
38 39 40
	NULL
};

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

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

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

static const char *use_message_buffer;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
67
static const char commit_editmsg[] = "COMMIT_EDITMSG";
68 69 70 71 72
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,
73
	COMMIT_PARTIAL
74
} commit_style;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
75

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

92 93 94 95 96 97 98 99 100 101
/*
 * 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,
102
	CLEANUP_ALL
103 104
} cleanup_mode;
static char *cleanup_arg;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
105

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

112 113 114 115
static int null_termination;
static enum {
	STATUS_FORMAT_LONG,
	STATUS_FORMAT_SHORT,
116
	STATUS_FORMAT_PORCELAIN
117
} status_format = STATUS_FORMAT_LONG;
118
static int status_show_branch;
119

120 121 122 123 124 125 126
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);
127
		strbuf_addstr(buf, "\n\n");
128 129 130
	}
	return 0;
}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
131 132

static struct option builtin_commit_options[] = {
133 134
	OPT__QUIET(&quiet, "suppress summary after successful commit"),
	OPT__VERBOSE(&verbose, "show diff in commit message template"),
Kristian Høgsberg's avatar
Kristian Høgsberg committed
135

136
	OPT_GROUP("Commit message options"),
137
	OPT_FILENAME('F', "file", &logfile, "read message from file"),
138 139 140 141 142 143 144
	OPT_STRING(0, "author", &force_author, "author", "override author for commit"),
	OPT_STRING(0, "date", &force_date, "date", "override date for commit"),
	OPT_CALLBACK('m', "message", &message, "message", "commit message", opt_parse_m),
	OPT_STRING('c', "reedit-message", &edit_message, "commit", "reuse and edit message from specified commit"),
	OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
	OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
	OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
145
	OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C/-c/--amend)"),
146
	OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
147
	OPT_FILENAME('t', "template", &template_file, "use specified template file"),
Junio C Hamano's avatar
Junio C Hamano committed
148
	OPT_BOOL('e', "edit", &edit_flag, "force edit of commit"),
149
	OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
150
	OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
151 152
	{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, "key id",
	  "GPG sign commit", PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
153
	/* end commit message options */
Kristian Høgsberg's avatar
Kristian Høgsberg committed
154 155 156 157 158

	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"),
159
	OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
160
	OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
Kristian Høgsberg's avatar
Kristian Høgsberg committed
161
	OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
Junio C Hamano's avatar
Junio C Hamano committed
162
	OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
163 164
	OPT_SET_INT(0, "short", &status_format, "show status concisely",
		    STATUS_FORMAT_SHORT),
165
	OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"),
166
	OPT_SET_INT(0, "porcelain", &status_format,
167
		    "machine-readable output", STATUS_FORMAT_PORCELAIN),
168 169
	OPT_BOOLEAN('z', "null", &null_termination,
		    "terminate entries with NUL"),
Kristian Høgsberg's avatar
Kristian Høgsberg committed
170
	OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
171
	OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
172
	{ 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" },
173
	/* end commit contents options */
Kristian Høgsberg's avatar
Kristian Høgsberg committed
174

175 176 177 178 179 180 181
	{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
	  "ok to record an empty change",
	  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
	{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
	  "ok to record a change with an empty message",
	  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },

Kristian Høgsberg's avatar
Kristian Høgsberg committed
182 183 184
	OPT_END()
};

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
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;
}

static const char *whence_s(void)
{
	char *s = "";

	switch (whence) {
	case FROM_COMMIT:
		break;
	case FROM_MERGE:
		s = "merge";
		break;
	case FROM_CHERRY_PICK:
		s = "cherry-pick";
		break;
	}

	return s;
}

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
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;
	}
}

230
static int commit_index_files(void)
231
{
232 233
	int err = 0;

234 235 236 237
	switch (commit_style) {
	case COMMIT_AS_IS:
		break; /* nothing to do */
	case COMMIT_NORMAL:
238
		err = commit_lock_file(&index_lock);
239 240
		break;
	case COMMIT_PARTIAL:
241
		err = commit_lock_file(&index_lock);
242 243 244
		rollback_lock_file(&false_lock);
		break;
	}
245 246

	return err;
247 248 249 250 251 252
}

/*
 * 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.
 */
253
static int list_paths(struct string_list *list, const char *with_tree,
254 255 256 257 258 259 260 261 262
		      const char *prefix, const char **pattern)
{
	int i;
	char *m;

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

263
	if (with_tree) {
264
		char *max_prefix = common_prefix(pattern);
265 266
		overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : prefix);
		free(max_prefix);
267
	}
268 269 270

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

273
		if (ce->ce_flags & CE_UPDATE)
274
			continue;
275
		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
276
			continue;
277
		item = string_list_insert(list, ce->name);
278 279
		if (ce_skip_worktree(ce))
			item->util = item; /* better a valid pointer than a fake one */
280 281
	}

282
	return report_path_error(m, pattern, prefix);
283 284
}

285
static void add_remove_files(struct string_list *list)
286 287 288
{
	int i;
	for (i = 0; i < list->nr; i++) {
289
		struct stat st;
290
		struct string_list_item *p = &(list->items[i]);
291

292 293
		/* p->util is skip-worktree */
		if (p->util)
294
			continue;
295

296 297
		if (!lstat(p->string, &st)) {
			if (add_to_cache(p->string, &st, 0))
298
				die(_("updating files failed"));
299
		} else
300
			remove_file_from_cache(p->string);
301 302 303
	}
}

304
static void create_base_index(const struct commit *current_head)
305 306 307 308 309
{
	struct tree *tree;
	struct unpack_trees_options opts;
	struct tree_desc t;

310
	if (!current_head) {
311 312 313 314 315 316 317 318
		discard_cache();
		return;
	}

	memset(&opts, 0, sizeof(opts));
	opts.head_idx = 1;
	opts.index_only = 1;
	opts.merge = 1;
319 320
	opts.src_index = &the_index;
	opts.dst_index = &the_index;
321 322

	opts.fn = oneway_merge;
323
	tree = parse_tree_indirect(current_head->object.sha1);
324
	if (!tree)
325
		die(_("failed to unpack HEAD tree object"));
326 327
	parse_tree(tree);
	init_tree_desc(&t, tree->buffer, tree->size);
328 329
	if (unpack_trees(1, &t, &opts))
		exit(128); /* We've already reported the error, finish dying */
330 331
}

332 333 334 335 336 337 338 339 340 341
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");
}

342 343
static char *prepare_index(int argc, const char **argv, const char *prefix,
			   const struct commit *current_head, int is_status)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
344 345
{
	int fd;
346
	struct string_list partial;
347
	const char **pathspec = NULL;
348
	char *old_index_env = NULL;
349
	int refresh_flags = REFRESH_QUIET;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
350

351 352
	if (is_status)
		refresh_flags |= REFRESH_UNMERGED;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
353

354 355
	if (*argv)
		pathspec = get_pathspec(prefix, argv);
356

Linus Torvalds's avatar
Linus Torvalds committed
357
	if (read_cache_preload(pathspec) < 0)
358
		die(_("index file corrupt"));
Linus Torvalds's avatar
Linus Torvalds committed
359

360 361 362 363 364 365 366 367 368 369 370 371
	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);

372
		if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
373 374 375 376 377 378 379 380 381 382 383 384 385 386
			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;
	}

387 388 389 390 391 392 393 394 395 396 397 398 399
	/*
	 * 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)) {
400
		fd = hold_locked_index(&index_lock, 1);
401
		add_files_to_cache(also ? prefix : NULL, pathspec, 0);
402
		refresh_cache_or_die(refresh_flags);
403
		update_main_cache_tree(1);
Brandon Casey's avatar
Brandon Casey committed
404 405
		if (write_cache(fd, active_cache, active_nr) ||
		    close_lock_file(&index_lock))
406
			die(_("unable to write new_index file"));
407 408
		commit_style = COMMIT_NORMAL;
		return index_lock.filename;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
409 410
	}

411 412 413 414 415
	/*
	 * As-is commit.
	 *
	 * (1) return the name of the real index file.
	 *
416 417
	 * The caller should run hooks on the real index,
	 * and create commit from the_index.
418 419 420 421
	 * We still need to refresh the index here.
	 */
	if (!pathspec || !*pathspec) {
		fd = hold_locked_index(&index_lock, 1);
422
		refresh_cache_or_die(refresh_flags);
423
		if (active_cache_changed) {
424
			update_main_cache_tree(1);
425 426
			if (write_cache(fd, active_cache, active_nr) ||
			    commit_locked_index(&index_lock))
427
				die(_("unable to write new_index file"));
428 429 430
		} else {
			rollback_lock_file(&index_lock);
		}
431
		commit_style = COMMIT_AS_IS;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
432 433 434
		return get_index_file();
	}

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
	/*
	 * 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;

456
	if (whence != FROM_COMMIT)
Junio C Hamano's avatar
Junio C Hamano committed
457
		die(_("cannot do a partial commit during a %s."), whence_s());
458 459

	memset(&partial, 0, sizeof(partial));
460
	partial.strdup_strings = 1;
461
	if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
462 463 464 465
		exit(1);

	discard_cache();
	if (read_cache() < 0)
466
		die(_("cannot read the index"));
467 468 469

	fd = hold_locked_index(&index_lock, 1);
	add_remove_files(&partial);
470
	refresh_cache(REFRESH_QUIET);
Brandon Casey's avatar
Brandon Casey committed
471 472
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&index_lock))
473
		die(_("unable to write new_index file"));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
474

475
	fd = hold_lock_file_for_update(&false_lock,
476 477
				       git_path("next-index-%"PRIuMAX,
						(uintmax_t) getpid()),
478
				       LOCK_DIE_ON_ERROR);
479

480
	create_base_index(current_head);
481
	add_remove_files(&partial);
482
	refresh_cache(REFRESH_QUIET);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
483

Brandon Casey's avatar
Brandon Casey committed
484 485
	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&false_lock))
486
		die(_("unable to write temporary index file"));
487 488 489 490

	discard_cache();
	read_cache_from(false_lock.filename);

491
	return false_lock.filename;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
492 493
}

494 495
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
		      struct wt_status *s)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
496
{
497 498
	unsigned char sha1[20];

499 500
	if (s->relative_paths)
		s->prefix = prefix;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
501 502

	if (amend) {
503 504
		s->amend = 1;
		s->reference = "HEAD^1";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
505
	}
506 507 508 509
	s->verbose = verbose;
	s->index_file = index_file;
	s->fp = fp;
	s->nowarn = nowarn;
510
	s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
511

512
	wt_status_collect(s);
513 514 515

	switch (status_format) {
	case STATUS_FORMAT_SHORT:
516
		wt_shortstatus_print(s, null_termination, status_show_branch);
517 518
		break;
	case STATUS_FORMAT_PORCELAIN:
519
		wt_porcelain_print(s, null_termination);
520 521 522 523 524
		break;
	case STATUS_FORMAT_LONG:
		wt_status_print(s);
		break;
	}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
525

526
	return s->commitable;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
527 528
}

529
static int is_a_merge(const struct commit *current_head)
530
{
531
	return !!(current_head->parents && current_head->parents->next);
532 533
}

Kristian Høgsberg's avatar
Kristian Høgsberg committed
534 535
static const char sign_off_header[] = "Signed-off-by: ";

536
static void determine_author_info(struct strbuf *author_ident)
537 538 539 540 541 542 543
{
	char *name, *email, *date;

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

544
	if (author_message) {
545 546
		const char *a, *lb, *rb, *eol;

547
		a = strstr(author_message_buffer, "\nauthor ");
548
		if (!a)
Junio C Hamano's avatar
Junio C Hamano committed
549
			die(_("invalid commit: %s"), author_message);
550

551 552 553 554
		lb = strchrnul(a + strlen("\nauthor "), '<');
		rb = strchrnul(lb, '>');
		eol = strchrnul(rb, '\n');
		if (!*lb || !*rb || !*eol)
Junio C Hamano's avatar
Junio C Hamano committed
555
			die(_("invalid commit: %s"), author_message);
556

557 558 559 560 561 562 563 564 565
		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("> ")));
566 567 568 569 570 571 572
	}

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

		if (!lb || !rb)
573
			die(_("malformed --author parameter"));
574 575 576 577
		name = xstrndup(force_author, lb - force_author);
		email = xstrndup(lb + 2, rb - (lb + 2));
	}

578 579
	if (force_date)
		date = force_date;
580 581
	strbuf_addstr(author_ident, fmt_ident(name, email, date,
					      IDENT_ERROR_ON_NO_NAME));
582 583
}

584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
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;
}

625 626 627 628
static char *cut_ident_timestamp_part(char *string)
{
	char *ket = strrchr(string, '>');
	if (!ket || ket[1] != ' ')
629
		die(_("Malformed ident string: '%s'"), string);
630 631 632 633
	*++ket = '\0';
	return ket;
}

634
static int prepare_to_commit(const char *index_file, const char *prefix,
635
			     struct commit *current_head,
636 637
			     struct wt_status *s,
			     struct strbuf *author_ident)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
638 639
{
	struct stat statbuf;
640
	struct strbuf committer_ident = STRBUF_INIT;
641
	int commitable, saved_color_setting;
642
	struct strbuf sb = STRBUF_INIT;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
643
	char *buffer;
644 645
	const char *hook_arg1 = NULL;
	const char *hook_arg2 = NULL;
646
	int ident_shown = 0;
647
	int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
648

649 650
	if (!no_verify && run_hook(index_file, "pre-commit", NULL))
		return 0;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
651

652 653 654 655 656 657 658 659 660 661 662 663
	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)
664
				die(_("could not lookup commit %s"), squash_message);
665 666 667 668 669 670
			ctx.output_encoding = get_commit_output_encoding();
			format_commit_message(c, "squash! %s\n\n", &sb,
					      &ctx);
		}
	}

671 672
	if (message.len) {
		strbuf_addbuf(&sb, &message);
673
		hook_arg1 = "message";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
674 675
	} else if (logfile && !strcmp(logfile, "-")) {
		if (isatty(0))
676
			fprintf(stderr, _("(reading log message from standard input)\n"));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
677
		if (strbuf_read(&sb, 0, 0) < 0)
678
			die_errno(_("could not read log from standard input"));
679
		hook_arg1 = "message";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
680 681
	} else if (logfile) {
		if (strbuf_read_file(&sb, logfile, 0) < 0)
682
			die_errno(_("could not read log file '%s'"),
683
				  logfile);
684
		hook_arg1 = "message";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
685 686 687
	} else if (use_message) {
		buffer = strstr(use_message_buffer, "\n\n");
		if (!buffer || buffer[2] == '\0')
688
			die(_("commit has empty message"));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
689
		strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
690 691
		hook_arg1 = "commit";
		hook_arg2 = use_message;
692 693 694 695 696
	} else if (fixup_message) {
		struct pretty_print_context ctx = {0};
		struct commit *commit;
		commit = lookup_commit_reference_by_name(fixup_message);
		if (!commit)
697
			die(_("could not lookup commit %s"), fixup_message);
698 699 700 701
		ctx.output_encoding = get_commit_output_encoding();
		format_commit_message(commit, "fixup! %s\n\n",
				      &sb, &ctx);
		hook_arg1 = "message";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
702 703
	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
704
			die_errno(_("could not read MERGE_MSG"));
705
		hook_arg1 = "merge";
Kristian Høgsberg's avatar
Kristian Høgsberg committed
706 707
	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
708
			die_errno(_("could not read SQUASH_MSG"));
709
		hook_arg1 = "squash";
710
	} else if (template_file) {
Kristian Høgsberg's avatar
Kristian Høgsberg committed
711
		if (strbuf_read_file(&sb, template_file, 0) < 0)
712
			die_errno(_("could not read '%s'"), template_file);
713
		hook_arg1 = "template";
714
		clean_message_contents = 0;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
715 716
	}

717
	/*
718 719
	 * The remaining cases don't modify the template message, but
	 * just set the argument(s) to the prepare-commit-msg hook.
720
	 */
721
	else if (whence == FROM_MERGE)
722
		hook_arg1 = "merge";
723 724 725 726
	else if (whence == FROM_CHERRY_PICK) {
		hook_arg1 = "commit";
		hook_arg2 = "CHERRY_PICK_HEAD";
	}
727

728 729 730 731 732 733 734 735 736 737
	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 = "";
	}

738 739
	s->fp = fopen(git_path(commit_editmsg), "w");
	if (s->fp == NULL)
740
		die_errno(_("could not open '%s'"), git_path(commit_editmsg));
Kristian Høgsberg's avatar
Kristian Høgsberg committed
741

742
	if (clean_message_contents)
743
		stripspace(&sb, 0);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
744 745

	if (signoff) {
746
		struct strbuf sob = STRBUF_INIT;
747 748 749
		int i;

		strbuf_addstr(&sob, sign_off_header);
750 751
		strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
					     getenv("GIT_COMMITTER_EMAIL")));
752 753 754
		strbuf_addch(&sob, '\n');
		for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
			; /* do nothing */
755
		if (prefixcmp(sb.buf + i, sob.buf)) {
756
			if (!i || !ends_rfc2822_footer(&sb))
757
				strbuf_addch(&sb, '\n');
758
			strbuf_addbuf(&sb, &sob);
759
		}
760
		strbuf_release(&sob);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
761 762
	}

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

Kristian Høgsberg's avatar
Kristian Høgsberg committed
766 767
	strbuf_release(&sb);

768 769
	/* This checks and barfs if author is badly specified */
	determine_author_info(author_ident);
770

771
	/* This checks if committer ident is explicitly given */
772
	strbuf_addstr(&committer_ident, git_committer_info(0));
773
	if (use_editor && include_status) {
774
		char *ai_tmp, *ci_tmp;
775
		if (whence != FROM_COMMIT)
776
			status_printf_ln(s, GIT_COLOR_NORMAL,
777
				_("\n"
778
				"It looks like you may be committing a %s.\n"
779 780 781
				"If this is not correct, please remove the file\n"
				"	%s\n"
				"and try again.\n"
782
				""),
783 784 785 786
				whence_s(),
				git_path(whence == FROM_MERGE
					 ? "MERGE_HEAD"
					 : "CHERRY_PICK_HEAD"));
787

788 789
		fprintf(s->fp, "\n");
		status_printf(s, GIT_COLOR_NORMAL,
790
			_("Please enter the commit message for your changes."));
791
		if (cleanup_mode == CLEANUP_ALL)
792
			status_printf_more(s, GIT_COLOR_NORMAL,
793
				_(" Lines starting\n"
794
				"with '#' will be ignored, and an empty"
795
				" message aborts the commit.\n"));
796
		else /* CLEANUP_SPACE, that is. */
797
			status_printf_more(s, GIT_COLOR_NORMAL,
798
				_(" Lines starting\n"
799
				"with '#' will be kept; you may remove them"
Jeff King's avatar
Jeff King committed
800
				" yourself if you want to.\n"
801
				"An empty message aborts the commit.\n"));
802
		if (only_include_assumed)
803 804
			status_printf_ln(s, GIT_COLOR_NORMAL,
					"%s", only_include_assumed);
805

806 807 808
		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))
809
			status_printf_ln(s, GIT_COLOR_NORMAL,
810 811
				_("%s"
				"Author:    %s"),
812
				ident_shown++ ? "" : "\n",
813
				author_ident->buf);
814

815
		if (!user_ident_sufficiently_given())
816
			status_printf_ln(s, GIT_COLOR_NORMAL,
817 818
				_("%s"
				"Committer: %s"),
819
				ident_shown++ ? "" : "\n",
820
				committer_ident.buf);
821 822

		if (ident_shown)
823
			status_printf_ln(s, GIT_COLOR_NORMAL, "");
824

825 826
		saved_color_setting = s->use_color;
		s->use_color = 0;
827
		commitable = run_status(s->fp, index_file, prefix, 1, s);
828
		s->use_color = saved_color_setting;
829 830 831

		*ai_tmp = ' ';
		*ci_tmp = ' ';
832
	} else {
833
		unsigned char sha1[20];
834
		const char *parent = "HEAD";
835 836

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

839 840 841
		if (amend)
			parent = "HEAD^1";

842
		if (get_sha1(parent, sha1))
843
			commitable = !!active_nr;
844 845
		else
			commitable = index_differs_from(parent, 0);
846
	}
847
	strbuf_release(&committer_ident);
848

849
	fclose(s->fp);
850

851 852 853 854 855 856
	/*
	 * 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 &&
857
	    !(amend && is_a_merge(current_head))) {
858
		run_status(stdout, index_file, prefix, 0, s);
859
		if (amend)
860
			fputs(_(empty_amend_advice), stderr);
861
		else if (whence == FROM_CHERRY_PICK)
Junio C Hamano's avatar
Junio C Hamano committed
862
			fputs(_(empty_cherry_pick_advice), stderr);
863
		return 0;
864 865
	}

866 867 868 869 870 871 872
	/*
	 * 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);
873
	if (update_main_cache_tree(0)) {
874
		error(_("Error building trees"));
875
		return 0;
876
	}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
877

878 879 880
	if (run_hook(index_file, "prepare-commit-msg",
		     git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
		return 0;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
881

882 883
	if (use_editor) {
		char index[PATH_MAX];
884 885
		const char *env[2] = { NULL };
		env[0] =  index;
886
		snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
887 888
		if (launch_editor(git_path(commit_editmsg), NULL, env)) {
			fprintf(stderr,
889
			_("Please supply the message using either -m or -F option.\n"));
890 891
			exit(1);
		}
892
	}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
893

894 895 896 897
	if (!no_verify &&
	    run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
		return 0;
	}
Kristian Høgsberg's avatar
Kristian Høgsberg committed
898

899
	return 1;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
900 901 902
}

/*
903 904
 * Find out if the message in the strbuf contains only whitespace and
 * Signed-off-by lines.
Kristian Høgsberg's avatar
Kristian Høgsberg committed
905
 */
906
static int message_is_empty(struct strbuf *sb)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
907
{
908
	struct strbuf tmpl = STRBUF_INIT;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
909
	const char *nl;
910
	int eol, i, start = 0;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
911

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

Kristian Høgsberg's avatar
Kristian Høgsberg committed
915 916
	/* See if the template is just a prefix of the message. */
	if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
917
		stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
		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;
}

945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
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) {
963 964
		struct pretty_print_context ctx = {0};
		ctx.date_mode = DATE_NORMAL;
965
		strbuf_release(&buf);
966
		format_commit_message(commit, "%an <%ae>", &buf, &ctx);
967 968
		return strbuf_detach(&buf, NULL);
	}
969
	die(_("No existing author found with '%s'"), name);
970 971
}

972 973 974 975 976 977 978 979 980 981 982 983

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

987 988 989 990 991 992 993
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)
Junio C Hamano's avatar
Junio C Hamano committed
994
		die(_("could not lookup commit %s"), name);
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
	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;
}

1009
static int parse_and_validate_options(int argc, const char *argv[],
1010
				      const char * const usage[],
1011
				      const char *prefix,
1012
				      struct commit *current_head,
1013
				      struct wt_status *s)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1014 1015 1