]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/commit.c
Do not strip empty lines / trailing spaces from a commit message template
[thirdparty/git.git] / builtin / commit.c
CommitLineData
f5bbc322
KH
1/*
2 * Builtin "git commit"
3 *
4 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
5 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
6 */
7
8#include "cache.h"
9#include "cache-tree.h"
6b2f2d98 10#include "color.h"
2888605c 11#include "dir.h"
f5bbc322
KH
12#include "builtin.h"
13#include "diff.h"
14#include "diffcore.h"
15#include "commit.h"
16#include "revision.h"
17#include "wt-status.h"
18#include "run-command.h"
19#include "refs.h"
20#include "log-tree.h"
21#include "strbuf.h"
22#include "utf8.h"
23#include "parse-options.h"
c455c87c 24#include "string-list.h"
5b2fd956 25#include "rerere.h"
fa9dcf80 26#include "unpack-trees.h"
76e2f7ce 27#include "quote.h"
302ad7a9 28#include "submodule.h"
f5bbc322
KH
29
30static const char * const builtin_commit_usage[] = {
1b1dd23f 31 "git commit [options] [--] <filepattern>...",
f5bbc322
KH
32 NULL
33};
34
2f02b25f 35static const char * const builtin_status_usage[] = {
1b1dd23f 36 "git status [options] [--] <filepattern>...",
2f02b25f
SB
37 NULL
38};
39
49ff9a7a 40static const char implicit_ident_advice[] =
fc88e316 41N_("Your name and email address were configured automatically based\n"
49ff9a7a
JK
42"on your username and hostname. Please check that they are accurate.\n"
43"You can suppress this message by setting them explicitly:\n"
44"\n"
8bb45b25 45" git config --global user.name \"Your Name\"\n"
49ff9a7a
JK
46" git config --global user.email you@example.com\n"
47"\n"
3f142468 48"After doing this, you may fix the identity used for this commit with:\n"
49ff9a7a 49"\n"
fc88e316 50" git commit --amend --reset-author\n");
49ff9a7a 51
f197ed2f 52static const char empty_amend_advice[] =
fc88e316 53N_("You asked to amend the most recent commit, but doing so would make\n"
f197ed2f 54"it empty. You can repeat your command with --allow-empty, or you can\n"
fc88e316 55"remove the commit entirely with \"git reset HEAD^\".\n");
f197ed2f 56
37f7a857 57static const char empty_cherry_pick_advice[] =
6c80cd29 58N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
37f7a857
JS
59"If you wish to commit it anyway, use:\n"
60"\n"
61" git commit --allow-empty\n"
62"\n"
6c80cd29 63"Otherwise, please use 'git reset'\n");
37f7a857 64
30988301 65static unsigned char head_sha1[20];
49ff9a7a 66
37f7a857 67static const char *use_message_buffer;
f5bbc322 68static const char commit_editmsg[] = "COMMIT_EDITMSG";
2888605c
JH
69static struct lock_file index_lock; /* real index */
70static struct lock_file false_lock; /* used only for partial commits */
71static enum {
72 COMMIT_AS_IS = 1,
73 COMMIT_NORMAL,
4b05548f 74 COMMIT_PARTIAL
2888605c 75} commit_style;
f5bbc322 76
dbd0f5c7 77static const char *logfile, *force_author;
984c6e7e 78static const char *template_file;
37f7a857
JS
79/*
80 * The _message variables are commit names from which to take
81 * the commit message and/or authorship.
82 */
83static const char *author_message, *author_message_buffer;
f5bbc322 84static char *edit_message, *use_message;
89ac1223 85static char *fixup_message, *squash_message;
f5bbc322 86static int all, edit_flag, also, interactive, only, amend, signoff;
c51f6cee 87static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
c9b5fde7 88static int no_post_rewrite, allow_empty_message;
46a958b3 89static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
5f065737
AR
90/*
91 * The default commit message cleanup mode will remove the lines
92 * beginning with # (shell comments) and leading and trailing
93 * whitespaces (empty lines or containing only whitespaces)
94 * if editor is used, and only the whitespaces if the message
95 * is specified explicitly.
96 */
97static enum {
98 CLEANUP_SPACE,
99 CLEANUP_NONE,
4b05548f 100 CLEANUP_ALL
5f065737
AR
101} cleanup_mode;
102static char *cleanup_arg;
f5bbc322 103
37f7a857
JS
104static enum commit_whence whence;
105static int use_editor = 1, initial_commit, include_status = 1;
2381e39e 106static int show_ignored_in_status;
3b6aeb3c
JS
107static const char *only_include_assumed;
108static struct strbuf message;
f9568530 109
7c9f7038
JK
110static int null_termination;
111static enum {
112 STATUS_FORMAT_LONG,
113 STATUS_FORMAT_SHORT,
4b05548f 114 STATUS_FORMAT_PORCELAIN
7c9f7038 115} status_format = STATUS_FORMAT_LONG;
05a59a08 116static int status_show_branch;
7c9f7038 117
f9568530
JS
118static int opt_parse_m(const struct option *opt, const char *arg, int unset)
119{
120 struct strbuf *buf = opt->value;
121 if (unset)
122 strbuf_setlen(buf, 0);
123 else {
124 strbuf_addstr(buf, arg);
3b6aeb3c 125 strbuf_addstr(buf, "\n\n");
f9568530
JS
126 }
127 return 0;
128}
f5bbc322
KH
129
130static struct option builtin_commit_options[] = {
8c839683
JN
131 OPT__QUIET(&quiet, "suppress summary after successful commit"),
132 OPT__VERBOSE(&verbose, "show diff in commit message template"),
f5bbc322 133
e97ca7f4 134 OPT_GROUP("Commit message options"),
726c4e3d 135 OPT_FILENAME('F', "file", &logfile, "read message from file"),
23c6a803
MG
136 OPT_STRING(0, "author", &force_author, "author", "override author for commit"),
137 OPT_STRING(0, "date", &force_date, "date", "override date for commit"),
138 OPT_CALLBACK('m', "message", &message, "message", "commit message", opt_parse_m),
139 OPT_STRING('c', "reedit-message", &edit_message, "commit", "reuse and edit message from specified commit"),
140 OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
141 OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
142 OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
c51f6cee 143 OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
362b0dd5 144 OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
df217ed6 145 OPT_FILENAME('t', "template", &template_file, "use specified template file"),
f5bbc322 146 OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
e97ca7f4 147 OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
bed575e4 148 OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
e97ca7f4 149 /* end commit message options */
f5bbc322
KH
150
151 OPT_GROUP("Commit contents options"),
152 OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
153 OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
154 OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
d4ba07ca 155 OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
f5bbc322 156 OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
3a5d13a3 157 OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
7c9f7038
JK
158 OPT_SET_INT(0, "short", &status_format, "show status concisely",
159 STATUS_FORMAT_SHORT),
05a59a08 160 OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"),
7c9f7038 161 OPT_SET_INT(0, "porcelain", &status_format,
ba9d7fe1 162 "machine-readable output", STATUS_FORMAT_PORCELAIN),
7c9f7038
JK
163 OPT_BOOLEAN('z', "null", &null_termination,
164 "terminate entries with NUL"),
f5bbc322 165 OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
6f6bee3b 166 OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
8547090c 167 { 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" },
e97ca7f4 168 /* end commit contents options */
f5bbc322 169
c9b5fde7
ÆAB
170 { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
171 "ok to record an empty change",
172 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
173 { OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
174 "ok to record a change with an empty message",
175 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
176
f5bbc322
KH
177 OPT_END()
178};
179
37f7a857
JS
180static void determine_whence(struct wt_status *s)
181{
182 if (file_exists(git_path("MERGE_HEAD")))
183 whence = FROM_MERGE;
184 else if (file_exists(git_path("CHERRY_PICK_HEAD")))
185 whence = FROM_CHERRY_PICK;
186 else
187 whence = FROM_COMMIT;
188 if (s)
189 s->whence = whence;
190}
191
192static const char *whence_s(void)
193{
194 char *s = "";
195
196 switch (whence) {
197 case FROM_COMMIT:
198 break;
199 case FROM_MERGE:
200 s = "merge";
201 break;
202 case FROM_CHERRY_PICK:
203 s = "cherry-pick";
204 break;
205 }
206
207 return s;
208}
209
2888605c
JH
210static void rollback_index_files(void)
211{
212 switch (commit_style) {
213 case COMMIT_AS_IS:
214 break; /* nothing to do */
215 case COMMIT_NORMAL:
216 rollback_lock_file(&index_lock);
217 break;
218 case COMMIT_PARTIAL:
219 rollback_lock_file(&index_lock);
220 rollback_lock_file(&false_lock);
221 break;
222 }
223}
224
5a9dd399 225static int commit_index_files(void)
2888605c 226{
5a9dd399
BC
227 int err = 0;
228
2888605c
JH
229 switch (commit_style) {
230 case COMMIT_AS_IS:
231 break; /* nothing to do */
232 case COMMIT_NORMAL:
5a9dd399 233 err = commit_lock_file(&index_lock);
2888605c
JH
234 break;
235 case COMMIT_PARTIAL:
5a9dd399 236 err = commit_lock_file(&index_lock);
2888605c
JH
237 rollback_lock_file(&false_lock);
238 break;
239 }
5a9dd399
BC
240
241 return err;
2888605c
JH
242}
243
244/*
245 * Take a union of paths in the index and the named tree (typically, "HEAD"),
246 * and return the paths that match the given pattern in list.
247 */
c455c87c 248static int list_paths(struct string_list *list, const char *with_tree,
2888605c
JH
249 const char *prefix, const char **pattern)
250{
251 int i;
252 char *m;
253
254 for (i = 0; pattern[i]; i++)
255 ;
256 m = xcalloc(1, i);
257
258 if (with_tree)
259 overlay_tree_on_cache(with_tree, prefix);
260
261 for (i = 0; i < active_nr; i++) {
262 struct cache_entry *ce = active_cache[i];
7fce6e3c
NTND
263 struct string_list_item *item;
264
7a51ed66 265 if (ce->ce_flags & CE_UPDATE)
e87e22d0 266 continue;
0b50922a 267 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
2888605c 268 continue;
78a395d3 269 item = string_list_insert(list, ce->name);
7fce6e3c
NTND
270 if (ce_skip_worktree(ce))
271 item->util = item; /* better a valid pointer than a fake one */
2888605c
JH
272 }
273
274 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
275}
276
c455c87c 277static void add_remove_files(struct string_list *list)
2888605c
JH
278{
279 int i;
280 for (i = 0; i < list->nr; i++) {
d177cab0 281 struct stat st;
c455c87c 282 struct string_list_item *p = &(list->items[i]);
d177cab0 283
7fce6e3c
NTND
284 /* p->util is skip-worktree */
285 if (p->util)
b4d1690d 286 continue;
d177cab0 287
c455c87c
JS
288 if (!lstat(p->string, &st)) {
289 if (add_to_cache(p->string, &st, 0))
8a6179bc 290 die(_("updating files failed"));
960b8ad1 291 } else
c455c87c 292 remove_file_from_cache(p->string);
2888605c
JH
293 }
294}
295
fa9dcf80
LT
296static void create_base_index(void)
297{
298 struct tree *tree;
299 struct unpack_trees_options opts;
300 struct tree_desc t;
301
302 if (initial_commit) {
303 discard_cache();
304 return;
305 }
306
307 memset(&opts, 0, sizeof(opts));
308 opts.head_idx = 1;
309 opts.index_only = 1;
310 opts.merge = 1;
34110cd4
LT
311 opts.src_index = &the_index;
312 opts.dst_index = &the_index;
fa9dcf80
LT
313
314 opts.fn = oneway_merge;
315 tree = parse_tree_indirect(head_sha1);
316 if (!tree)
8a6179bc 317 die(_("failed to unpack HEAD tree object"));
fa9dcf80
LT
318 parse_tree(tree);
319 init_tree_desc(&t, tree->buffer, tree->size);
203a2fe1
DB
320 if (unpack_trees(1, &t, &opts))
321 exit(128); /* We've already reported the error, finish dying */
fa9dcf80
LT
322}
323
d38a30df
MM
324static void refresh_cache_or_die(int refresh_flags)
325{
326 /*
327 * refresh_flags contains REFRESH_QUIET, so the only errors
328 * are for unmerged entries.
329 */
330 if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
331 die_resolve_conflict("commit");
332}
333
50b7e70f 334static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
f5bbc322
KH
335{
336 int fd;
c455c87c 337 struct string_list partial;
2888605c 338 const char **pathspec = NULL;
50b7e70f 339 int refresh_flags = REFRESH_QUIET;
f5bbc322 340
50b7e70f
JH
341 if (is_status)
342 refresh_flags |= REFRESH_UNMERGED;
f5bbc322 343 if (interactive) {
4f6a32f8 344 if (interactive_add(argc, argv, prefix) != 0)
8a6179bc 345 die(_("interactive add failed"));
671c9b7e 346 if (read_cache_preload(NULL) < 0)
8a6179bc 347 die(_("index file corrupt"));
2888605c 348 commit_style = COMMIT_AS_IS;
f5bbc322
KH
349 return get_index_file();
350 }
351
f64fe7b4
JH
352 if (*argv)
353 pathspec = get_pathspec(prefix, argv);
2888605c 354
671c9b7e 355 if (read_cache_preload(pathspec) < 0)
8a6179bc 356 die(_("index file corrupt"));
671c9b7e 357
2888605c
JH
358 /*
359 * Non partial, non as-is commit.
360 *
361 * (1) get the real index;
362 * (2) update the_index as necessary;
363 * (3) write the_index out to the real index (still locked);
364 * (4) return the name of the locked index file.
365 *
366 * The caller should run hooks on the locked real index, and
367 * (A) if all goes well, commit the real index;
368 * (B) on failure, rollback the real index.
369 */
370 if (all || (also && pathspec && *pathspec)) {
1f2362a9 371 fd = hold_locked_index(&index_lock, 1);
7ae02a30 372 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
d38a30df 373 refresh_cache_or_die(refresh_flags);
4ed7cd3a
BC
374 if (write_cache(fd, active_cache, active_nr) ||
375 close_lock_file(&index_lock))
8a6179bc 376 die(_("unable to write new_index file"));
2888605c
JH
377 commit_style = COMMIT_NORMAL;
378 return index_lock.filename;
f5bbc322
KH
379 }
380
2888605c
JH
381 /*
382 * As-is commit.
383 *
384 * (1) return the name of the real index file.
385 *
73276235
MH
386 * The caller should run hooks on the real index,
387 * and create commit from the_index.
2888605c
JH
388 * We still need to refresh the index here.
389 */
390 if (!pathspec || !*pathspec) {
391 fd = hold_locked_index(&index_lock, 1);
d38a30df 392 refresh_cache_or_die(refresh_flags);
d5f5d0a9
JH
393 if (active_cache_changed) {
394 if (write_cache(fd, active_cache, active_nr) ||
395 commit_locked_index(&index_lock))
8a6179bc 396 die(_("unable to write new_index file"));
d5f5d0a9
JH
397 } else {
398 rollback_lock_file(&index_lock);
399 }
2888605c 400 commit_style = COMMIT_AS_IS;
f5bbc322
KH
401 return get_index_file();
402 }
403
2888605c
JH
404 /*
405 * A partial commit.
406 *
407 * (0) find the set of affected paths;
408 * (1) get lock on the real index file;
409 * (2) update the_index with the given paths;
410 * (3) write the_index out to the real index (still locked);
411 * (4) get lock on the false index file;
412 * (5) reset the_index from HEAD;
413 * (6) update the_index the same way as (2);
414 * (7) write the_index out to the false index file;
415 * (8) return the name of the false index file (still locked);
416 *
417 * The caller should run hooks on the locked false index, and
418 * create commit from it. Then
419 * (A) if all goes well, commit the real index;
420 * (B) on failure, rollback the real index;
421 * In either case, rollback the false index.
422 */
423 commit_style = COMMIT_PARTIAL;
424
37f7a857 425 if (whence != FROM_COMMIT)
6c80cd29 426 die(_("cannot do a partial commit during a %s."), whence_s());
2888605c
JH
427
428 memset(&partial, 0, sizeof(partial));
c455c87c 429 partial.strdup_strings = 1;
2888605c
JH
430 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
431 exit(1);
432
433 discard_cache();
434 if (read_cache() < 0)
8a6179bc 435 die(_("cannot read the index"));
2888605c
JH
436
437 fd = hold_locked_index(&index_lock, 1);
438 add_remove_files(&partial);
ef12b50d 439 refresh_cache(REFRESH_QUIET);
4ed7cd3a
BC
440 if (write_cache(fd, active_cache, active_nr) ||
441 close_lock_file(&index_lock))
8a6179bc 442 die(_("unable to write new_index file"));
f5bbc322 443
2888605c 444 fd = hold_lock_file_for_update(&false_lock,
a157400c
JH
445 git_path("next-index-%"PRIuMAX,
446 (uintmax_t) getpid()),
acd3b9ec 447 LOCK_DIE_ON_ERROR);
fa9dcf80
LT
448
449 create_base_index();
2888605c 450 add_remove_files(&partial);
d37d3203 451 refresh_cache(REFRESH_QUIET);
f5bbc322 452
4ed7cd3a
BC
453 if (write_cache(fd, active_cache, active_nr) ||
454 close_lock_file(&false_lock))
8a6179bc 455 die(_("unable to write temporary index file"));
959ba670
JK
456
457 discard_cache();
458 read_cache_from(false_lock.filename);
459
2888605c 460 return false_lock.filename;
f5bbc322
KH
461}
462
d249b098
JH
463static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
464 struct wt_status *s)
f5bbc322 465{
76e2f7ce
JH
466 unsigned char sha1[20];
467
d249b098
JH
468 if (s->relative_paths)
469 s->prefix = prefix;
f5bbc322
KH
470
471 if (amend) {
d249b098
JH
472 s->amend = 1;
473 s->reference = "HEAD^1";
f5bbc322 474 }
d249b098
JH
475 s->verbose = verbose;
476 s->index_file = index_file;
477 s->fp = fp;
478 s->nowarn = nowarn;
76e2f7ce 479 s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
f5bbc322 480
76e2f7ce 481 wt_status_collect(s);
7c9f7038
JK
482
483 switch (status_format) {
484 case STATUS_FORMAT_SHORT:
05a59a08 485 wt_shortstatus_print(s, null_termination, status_show_branch);
7c9f7038
JK
486 break;
487 case STATUS_FORMAT_PORCELAIN:
4a7cc2fd 488 wt_porcelain_print(s, null_termination);
7c9f7038
JK
489 break;
490 case STATUS_FORMAT_LONG:
491 wt_status_print(s);
492 break;
493 }
f5bbc322 494
d249b098 495 return s->commitable;
f5bbc322
KH
496}
497
ec84bd00
PB
498static int is_a_merge(const unsigned char *sha1)
499{
500 struct commit *commit = lookup_commit(sha1);
501 if (!commit || parse_commit(commit))
8a6179bc 502 die(_("could not parse HEAD commit"));
ec84bd00
PB
503 return !!(commit->parents && commit->parents->next);
504}
505
f5bbc322
KH
506static const char sign_off_header[] = "Signed-off-by: ";
507
4c28e4ad 508static void determine_author_info(struct strbuf *author_ident)
a45d46ba
SB
509{
510 char *name, *email, *date;
511
512 name = getenv("GIT_AUTHOR_NAME");
513 email = getenv("GIT_AUTHOR_EMAIL");
514 date = getenv("GIT_AUTHOR_DATE");
515
37f7a857 516 if (author_message) {
a45d46ba
SB
517 const char *a, *lb, *rb, *eol;
518
37f7a857 519 a = strstr(author_message_buffer, "\nauthor ");
a45d46ba 520 if (!a)
6c80cd29 521 die(_("invalid commit: %s"), author_message);
a45d46ba 522
fb7749e4
JN
523 lb = strchrnul(a + strlen("\nauthor "), '<');
524 rb = strchrnul(lb, '>');
525 eol = strchrnul(rb, '\n');
526 if (!*lb || !*rb || !*eol)
6c80cd29 527 die(_("invalid commit: %s"), author_message);
a45d46ba 528
fb7749e4
JN
529 if (lb == a + strlen("\nauthor "))
530 /* \nauthor <foo@example.com> */
531 name = xcalloc(1, 1);
532 else
533 name = xmemdupz(a + strlen("\nauthor "),
534 (lb - strlen(" ") -
535 (a + strlen("\nauthor "))));
536 email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
537 date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
a45d46ba
SB
538 }
539
540 if (force_author) {
541 const char *lb = strstr(force_author, " <");
542 const char *rb = strchr(force_author, '>');
543
544 if (!lb || !rb)
8a6179bc 545 die(_("malformed --author parameter"));
a45d46ba
SB
546 name = xstrndup(force_author, lb - force_author);
547 email = xstrndup(lb + 2, rb - (lb + 2));
548 }
549
02b47cd7
MV
550 if (force_date)
551 date = force_date;
4c28e4ad
JH
552 strbuf_addstr(author_ident, fmt_ident(name, email, date,
553 IDENT_ERROR_ON_NO_NAME));
a45d46ba
SB
554}
555
c1e01b0c
DB
556static int ends_rfc2822_footer(struct strbuf *sb)
557{
558 int ch;
559 int hit = 0;
560 int i, j, k;
561 int len = sb->len;
562 int first = 1;
563 const char *buf = sb->buf;
564
565 for (i = len - 1; i > 0; i--) {
566 if (hit && buf[i] == '\n')
567 break;
568 hit = (buf[i] == '\n');
569 }
570
571 while (i < len - 1 && buf[i] == '\n')
572 i++;
573
574 for (; i < len; i = k) {
575 for (k = i; k < len && buf[k] != '\n'; k++)
576 ; /* do nothing */
577 k++;
578
579 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
580 continue;
581
582 first = 0;
583
584 for (j = 0; i + j < len; j++) {
585 ch = buf[i + j];
586 if (ch == ':')
587 break;
588 if (isalnum(ch) ||
589 (ch == '-'))
590 continue;
591 return 0;
592 }
593 }
594 return 1;
595}
596
4c28e4ad
JH
597static char *cut_ident_timestamp_part(char *string)
598{
599 char *ket = strrchr(string, '>');
600 if (!ket || ket[1] != ' ')
8a6179bc 601 die(_("Malformed ident string: '%s'"), string);
4c28e4ad
JH
602 *++ket = '\0';
603 return ket;
604}
605
d249b098 606static int prepare_to_commit(const char *index_file, const char *prefix,
4c28e4ad
JH
607 struct wt_status *s,
608 struct strbuf *author_ident)
f5bbc322
KH
609{
610 struct stat statbuf;
4c28e4ad 611 struct strbuf committer_ident = STRBUF_INIT;
bc5d248a 612 int commitable, saved_color_setting;
f285a2d7 613 struct strbuf sb = STRBUF_INIT;
f5bbc322 614 char *buffer;
8089c85b
PB
615 const char *hook_arg1 = NULL;
616 const char *hook_arg2 = NULL;
bb1ae3f6 617 int ident_shown = 0;
8b1ae678 618 int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
f5bbc322 619
ec84bd00
PB
620 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
621 return 0;
f5bbc322 622
89ac1223
PN
623 if (squash_message) {
624 /*
625 * Insert the proper subject line before other commit
626 * message options add their content.
627 */
628 if (use_message && !strcmp(use_message, squash_message))
629 strbuf_addstr(&sb, "squash! ");
630 else {
631 struct pretty_print_context ctx = {0};
632 struct commit *c;
633 c = lookup_commit_reference_by_name(squash_message);
634 if (!c)
8a6179bc 635 die(_("could not lookup commit %s"), squash_message);
89ac1223
PN
636 ctx.output_encoding = get_commit_output_encoding();
637 format_commit_message(c, "squash! %s\n\n", &sb,
638 &ctx);
639 }
640 }
641
f9568530
JS
642 if (message.len) {
643 strbuf_addbuf(&sb, &message);
8089c85b 644 hook_arg1 = "message";
f5bbc322
KH
645 } else if (logfile && !strcmp(logfile, "-")) {
646 if (isatty(0))
8a6179bc 647 fprintf(stderr, _("(reading log message from standard input)\n"));
f5bbc322 648 if (strbuf_read(&sb, 0, 0) < 0)
8a6179bc 649 die_errno(_("could not read log from standard input"));
8089c85b 650 hook_arg1 = "message";
f5bbc322
KH
651 } else if (logfile) {
652 if (strbuf_read_file(&sb, logfile, 0) < 0)
8a6179bc 653 die_errno(_("could not read log file '%s'"),
d824cbba 654 logfile);
8089c85b 655 hook_arg1 = "message";
f5bbc322
KH
656 } else if (use_message) {
657 buffer = strstr(use_message_buffer, "\n\n");
658 if (!buffer || buffer[2] == '\0')
8a6179bc 659 die(_("commit has empty message"));
f5bbc322 660 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
8089c85b
PB
661 hook_arg1 = "commit";
662 hook_arg2 = use_message;
d71b8ba7
PN
663 } else if (fixup_message) {
664 struct pretty_print_context ctx = {0};
665 struct commit *commit;
666 commit = lookup_commit_reference_by_name(fixup_message);
667 if (!commit)
8a6179bc 668 die(_("could not lookup commit %s"), fixup_message);
d71b8ba7
PN
669 ctx.output_encoding = get_commit_output_encoding();
670 format_commit_message(commit, "fixup! %s\n\n",
671 &sb, &ctx);
672 hook_arg1 = "message";
f5bbc322
KH
673 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
674 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
8a6179bc 675 die_errno(_("could not read MERGE_MSG"));
8089c85b 676 hook_arg1 = "merge";
f5bbc322
KH
677 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
678 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
8a6179bc 679 die_errno(_("could not read SQUASH_MSG"));
8089c85b 680 hook_arg1 = "squash";
2140b140 681 } else if (template_file) {
f5bbc322 682 if (strbuf_read_file(&sb, template_file, 0) < 0)
8a6179bc 683 die_errno(_("could not read '%s'"), template_file);
8089c85b 684 hook_arg1 = "template";
8b1ae678 685 clean_message_contents = 0;
f5bbc322
KH
686 }
687
8089c85b 688 /*
37f7a857
JS
689 * The remaining cases don't modify the template message, but
690 * just set the argument(s) to the prepare-commit-msg hook.
8089c85b 691 */
37f7a857 692 else if (whence == FROM_MERGE)
8089c85b 693 hook_arg1 = "merge";
37f7a857
JS
694 else if (whence == FROM_CHERRY_PICK) {
695 hook_arg1 = "commit";
696 hook_arg2 = "CHERRY_PICK_HEAD";
697 }
8089c85b 698
89ac1223
PN
699 if (squash_message) {
700 /*
701 * If squash_commit was used for the commit subject,
702 * then we're possibly hijacking other commit log options.
703 * Reset the hook args to tell the real story.
704 */
705 hook_arg1 = "message";
706 hook_arg2 = "";
707 }
708
37f3012f
JN
709 s->fp = fopen(git_path(commit_editmsg), "w");
710 if (s->fp == NULL)
8a6179bc 711 die_errno(_("could not open '%s'"), git_path(commit_editmsg));
f5bbc322 712
8b1ae678 713 if (clean_message_contents)
5f065737 714 stripspace(&sb, 0);
f5bbc322
KH
715
716 if (signoff) {
f285a2d7 717 struct strbuf sob = STRBUF_INIT;
13208572
JS
718 int i;
719
13208572 720 strbuf_addstr(&sob, sign_off_header);
d9ccfe77
JH
721 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
722 getenv("GIT_COMMITTER_EMAIL")));
13208572 723 strbuf_addch(&sob, '\n');
13208572
JS
724 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
725 ; /* do nothing */
2150554b 726 if (prefixcmp(sb.buf + i, sob.buf)) {
e5138436 727 if (!i || !ends_rfc2822_footer(&sb))
2150554b 728 strbuf_addch(&sb, '\n');
13208572 729 strbuf_addbuf(&sb, &sob);
2150554b 730 }
13208572 731 strbuf_release(&sob);
f5bbc322
KH
732 }
733
37f3012f 734 if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
8a6179bc 735 die_errno(_("could not write commit template"));
13208572 736
f5bbc322
KH
737 strbuf_release(&sb);
738
4c28e4ad
JH
739 /* This checks and barfs if author is badly specified */
740 determine_author_info(author_ident);
e83dbe80 741
bb1ae3f6 742 /* This checks if committer ident is explicitly given */
4c28e4ad 743 strbuf_addstr(&committer_ident, git_committer_info(0));
bed575e4 744 if (use_editor && include_status) {
4c28e4ad 745 char *ai_tmp, *ci_tmp;
37f7a857 746 if (whence != FROM_COMMIT)
b926c0d1 747 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd 748 _("\n"
f4784b3e 749 "It looks like you may be committing a %s.\n"
b926c0d1
JN
750 "If this is not correct, please remove the file\n"
751 " %s\n"
752 "and try again.\n"
fe8165cd 753 ""),
37f7a857
JS
754 whence_s(),
755 git_path(whence == FROM_MERGE
756 ? "MERGE_HEAD"
757 : "CHERRY_PICK_HEAD"));
ec84bd00 758
b926c0d1
JN
759 fprintf(s->fp, "\n");
760 status_printf(s, GIT_COLOR_NORMAL,
0b430a17 761 _("Please enter the commit message for your changes."));
ec84bd00 762 if (cleanup_mode == CLEANUP_ALL)
b926c0d1 763 status_printf_more(s, GIT_COLOR_NORMAL,
0b430a17 764 _(" Lines starting\n"
b926c0d1 765 "with '#' will be ignored, and an empty"
0b430a17 766 " message aborts the commit.\n"));
ec84bd00 767 else /* CLEANUP_SPACE, that is. */
b926c0d1 768 status_printf_more(s, GIT_COLOR_NORMAL,
0b430a17 769 _(" Lines starting\n"
b926c0d1 770 "with '#' will be kept; you may remove them"
fdc7c811 771 " yourself if you want to.\n"
0b430a17 772 "An empty message aborts the commit.\n"));
ec84bd00 773 if (only_include_assumed)
b926c0d1
JN
774 status_printf_ln(s, GIT_COLOR_NORMAL,
775 "%s", only_include_assumed);
ec84bd00 776
4c28e4ad
JH
777 ai_tmp = cut_ident_timestamp_part(author_ident->buf);
778 ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
779 if (strcmp(author_ident->buf, committer_ident.buf))
b926c0d1 780 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd
ÆAB
781 _("%s"
782 "Author: %s"),
b926c0d1 783 ident_shown++ ? "" : "\n",
4c28e4ad 784 author_ident->buf);
e83dbe80 785
5aeb3a3a 786 if (!user_ident_sufficiently_given())
b926c0d1 787 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd
ÆAB
788 _("%s"
789 "Committer: %s"),
b926c0d1 790 ident_shown++ ? "" : "\n",
4c28e4ad 791 committer_ident.buf);
bb1ae3f6
SB
792
793 if (ident_shown)
b926c0d1 794 status_printf_ln(s, GIT_COLOR_NORMAL, "");
bb1ae3f6 795
d249b098
JH
796 saved_color_setting = s->use_color;
797 s->use_color = 0;
37f3012f 798 commitable = run_status(s->fp, index_file, prefix, 1, s);
d249b098 799 s->use_color = saved_color_setting;
4c28e4ad
JH
800
801 *ai_tmp = ' ';
802 *ci_tmp = ' ';
ec84bd00 803 } else {
d616a239 804 unsigned char sha1[20];
fbcf1184 805 const char *parent = "HEAD";
7168624c 806
7168624c 807 if (!active_nr && read_cache() < 0)
8a6179bc 808 die(_("Cannot read index"));
7168624c 809
fbcf1184
JH
810 if (amend)
811 parent = "HEAD^1";
812
d616a239 813 if (get_sha1(parent, sha1))
ec84bd00 814 commitable = !!active_nr;
75f3ff2e
SB
815 else
816 commitable = index_differs_from(parent, 0);
ec84bd00 817 }
4c28e4ad 818 strbuf_release(&committer_ident);
d616a239 819
37f3012f 820 fclose(s->fp);
7168624c 821
37f7a857
JS
822 /*
823 * Reject an attempt to record a non-merge empty commit without
824 * explicit --allow-empty. In the cherry-pick case, it may be
825 * empty due to conflict resolution, which the user should okay.
826 */
827 if (!commitable && whence != FROM_MERGE && !allow_empty &&
ec84bd00 828 !(amend && is_a_merge(head_sha1))) {
d249b098 829 run_status(stdout, index_file, prefix, 0, s);
f197ed2f 830 if (amend)
fc88e316 831 fputs(_(empty_amend_advice), stderr);
37f7a857 832 else if (whence == FROM_CHERRY_PICK)
6c80cd29 833 fputs(_(empty_cherry_pick_advice), stderr);
ec84bd00 834 return 0;
7168624c
AR
835 }
836
ec84bd00
PB
837 /*
838 * Re-read the index as pre-commit hook could have updated it,
839 * and write it out as a tree. We must do this before we invoke
840 * the editor and after we invoke run_status above.
841 */
842 discard_cache();
843 read_cache_from(index_file);
844 if (!active_cache_tree)
845 active_cache_tree = cache_tree();
846 if (cache_tree_update(active_cache_tree,
847 active_cache, active_nr, 0, 0) < 0) {
8a6179bc 848 error(_("Error building trees"));
ec84bd00 849 return 0;
7168624c 850 }
f5bbc322 851
8089c85b
PB
852 if (run_hook(index_file, "prepare-commit-msg",
853 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
854 return 0;
f5bbc322 855
ec84bd00
PB
856 if (use_editor) {
857 char index[PATH_MAX];
66dbfd55
GV
858 const char *env[2] = { NULL };
859 env[0] = index;
ec84bd00 860 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
7198203a
SB
861 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
862 fprintf(stderr,
8a6179bc 863 _("Please supply the message using either -m or -F option.\n"));
7198203a
SB
864 exit(1);
865 }
ec84bd00 866 }
f5bbc322 867
ec84bd00
PB
868 if (!no_verify &&
869 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
870 return 0;
871 }
f5bbc322 872
ec84bd00 873 return 1;
f5bbc322
KH
874}
875
876/*
6bb6b034
MV
877 * Find out if the message in the strbuf contains only whitespace and
878 * Signed-off-by lines.
f5bbc322 879 */
6bb6b034 880static int message_is_empty(struct strbuf *sb)
f5bbc322 881{
f285a2d7 882 struct strbuf tmpl = STRBUF_INIT;
f5bbc322 883 const char *nl;
6bb6b034 884 int eol, i, start = 0;
f5bbc322 885
5f065737
AR
886 if (cleanup_mode == CLEANUP_NONE && sb->len)
887 return 0;
888
f5bbc322 889 /* See if the template is just a prefix of the message. */
f5bbc322 890 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
5f065737 891 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
f5bbc322
KH
892 if (start + tmpl.len <= sb->len &&
893 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
894 start += tmpl.len;
895 }
896 strbuf_release(&tmpl);
897
898 /* Check if the rest is just whitespace and Signed-of-by's. */
899 for (i = start; i < sb->len; i++) {
900 nl = memchr(sb->buf + i, '\n', sb->len - i);
901 if (nl)
902 eol = nl - sb->buf;
903 else
904 eol = sb->len;
905
906 if (strlen(sign_off_header) <= eol - i &&
907 !prefixcmp(sb->buf + i, sign_off_header)) {
908 i = eol;
909 continue;
910 }
911 while (i < eol)
912 if (!isspace(sb->buf[i++]))
913 return 0;
914 }
915
916 return 1;
917}
918
146ea068
JH
919static const char *find_author_by_nickname(const char *name)
920{
921 struct rev_info revs;
922 struct commit *commit;
923 struct strbuf buf = STRBUF_INIT;
924 const char *av[20];
925 int ac = 0;
926
927 init_revisions(&revs, NULL);
928 strbuf_addf(&buf, "--author=%s", name);
929 av[++ac] = "--all";
930 av[++ac] = "-i";
931 av[++ac] = buf.buf;
932 av[++ac] = NULL;
933 setup_revisions(ac, av, &revs, NULL);
934 prepare_revision_walk(&revs);
935 commit = get_revision(&revs);
936 if (commit) {
dd2e794a
TR
937 struct pretty_print_context ctx = {0};
938 ctx.date_mode = DATE_NORMAL;
146ea068 939 strbuf_release(&buf);
dd2e794a 940 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
146ea068
JH
941 return strbuf_detach(&buf, NULL);
942 }
8a6179bc 943 die(_("No existing author found with '%s'"), name);
146ea068
JH
944}
945
76e2f7ce
JH
946
947static void handle_untracked_files_arg(struct wt_status *s)
948{
949 if (!untracked_files_arg)
950 ; /* default already initialized */
951 else if (!strcmp(untracked_files_arg, "no"))
952 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
953 else if (!strcmp(untracked_files_arg, "normal"))
954 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
955 else if (!strcmp(untracked_files_arg, "all"))
956 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
957 else
8a6179bc 958 die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
76e2f7ce
JH
959}
960
37f7a857
JS
961static const char *read_commit_message(const char *name)
962{
963 const char *out_enc, *out;
964 struct commit *commit;
965
966 commit = lookup_commit_reference_by_name(name);
967 if (!commit)
6c80cd29 968 die(_("could not lookup commit %s"), name);
37f7a857
JS
969 out_enc = get_commit_output_encoding();
970 out = logmsg_reencode(commit, out_enc);
971
972 /*
973 * If we failed to reencode the buffer, just copy it
974 * byte for byte so the user can try to fix it up.
975 * This also handles the case where input and output
976 * encodings are identical.
977 */
978 if (out == NULL)
979 out = xstrdup(commit->buffer);
980 return out;
981}
982
2f02b25f 983static int parse_and_validate_options(int argc, const char *argv[],
dbd0f5c7 984 const char * const usage[],
d249b098
JH
985 const char *prefix,
986 struct wt_status *s)
f5bbc322
KH
987{
988 int f = 0;
989
37782920
SB
990 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
991 0);
f5bbc322 992
146ea068
JH
993 if (force_author && !strchr(force_author, '>'))
994 force_author = find_author_by_nickname(force_author);
995
c51f6cee 996 if (force_author && renew_authorship)
8a6179bc 997 die(_("Using both --reset-author and --author does not make sense"));
c51f6cee 998
d71b8ba7 999 if (logfile || message.len || use_message || fixup_message)
4803466f 1000 use_editor = 0;
f5bbc322 1001 if (edit_flag)
4803466f 1002 use_editor = 1;
406400ce
PB
1003 if (!use_editor)
1004 setenv("GIT_EDITOR", ":", 1);
f5bbc322
KH
1005
1006 if (get_sha1("HEAD", head_sha1))
1007 initial_commit = 1;
1008
f5bbc322
KH
1009 /* Sanity check options */
1010 if (amend && initial_commit)
8a6179bc 1011 die(_("You have nothing to amend."));
37f7a857 1012 if (amend && whence != FROM_COMMIT)
6c80cd29 1013 die(_("You are in the middle of a %s -- cannot amend."), whence_s());
89ac1223 1014 if (fixup_message && squash_message)
9c227655 1015 die(_("Options --squash and --fixup cannot be used together"));
f5bbc322
KH
1016 if (use_message)
1017 f++;
1018 if (edit_message)
1019 f++;
d71b8ba7
PN
1020 if (fixup_message)
1021 f++;
f5bbc322
KH
1022 if (logfile)
1023 f++;
1024 if (f > 1)
8a6179bc 1025 die(_("Only one of -c/-C/-F/--fixup can be used."));
f9568530 1026 if (message.len && f > 0)
8a6179bc 1027 die((_("Option -m cannot be combined with -c/-C/-F/--fixup.")));
f5bbc322
KH
1028 if (edit_message)
1029 use_message = edit_message;
d71b8ba7 1030 if (amend && !use_message && !fixup_message)
f5bbc322 1031 use_message = "HEAD";
37f7a857 1032 if (!use_message && whence != FROM_CHERRY_PICK && renew_authorship)
8a6179bc 1033 die(_("--reset-author can be used only with -C, -c or --amend."));
f5bbc322 1034 if (use_message) {
37f7a857
JS
1035 use_message_buffer = read_commit_message(use_message);
1036 if (!renew_authorship) {
1037 author_message = use_message;
1038 author_message_buffer = use_message_buffer;
1039 }
1040 }
1041 if (whence == FROM_CHERRY_PICK && !renew_authorship) {
1042 author_message = "CHERRY_PICK_HEAD";
1043 author_message_buffer = read_commit_message(author_message);
f5bbc322
KH
1044 }
1045
1046 if (!!also + !!only + !!all + !!interactive > 1)
8a6179bc 1047 die(_("Only one of --include/--only/--all/--interactive can be used."));
f5bbc322 1048 if (argc == 0 && (also || (only && !amend)))
8a6179bc 1049 die(_("No paths with --include/--only does not make sense."));
f5bbc322 1050 if (argc == 0 && only && amend)
8a6179bc 1051 only_include_assumed = _("Clever... amending the last one with dirty index.");
3c5283f8 1052 if (argc > 0 && !also && !only)
8a6179bc 1053 only_include_assumed = _("Explicit paths specified without -i nor -o; assuming --only paths...");
5f065737
AR
1054 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
1055 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
1056 else if (!strcmp(cleanup_arg, "verbatim"))
1057 cleanup_mode = CLEANUP_NONE;
1058 else if (!strcmp(cleanup_arg, "whitespace"))
1059 cleanup_mode = CLEANUP_SPACE;
1060 else if (!strcmp(cleanup_arg, "strip"))
1061 cleanup_mode = CLEANUP_ALL;
1062 else
8a6179bc 1063 die(_("Invalid cleanup mode %s"), cleanup_arg);
f5bbc322 1064
76e2f7ce 1065 handle_untracked_files_arg(s);
4bfee30a 1066
f5bbc322 1067 if (all && argc > 0)
8a6179bc 1068 die(_("Paths with -a does not make sense."));
f5bbc322 1069 else if (interactive && argc > 0)
8a6179bc 1070 die(_("Paths with --interactive does not make sense."));
f5bbc322 1071
7c9f7038
JK
1072 if (null_termination && status_format == STATUS_FORMAT_LONG)
1073 status_format = STATUS_FORMAT_PORCELAIN;
1074 if (status_format != STATUS_FORMAT_LONG)
1075 dry_run = 1;
1076
f5bbc322
KH
1077 return argc;
1078}
1079
d249b098
JH
1080static int dry_run_commit(int argc, const char **argv, const char *prefix,
1081 struct wt_status *s)
f5bbc322 1082{
f5bbc322 1083 int commitable;
3a5d13a3 1084 const char *index_file;
f5bbc322 1085
3a5d13a3 1086 index_file = prepare_index(argc, argv, prefix, 1);
d249b098 1087 commitable = run_status(stdout, index_file, prefix, 0, s);
3a5d13a3 1088 rollback_index_files();
f5bbc322 1089
3a5d13a3
JH
1090 return commitable ? 0 : 1;
1091}
1092
f766b367
JH
1093static int parse_status_slot(const char *var, int offset)
1094{
1095 if (!strcasecmp(var+offset, "header"))
1096 return WT_STATUS_HEADER;
1d282327
AA
1097 if (!strcasecmp(var+offset, "branch"))
1098 return WT_STATUS_ONBRANCH;
f766b367
JH
1099 if (!strcasecmp(var+offset, "updated")
1100 || !strcasecmp(var+offset, "added"))
1101 return WT_STATUS_UPDATED;
1102 if (!strcasecmp(var+offset, "changed"))
1103 return WT_STATUS_CHANGED;
1104 if (!strcasecmp(var+offset, "untracked"))
1105 return WT_STATUS_UNTRACKED;
1106 if (!strcasecmp(var+offset, "nobranch"))
1107 return WT_STATUS_NOBRANCH;
1108 if (!strcasecmp(var+offset, "unmerged"))
1109 return WT_STATUS_UNMERGED;
8b8e8624 1110 return -1;
f766b367
JH
1111}
1112
1113static int git_status_config(const char *k, const char *v, void *cb)
1114{
1115 struct wt_status *s = cb;
1116
1117 if (!strcmp(k, "status.submodulesummary")) {
1118 int is_bool;
1119 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
1120 if (is_bool && s->submodule_summary)
1121 s->submodule_summary = -1;
1122 return 0;
1123 }
1124 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
1125 s->use_color = git_config_colorbool(k, v, -1);
1126 return 0;
1127 }
1128 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
1129 int slot = parse_status_slot(k, 13);
8b8e8624
JK
1130 if (slot < 0)
1131 return 0;
f766b367
JH
1132 if (!v)
1133 return config_error_nonbool(k);
1134 color_parse(v, k, s->color_palette[slot]);
1135 return 0;
1136 }
1137 if (!strcmp(k, "status.relativepaths")) {
1138 s->relative_paths = git_config_bool(k, v);
1139 return 0;
1140 }
1141 if (!strcmp(k, "status.showuntrackedfiles")) {
1142 if (!v)
1143 return config_error_nonbool(k);
1144 else if (!strcmp(v, "no"))
1145 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
1146 else if (!strcmp(v, "normal"))
1147 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
1148 else if (!strcmp(v, "all"))
1149 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
1150 else
8a6179bc 1151 return error(_("Invalid untracked files mode '%s'"), v);
f766b367
JH
1152 return 0;
1153 }
1154 return git_diff_ui_config(k, v, NULL);
1155}
1156
3a5d13a3
JH
1157int cmd_status(int argc, const char **argv, const char *prefix)
1158{
d249b098 1159 struct wt_status s;
4bb6644d 1160 int fd;
76e2f7ce 1161 unsigned char sha1[20];
9e4b7ab6 1162 static struct option builtin_status_options[] = {
fd03881a 1163 OPT__VERBOSE(&verbose, "be verbose"),
dd2be243
JK
1164 OPT_SET_INT('s', "short", &status_format,
1165 "show status concisely", STATUS_FORMAT_SHORT),
05a59a08
DKF
1166 OPT_BOOLEAN('b', "branch", &status_show_branch,
1167 "show branch information"),
6f157871 1168 OPT_SET_INT(0, "porcelain", &status_format,
ba9d7fe1 1169 "machine-readable output",
6f157871 1170 STATUS_FORMAT_PORCELAIN),
173e6c88
JH
1171 OPT_BOOLEAN('z', "null", &null_termination,
1172 "terminate entries with NUL"),
76e2f7ce
JH
1173 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1174 "mode",
1175 "show untracked files, optional modes: all, normal, no. (Default: all)",
1176 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
2381e39e
JH
1177 OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
1178 "show ignored files"),
46a958b3
JL
1179 { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
1180 "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
1181 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
76e2f7ce
JH
1182 OPT_END(),
1183 };
1184
5d3dd915
NTND
1185 if (argc == 2 && !strcmp(argv[1], "-h"))
1186 usage_with_options(builtin_status_usage, builtin_status_options);
1187
dd2be243 1188 if (null_termination && status_format == STATUS_FORMAT_LONG)
6f157871 1189 status_format = STATUS_FORMAT_PORCELAIN;
d249b098
JH
1190
1191 wt_status_prepare(&s);
302ad7a9 1192 gitmodules_config();
d249b098 1193 git_config(git_status_config, &s);
37f7a857 1194 determine_whence(&s);
76e2f7ce 1195 argc = parse_options(argc, argv, prefix,
9e4b7ab6
JH
1196 builtin_status_options,
1197 builtin_status_usage, 0);
76e2f7ce 1198 handle_untracked_files_arg(&s);
2381e39e
JH
1199 if (show_ignored_in_status)
1200 s.show_ignored_files = 1;
76e2f7ce
JH
1201 if (*argv)
1202 s.pathspec = get_pathspec(prefix, argv);
1203
149794dd 1204 read_cache_preload(s.pathspec);
688cd6d2 1205 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
4bb6644d
MH
1206
1207 fd = hold_locked_index(&index_lock, 0);
ccdc4ec3
JH
1208 if (0 <= fd)
1209 update_index_if_able(&the_index, &index_lock);
4bb6644d 1210
76e2f7ce 1211 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
46a958b3 1212 s.ignore_submodule_arg = ignore_submodule_arg;
76e2f7ce
JH
1213 wt_status_collect(&s);
1214
8661768f
JK
1215 if (s.relative_paths)
1216 s.prefix = prefix;
d249b098
JH
1217 if (s.use_color == -1)
1218 s.use_color = git_use_color_default;
38920dd6
MH
1219 if (diff_use_color_default == -1)
1220 diff_use_color_default = git_use_color_default;
1221
dd2be243
JK
1222 switch (status_format) {
1223 case STATUS_FORMAT_SHORT:
05a59a08 1224 wt_shortstatus_print(&s, null_termination, status_show_branch);
dd2be243 1225 break;
6f157871 1226 case STATUS_FORMAT_PORCELAIN:
4a7cc2fd 1227 wt_porcelain_print(&s, null_termination);
6f157871 1228 break;
dd2be243 1229 case STATUS_FORMAT_LONG:
173e6c88 1230 s.verbose = verbose;
46a958b3 1231 s.ignore_submodule_arg = ignore_submodule_arg;
173e6c88 1232 wt_status_print(&s);
dd2be243 1233 break;
173e6c88 1234 }
76e2f7ce 1235 return 0;
f5bbc322
KH
1236}
1237
f5bbc322
KH
1238static void print_summary(const char *prefix, const unsigned char *sha1)
1239{
1240 struct rev_info rev;
1241 struct commit *commit;
49ff9a7a 1242 struct strbuf format = STRBUF_INIT;
c85db254
JK
1243 unsigned char junk_sha1[20];
1244 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
49ff9a7a
JK
1245 struct pretty_print_context pctx = {0};
1246 struct strbuf author_ident = STRBUF_INIT;
1247 struct strbuf committer_ident = STRBUF_INIT;
f5bbc322
KH
1248
1249 commit = lookup_commit(sha1);
1250 if (!commit)
8a6179bc 1251 die(_("couldn't look up newly created commit"));
f5bbc322 1252 if (!commit || parse_commit(commit))
8a6179bc 1253 die(_("could not parse newly created commit"));
f5bbc322 1254
49ff9a7a
JK
1255 strbuf_addstr(&format, "format:%h] %s");
1256
1257 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
1258 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
1259 if (strbuf_cmp(&author_ident, &committer_ident)) {
1260 strbuf_addstr(&format, "\n Author: ");
1261 strbuf_addbuf_percentquote(&format, &author_ident);
1262 }
1a893064 1263 if (!user_ident_sufficiently_given()) {
49ff9a7a
JK
1264 strbuf_addstr(&format, "\n Committer: ");
1265 strbuf_addbuf_percentquote(&format, &committer_ident);
b706fcfe
JK
1266 if (advice_implicit_identity) {
1267 strbuf_addch(&format, '\n');
fc88e316 1268 strbuf_addstr(&format, _(implicit_ident_advice));
b706fcfe 1269 }
49ff9a7a
JK
1270 }
1271 strbuf_release(&author_ident);
1272 strbuf_release(&committer_ident);
1273
f5bbc322
KH
1274 init_revisions(&rev, prefix);
1275 setup_revisions(0, NULL, &rev, NULL);
1276
f5bbc322
KH
1277 rev.diff = 1;
1278 rev.diffopt.output_format =
1279 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1280
1281 rev.verbose_header = 1;
1282 rev.show_root_diff = 1;
49ff9a7a 1283 get_commit_format(format.buf, &rev);
bf82a150 1284 rev.always_show_header = 0;
3eb2a15e 1285 rev.diffopt.detect_rename = 1;
3eb2a15e 1286 rev.diffopt.break_opt = 0;
15964563 1287 diff_setup_done(&rev.diffopt);
f5bbc322 1288
c5ee71fd 1289 printf("[%s%s ",
c85db254
JK
1290 !prefixcmp(head, "refs/heads/") ?
1291 head + 11 :
1292 !strcmp(head, "HEAD") ?
7f5673d7 1293 _("detached HEAD") :
c85db254 1294 head,
7f5673d7 1295 initial_commit ? _(" (root-commit)") : "");
f5bbc322 1296
bf82a150 1297 if (!log_tree_commit(&rev, commit)) {
a45e1a87
TRC
1298 rev.always_show_header = 1;
1299 rev.use_terminator = 1;
1300 log_tree_commit(&rev, commit);
bf82a150 1301 }
a45e1a87 1302
fc6f19fe 1303 strbuf_release(&format);
f5bbc322
KH
1304}
1305
186458b1 1306static int git_commit_config(const char *k, const char *v, void *cb)
f5bbc322 1307{
d249b098
JH
1308 struct wt_status *s = cb;
1309
984c6e7e 1310 if (!strcmp(k, "commit.template"))
395de250 1311 return git_config_pathname(&template_file, k, v);
bed575e4
JHI
1312 if (!strcmp(k, "commit.status")) {
1313 include_status = git_config_bool(k, v);
1314 return 0;
1315 }
f5bbc322 1316
d249b098 1317 return git_status_config(k, v, s);
f5bbc322
KH
1318}
1319
6f6bee3b
TR
1320static const char post_rewrite_hook[] = "hooks/post-rewrite";
1321
1322static int run_rewrite_hook(const unsigned char *oldsha1,
1323 const unsigned char *newsha1)
1324{
1325 /* oldsha1 SP newsha1 LF NUL */
1326 static char buf[2*40 + 3];
1327 struct child_process proc;
1328 const char *argv[3];
1329 int code;
1330 size_t n;
1331
1332 if (access(git_path(post_rewrite_hook), X_OK) < 0)
1333 return 0;
1334
1335 argv[0] = git_path(post_rewrite_hook);
1336 argv[1] = "amend";
1337 argv[2] = NULL;
1338
1339 memset(&proc, 0, sizeof(proc));
1340 proc.argv = argv;
1341 proc.in = -1;
1342 proc.stdout_to_stderr = 1;
1343
1344 code = start_command(&proc);
1345 if (code)
1346 return code;
1347 n = snprintf(buf, sizeof(buf), "%s %s\n",
1348 sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1349 write_in_full(proc.in, buf, n);
1350 close(proc.in);
1351 return finish_command(&proc);
1352}
1353
f5bbc322
KH
1354int cmd_commit(int argc, const char **argv, const char *prefix)
1355{
f285a2d7 1356 struct strbuf sb = STRBUF_INIT;
4c28e4ad 1357 struct strbuf author_ident = STRBUF_INIT;
f5bbc322 1358 const char *index_file, *reflog_msg;
99a12694 1359 char *nl, *p;
f5bbc322
KH
1360 unsigned char commit_sha1[20];
1361 struct ref_lock *ref_lock;
6bb6b034 1362 struct commit_list *parents = NULL, **pptr = &parents;
cf10f9fd
MV
1363 struct stat statbuf;
1364 int allow_fast_forward = 1;
d249b098 1365 struct wt_status s;
f5bbc322 1366
5d3dd915
NTND
1367 if (argc == 2 && !strcmp(argv[1], "-h"))
1368 usage_with_options(builtin_commit_usage, builtin_commit_options);
1369
d249b098
JH
1370 wt_status_prepare(&s);
1371 git_config(git_commit_config, &s);
37f7a857 1372 determine_whence(&s);
f5bbc322 1373
d249b098
JH
1374 if (s.use_color == -1)
1375 s.use_color = git_use_color_default;
d249b098
JH
1376 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1377 prefix, &s);
3fa509df
JH
1378 if (dry_run) {
1379 if (diff_use_color_default == -1)
1380 diff_use_color_default = git_use_color_default;
d249b098 1381 return dry_run_commit(argc, argv, prefix, &s);
3fa509df 1382 }
50b7e70f 1383 index_file = prepare_index(argc, argv, prefix, 0);
f5bbc322 1384
ec84bd00
PB
1385 /* Set up everything for writing the commit object. This includes
1386 running hooks, writing the trees, and interacting with the user. */
4c28e4ad 1387 if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) {
2888605c 1388 rollback_index_files();
f5bbc322
KH
1389 return 1;
1390 }
1391
f5bbc322 1392 /* Determine parents */
643cb5f7 1393 reflog_msg = getenv("GIT_REFLOG_ACTION");
f5bbc322 1394 if (initial_commit) {
643cb5f7
CC
1395 if (!reflog_msg)
1396 reflog_msg = "commit (initial)";
f5bbc322
KH
1397 } else if (amend) {
1398 struct commit_list *c;
1399 struct commit *commit;
1400
643cb5f7
CC
1401 if (!reflog_msg)
1402 reflog_msg = "commit (amend)";
f5bbc322
KH
1403 commit = lookup_commit(head_sha1);
1404 if (!commit || parse_commit(commit))
8a6179bc 1405 die(_("could not parse HEAD commit"));
f5bbc322
KH
1406
1407 for (c = commit->parents; c; c = c->next)
6bb6b034 1408 pptr = &commit_list_insert(c->item, pptr)->next;
37f7a857 1409 } else if (whence == FROM_MERGE) {
f285a2d7 1410 struct strbuf m = STRBUF_INIT;
f5bbc322
KH
1411 FILE *fp;
1412
643cb5f7
CC
1413 if (!reflog_msg)
1414 reflog_msg = "commit (merge)";
6bb6b034 1415 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
f5bbc322
KH
1416 fp = fopen(git_path("MERGE_HEAD"), "r");
1417 if (fp == NULL)
8a6179bc 1418 die_errno(_("could not open '%s' for reading"),
d824cbba 1419 git_path("MERGE_HEAD"));
7c3fd25d
LT
1420 while (strbuf_getline(&m, fp, '\n') != EOF) {
1421 unsigned char sha1[20];
1422 if (get_sha1_hex(m.buf, sha1) < 0)
8a6179bc 1423 die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
6bb6b034 1424 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
7c3fd25d 1425 }
f5bbc322
KH
1426 fclose(fp);
1427 strbuf_release(&m);
cf10f9fd
MV
1428 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1429 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
8a6179bc 1430 die_errno(_("could not read MERGE_MODE"));
cf10f9fd
MV
1431 if (!strcmp(sb.buf, "no-ff"))
1432 allow_fast_forward = 0;
1433 }
1434 if (allow_fast_forward)
1435 parents = reduce_heads(parents);
f5bbc322 1436 } else {
643cb5f7 1437 if (!reflog_msg)
37f7a857
JS
1438 reflog_msg = (whence == FROM_CHERRY_PICK)
1439 ? "commit (cherry-pick)"
1440 : "commit";
6bb6b034 1441 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
f5bbc322 1442 }
f5bbc322 1443
ec84bd00 1444 /* Finally, get the commit message */
cf10f9fd 1445 strbuf_reset(&sb);
740001a5 1446 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
0721c314 1447 int saved_errno = errno;
740001a5 1448 rollback_index_files();
8a6179bc 1449 die(_("could not read commit message: %s"), strerror(saved_errno));
740001a5 1450 }
99a12694
KH
1451
1452 /* Truncate the message just before the diff, if any. */
0b38227f
JK
1453 if (verbose) {
1454 p = strstr(sb.buf, "\ndiff --git ");
1455 if (p != NULL)
1456 strbuf_setlen(&sb, p - sb.buf + 1);
1457 }
99a12694 1458
5f065737
AR
1459 if (cleanup_mode != CLEANUP_NONE)
1460 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
c9b5fde7 1461 if (message_is_empty(&sb) && !allow_empty_message) {
2888605c 1462 rollback_index_files();
8a6179bc 1463 fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
fdc7c811 1464 exit(1);
2888605c 1465 }
f5bbc322 1466
6bb6b034 1467 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
4c28e4ad 1468 author_ident.buf)) {
2888605c 1469 rollback_index_files();
8a6179bc 1470 die(_("failed to write commit object"));
2888605c 1471 }
4c28e4ad 1472 strbuf_release(&author_ident);
f5bbc322
KH
1473
1474 ref_lock = lock_any_ref_for_update("HEAD",
1475 initial_commit ? NULL : head_sha1,
1476 0);
1477
6bb6b034 1478 nl = strchr(sb.buf, '\n');
741707b1
JS
1479 if (nl)
1480 strbuf_setlen(&sb, nl + 1 - sb.buf);
1481 else
1482 strbuf_addch(&sb, '\n');
741707b1
JS
1483 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1484 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
f5bbc322 1485
2888605c
JH
1486 if (!ref_lock) {
1487 rollback_index_files();
8a6179bc 1488 die(_("cannot lock HEAD ref"));
2888605c
JH
1489 }
1490 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1491 rollback_index_files();
8a6179bc 1492 die(_("cannot update HEAD ref"));
2888605c 1493 }
f5bbc322 1494
d7e5c0cb 1495 unlink(git_path("CHERRY_PICK_HEAD"));
f5bbc322
KH
1496 unlink(git_path("MERGE_HEAD"));
1497 unlink(git_path("MERGE_MSG"));
cf10f9fd 1498 unlink(git_path("MERGE_MODE"));
5a95b855 1499 unlink(git_path("SQUASH_MSG"));
f5bbc322 1500
5a9dd399 1501 if (commit_index_files())
8a6179bc 1502 die (_("Repository has been updated, but unable to write\n"
5a9dd399 1503 "new_index file. Check that disk is not full or quota is\n"
8a6179bc 1504 "not exceeded, and then \"git reset HEAD\" to recover."));
f5bbc322 1505
cb6020bb 1506 rerere(0);
2888605c 1507 run_hook(get_index_file(), "post-commit", NULL);
6f6bee3b 1508 if (amend && !no_post_rewrite) {
6360d343
TR
1509 struct notes_rewrite_cfg *cfg;
1510 cfg = init_copy_notes_for_rewrite("amend");
1511 if (cfg) {
1512 copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
1513 finish_copy_notes_for_rewrite(cfg);
1514 }
6f6bee3b
TR
1515 run_rewrite_hook(head_sha1, commit_sha1);
1516 }
f5bbc322
KH
1517 if (!quiet)
1518 print_summary(prefix, commit_sha1);
1519
1520 return 0;
1521}