]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/commit.c
git-reset.txt: better docs for '--patch'
[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;
f5bbc322 618
ec84bd00
PB
619 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
620 return 0;
f5bbc322 621
89ac1223
PN
622 if (squash_message) {
623 /*
624 * Insert the proper subject line before other commit
625 * message options add their content.
626 */
627 if (use_message && !strcmp(use_message, squash_message))
628 strbuf_addstr(&sb, "squash! ");
629 else {
630 struct pretty_print_context ctx = {0};
631 struct commit *c;
632 c = lookup_commit_reference_by_name(squash_message);
633 if (!c)
8a6179bc 634 die(_("could not lookup commit %s"), squash_message);
89ac1223
PN
635 ctx.output_encoding = get_commit_output_encoding();
636 format_commit_message(c, "squash! %s\n\n", &sb,
637 &ctx);
638 }
639 }
640
f9568530
JS
641 if (message.len) {
642 strbuf_addbuf(&sb, &message);
8089c85b 643 hook_arg1 = "message";
f5bbc322
KH
644 } else if (logfile && !strcmp(logfile, "-")) {
645 if (isatty(0))
8a6179bc 646 fprintf(stderr, _("(reading log message from standard input)\n"));
f5bbc322 647 if (strbuf_read(&sb, 0, 0) < 0)
8a6179bc 648 die_errno(_("could not read log from standard input"));
8089c85b 649 hook_arg1 = "message";
f5bbc322
KH
650 } else if (logfile) {
651 if (strbuf_read_file(&sb, logfile, 0) < 0)
8a6179bc 652 die_errno(_("could not read log file '%s'"),
d824cbba 653 logfile);
8089c85b 654 hook_arg1 = "message";
f5bbc322
KH
655 } else if (use_message) {
656 buffer = strstr(use_message_buffer, "\n\n");
657 if (!buffer || buffer[2] == '\0')
8a6179bc 658 die(_("commit has empty message"));
f5bbc322 659 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
8089c85b
PB
660 hook_arg1 = "commit";
661 hook_arg2 = use_message;
d71b8ba7
PN
662 } else if (fixup_message) {
663 struct pretty_print_context ctx = {0};
664 struct commit *commit;
665 commit = lookup_commit_reference_by_name(fixup_message);
666 if (!commit)
8a6179bc 667 die(_("could not lookup commit %s"), fixup_message);
d71b8ba7
PN
668 ctx.output_encoding = get_commit_output_encoding();
669 format_commit_message(commit, "fixup! %s\n\n",
670 &sb, &ctx);
671 hook_arg1 = "message";
f5bbc322
KH
672 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
673 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
8a6179bc 674 die_errno(_("could not read MERGE_MSG"));
8089c85b 675 hook_arg1 = "merge";
f5bbc322
KH
676 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
677 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
8a6179bc 678 die_errno(_("could not read SQUASH_MSG"));
8089c85b 679 hook_arg1 = "squash";
2140b140 680 } else if (template_file) {
f5bbc322 681 if (strbuf_read_file(&sb, template_file, 0) < 0)
8a6179bc 682 die_errno(_("could not read '%s'"), template_file);
8089c85b 683 hook_arg1 = "template";
f5bbc322
KH
684 }
685
8089c85b 686 /*
37f7a857
JS
687 * The remaining cases don't modify the template message, but
688 * just set the argument(s) to the prepare-commit-msg hook.
8089c85b 689 */
37f7a857 690 else if (whence == FROM_MERGE)
8089c85b 691 hook_arg1 = "merge";
37f7a857
JS
692 else if (whence == FROM_CHERRY_PICK) {
693 hook_arg1 = "commit";
694 hook_arg2 = "CHERRY_PICK_HEAD";
695 }
8089c85b 696
89ac1223
PN
697 if (squash_message) {
698 /*
699 * If squash_commit was used for the commit subject,
700 * then we're possibly hijacking other commit log options.
701 * Reset the hook args to tell the real story.
702 */
703 hook_arg1 = "message";
704 hook_arg2 = "";
705 }
706
37f3012f
JN
707 s->fp = fopen(git_path(commit_editmsg), "w");
708 if (s->fp == NULL)
8a6179bc 709 die_errno(_("could not open '%s'"), git_path(commit_editmsg));
f5bbc322 710
5f065737
AR
711 if (cleanup_mode != CLEANUP_NONE)
712 stripspace(&sb, 0);
f5bbc322
KH
713
714 if (signoff) {
f285a2d7 715 struct strbuf sob = STRBUF_INIT;
13208572
JS
716 int i;
717
13208572 718 strbuf_addstr(&sob, sign_off_header);
d9ccfe77
JH
719 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
720 getenv("GIT_COMMITTER_EMAIL")));
13208572 721 strbuf_addch(&sob, '\n');
13208572
JS
722 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
723 ; /* do nothing */
2150554b 724 if (prefixcmp(sb.buf + i, sob.buf)) {
e5138436 725 if (!i || !ends_rfc2822_footer(&sb))
2150554b 726 strbuf_addch(&sb, '\n');
13208572 727 strbuf_addbuf(&sb, &sob);
2150554b 728 }
13208572 729 strbuf_release(&sob);
f5bbc322
KH
730 }
731
37f3012f 732 if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
8a6179bc 733 die_errno(_("could not write commit template"));
13208572 734
f5bbc322
KH
735 strbuf_release(&sb);
736
4c28e4ad
JH
737 /* This checks and barfs if author is badly specified */
738 determine_author_info(author_ident);
e83dbe80 739
bb1ae3f6 740 /* This checks if committer ident is explicitly given */
4c28e4ad 741 strbuf_addstr(&committer_ident, git_committer_info(0));
bed575e4 742 if (use_editor && include_status) {
4c28e4ad 743 char *ai_tmp, *ci_tmp;
37f7a857 744 if (whence != FROM_COMMIT)
b926c0d1 745 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd 746 _("\n"
f4784b3e 747 "It looks like you may be committing a %s.\n"
b926c0d1
JN
748 "If this is not correct, please remove the file\n"
749 " %s\n"
750 "and try again.\n"
fe8165cd 751 ""),
37f7a857
JS
752 whence_s(),
753 git_path(whence == FROM_MERGE
754 ? "MERGE_HEAD"
755 : "CHERRY_PICK_HEAD"));
ec84bd00 756
b926c0d1
JN
757 fprintf(s->fp, "\n");
758 status_printf(s, GIT_COLOR_NORMAL,
0b430a17 759 _("Please enter the commit message for your changes."));
ec84bd00 760 if (cleanup_mode == CLEANUP_ALL)
b926c0d1 761 status_printf_more(s, GIT_COLOR_NORMAL,
0b430a17 762 _(" Lines starting\n"
b926c0d1 763 "with '#' will be ignored, and an empty"
0b430a17 764 " message aborts the commit.\n"));
ec84bd00 765 else /* CLEANUP_SPACE, that is. */
b926c0d1 766 status_printf_more(s, GIT_COLOR_NORMAL,
0b430a17 767 _(" Lines starting\n"
b926c0d1 768 "with '#' will be kept; you may remove them"
fdc7c811 769 " yourself if you want to.\n"
0b430a17 770 "An empty message aborts the commit.\n"));
ec84bd00 771 if (only_include_assumed)
b926c0d1
JN
772 status_printf_ln(s, GIT_COLOR_NORMAL,
773 "%s", only_include_assumed);
ec84bd00 774
4c28e4ad
JH
775 ai_tmp = cut_ident_timestamp_part(author_ident->buf);
776 ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
777 if (strcmp(author_ident->buf, committer_ident.buf))
b926c0d1 778 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd
ÆAB
779 _("%s"
780 "Author: %s"),
b926c0d1 781 ident_shown++ ? "" : "\n",
4c28e4ad 782 author_ident->buf);
e83dbe80 783
5aeb3a3a 784 if (!user_ident_sufficiently_given())
b926c0d1 785 status_printf_ln(s, GIT_COLOR_NORMAL,
fe8165cd
ÆAB
786 _("%s"
787 "Committer: %s"),
b926c0d1 788 ident_shown++ ? "" : "\n",
4c28e4ad 789 committer_ident.buf);
bb1ae3f6
SB
790
791 if (ident_shown)
b926c0d1 792 status_printf_ln(s, GIT_COLOR_NORMAL, "");
bb1ae3f6 793
d249b098
JH
794 saved_color_setting = s->use_color;
795 s->use_color = 0;
37f3012f 796 commitable = run_status(s->fp, index_file, prefix, 1, s);
d249b098 797 s->use_color = saved_color_setting;
4c28e4ad
JH
798
799 *ai_tmp = ' ';
800 *ci_tmp = ' ';
ec84bd00 801 } else {
d616a239 802 unsigned char sha1[20];
fbcf1184 803 const char *parent = "HEAD";
7168624c 804
7168624c 805 if (!active_nr && read_cache() < 0)
8a6179bc 806 die(_("Cannot read index"));
7168624c 807
fbcf1184
JH
808 if (amend)
809 parent = "HEAD^1";
810
d616a239 811 if (get_sha1(parent, sha1))
ec84bd00 812 commitable = !!active_nr;
75f3ff2e
SB
813 else
814 commitable = index_differs_from(parent, 0);
ec84bd00 815 }
4c28e4ad 816 strbuf_release(&committer_ident);
d616a239 817
37f3012f 818 fclose(s->fp);
7168624c 819
37f7a857
JS
820 /*
821 * Reject an attempt to record a non-merge empty commit without
822 * explicit --allow-empty. In the cherry-pick case, it may be
823 * empty due to conflict resolution, which the user should okay.
824 */
825 if (!commitable && whence != FROM_MERGE && !allow_empty &&
ec84bd00 826 !(amend && is_a_merge(head_sha1))) {
d249b098 827 run_status(stdout, index_file, prefix, 0, s);
f197ed2f 828 if (amend)
fc88e316 829 fputs(_(empty_amend_advice), stderr);
37f7a857 830 else if (whence == FROM_CHERRY_PICK)
6c80cd29 831 fputs(_(empty_cherry_pick_advice), stderr);
ec84bd00 832 return 0;
7168624c
AR
833 }
834
ec84bd00
PB
835 /*
836 * Re-read the index as pre-commit hook could have updated it,
837 * and write it out as a tree. We must do this before we invoke
838 * the editor and after we invoke run_status above.
839 */
840 discard_cache();
841 read_cache_from(index_file);
842 if (!active_cache_tree)
843 active_cache_tree = cache_tree();
844 if (cache_tree_update(active_cache_tree,
845 active_cache, active_nr, 0, 0) < 0) {
8a6179bc 846 error(_("Error building trees"));
ec84bd00 847 return 0;
7168624c 848 }
f5bbc322 849
8089c85b
PB
850 if (run_hook(index_file, "prepare-commit-msg",
851 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
852 return 0;
f5bbc322 853
ec84bd00
PB
854 if (use_editor) {
855 char index[PATH_MAX];
66dbfd55
GV
856 const char *env[2] = { NULL };
857 env[0] = index;
ec84bd00 858 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
7198203a
SB
859 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
860 fprintf(stderr,
8a6179bc 861 _("Please supply the message using either -m or -F option.\n"));
7198203a
SB
862 exit(1);
863 }
ec84bd00 864 }
f5bbc322 865
ec84bd00
PB
866 if (!no_verify &&
867 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
868 return 0;
869 }
f5bbc322 870
ec84bd00 871 return 1;
f5bbc322
KH
872}
873
874/*
6bb6b034
MV
875 * Find out if the message in the strbuf contains only whitespace and
876 * Signed-off-by lines.
f5bbc322 877 */
6bb6b034 878static int message_is_empty(struct strbuf *sb)
f5bbc322 879{
f285a2d7 880 struct strbuf tmpl = STRBUF_INIT;
f5bbc322 881 const char *nl;
6bb6b034 882 int eol, i, start = 0;
f5bbc322 883
5f065737
AR
884 if (cleanup_mode == CLEANUP_NONE && sb->len)
885 return 0;
886
f5bbc322 887 /* See if the template is just a prefix of the message. */
f5bbc322 888 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
5f065737 889 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
f5bbc322
KH
890 if (start + tmpl.len <= sb->len &&
891 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
892 start += tmpl.len;
893 }
894 strbuf_release(&tmpl);
895
896 /* Check if the rest is just whitespace and Signed-of-by's. */
897 for (i = start; i < sb->len; i++) {
898 nl = memchr(sb->buf + i, '\n', sb->len - i);
899 if (nl)
900 eol = nl - sb->buf;
901 else
902 eol = sb->len;
903
904 if (strlen(sign_off_header) <= eol - i &&
905 !prefixcmp(sb->buf + i, sign_off_header)) {
906 i = eol;
907 continue;
908 }
909 while (i < eol)
910 if (!isspace(sb->buf[i++]))
911 return 0;
912 }
913
914 return 1;
915}
916
146ea068
JH
917static const char *find_author_by_nickname(const char *name)
918{
919 struct rev_info revs;
920 struct commit *commit;
921 struct strbuf buf = STRBUF_INIT;
922 const char *av[20];
923 int ac = 0;
924
925 init_revisions(&revs, NULL);
926 strbuf_addf(&buf, "--author=%s", name);
927 av[++ac] = "--all";
928 av[++ac] = "-i";
929 av[++ac] = buf.buf;
930 av[++ac] = NULL;
931 setup_revisions(ac, av, &revs, NULL);
932 prepare_revision_walk(&revs);
933 commit = get_revision(&revs);
934 if (commit) {
dd2e794a
TR
935 struct pretty_print_context ctx = {0};
936 ctx.date_mode = DATE_NORMAL;
146ea068 937 strbuf_release(&buf);
dd2e794a 938 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
146ea068
JH
939 return strbuf_detach(&buf, NULL);
940 }
8a6179bc 941 die(_("No existing author found with '%s'"), name);
146ea068
JH
942}
943
76e2f7ce
JH
944
945static void handle_untracked_files_arg(struct wt_status *s)
946{
947 if (!untracked_files_arg)
948 ; /* default already initialized */
949 else if (!strcmp(untracked_files_arg, "no"))
950 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
951 else if (!strcmp(untracked_files_arg, "normal"))
952 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
953 else if (!strcmp(untracked_files_arg, "all"))
954 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
955 else
8a6179bc 956 die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
76e2f7ce
JH
957}
958
37f7a857
JS
959static const char *read_commit_message(const char *name)
960{
961 const char *out_enc, *out;
962 struct commit *commit;
963
964 commit = lookup_commit_reference_by_name(name);
965 if (!commit)
6c80cd29 966 die(_("could not lookup commit %s"), name);
37f7a857
JS
967 out_enc = get_commit_output_encoding();
968 out = logmsg_reencode(commit, out_enc);
969
970 /*
971 * If we failed to reencode the buffer, just copy it
972 * byte for byte so the user can try to fix it up.
973 * This also handles the case where input and output
974 * encodings are identical.
975 */
976 if (out == NULL)
977 out = xstrdup(commit->buffer);
978 return out;
979}
980
2f02b25f 981static int parse_and_validate_options(int argc, const char *argv[],
dbd0f5c7 982 const char * const usage[],
d249b098
JH
983 const char *prefix,
984 struct wt_status *s)
f5bbc322
KH
985{
986 int f = 0;
987
37782920
SB
988 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
989 0);
f5bbc322 990
146ea068
JH
991 if (force_author && !strchr(force_author, '>'))
992 force_author = find_author_by_nickname(force_author);
993
c51f6cee 994 if (force_author && renew_authorship)
8a6179bc 995 die(_("Using both --reset-author and --author does not make sense"));
c51f6cee 996
d71b8ba7 997 if (logfile || message.len || use_message || fixup_message)
4803466f 998 use_editor = 0;
f5bbc322 999 if (edit_flag)
4803466f 1000 use_editor = 1;
406400ce
PB
1001 if (!use_editor)
1002 setenv("GIT_EDITOR", ":", 1);
f5bbc322
KH
1003
1004 if (get_sha1("HEAD", head_sha1))
1005 initial_commit = 1;
1006
f5bbc322
KH
1007 /* Sanity check options */
1008 if (amend && initial_commit)
8a6179bc 1009 die(_("You have nothing to amend."));
37f7a857 1010 if (amend && whence != FROM_COMMIT)
6c80cd29 1011 die(_("You are in the middle of a %s -- cannot amend."), whence_s());
89ac1223 1012 if (fixup_message && squash_message)
9c227655 1013 die(_("Options --squash and --fixup cannot be used together"));
f5bbc322
KH
1014 if (use_message)
1015 f++;
1016 if (edit_message)
1017 f++;
d71b8ba7
PN
1018 if (fixup_message)
1019 f++;
f5bbc322
KH
1020 if (logfile)
1021 f++;
1022 if (f > 1)
8a6179bc 1023 die(_("Only one of -c/-C/-F/--fixup can be used."));
f9568530 1024 if (message.len && f > 0)
8a6179bc 1025 die((_("Option -m cannot be combined with -c/-C/-F/--fixup.")));
f5bbc322
KH
1026 if (edit_message)
1027 use_message = edit_message;
d71b8ba7 1028 if (amend && !use_message && !fixup_message)
f5bbc322 1029 use_message = "HEAD";
37f7a857 1030 if (!use_message && whence != FROM_CHERRY_PICK && renew_authorship)
8a6179bc 1031 die(_("--reset-author can be used only with -C, -c or --amend."));
f5bbc322 1032 if (use_message) {
37f7a857
JS
1033 use_message_buffer = read_commit_message(use_message);
1034 if (!renew_authorship) {
1035 author_message = use_message;
1036 author_message_buffer = use_message_buffer;
1037 }
1038 }
1039 if (whence == FROM_CHERRY_PICK && !renew_authorship) {
1040 author_message = "CHERRY_PICK_HEAD";
1041 author_message_buffer = read_commit_message(author_message);
f5bbc322
KH
1042 }
1043
1044 if (!!also + !!only + !!all + !!interactive > 1)
8a6179bc 1045 die(_("Only one of --include/--only/--all/--interactive can be used."));
f5bbc322 1046 if (argc == 0 && (also || (only && !amend)))
8a6179bc 1047 die(_("No paths with --include/--only does not make sense."));
f5bbc322 1048 if (argc == 0 && only && amend)
8a6179bc 1049 only_include_assumed = _("Clever... amending the last one with dirty index.");
3c5283f8 1050 if (argc > 0 && !also && !only)
8a6179bc 1051 only_include_assumed = _("Explicit paths specified without -i nor -o; assuming --only paths...");
5f065737
AR
1052 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
1053 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
1054 else if (!strcmp(cleanup_arg, "verbatim"))
1055 cleanup_mode = CLEANUP_NONE;
1056 else if (!strcmp(cleanup_arg, "whitespace"))
1057 cleanup_mode = CLEANUP_SPACE;
1058 else if (!strcmp(cleanup_arg, "strip"))
1059 cleanup_mode = CLEANUP_ALL;
1060 else
8a6179bc 1061 die(_("Invalid cleanup mode %s"), cleanup_arg);
f5bbc322 1062
76e2f7ce 1063 handle_untracked_files_arg(s);
4bfee30a 1064
f5bbc322 1065 if (all && argc > 0)
8a6179bc 1066 die(_("Paths with -a does not make sense."));
f5bbc322 1067 else if (interactive && argc > 0)
8a6179bc 1068 die(_("Paths with --interactive does not make sense."));
f5bbc322 1069
7c9f7038
JK
1070 if (null_termination && status_format == STATUS_FORMAT_LONG)
1071 status_format = STATUS_FORMAT_PORCELAIN;
1072 if (status_format != STATUS_FORMAT_LONG)
1073 dry_run = 1;
1074
f5bbc322
KH
1075 return argc;
1076}
1077
d249b098
JH
1078static int dry_run_commit(int argc, const char **argv, const char *prefix,
1079 struct wt_status *s)
f5bbc322 1080{
f5bbc322 1081 int commitable;
3a5d13a3 1082 const char *index_file;
f5bbc322 1083
3a5d13a3 1084 index_file = prepare_index(argc, argv, prefix, 1);
d249b098 1085 commitable = run_status(stdout, index_file, prefix, 0, s);
3a5d13a3 1086 rollback_index_files();
f5bbc322 1087
3a5d13a3
JH
1088 return commitable ? 0 : 1;
1089}
1090
f766b367
JH
1091static int parse_status_slot(const char *var, int offset)
1092{
1093 if (!strcasecmp(var+offset, "header"))
1094 return WT_STATUS_HEADER;
1d282327
AA
1095 if (!strcasecmp(var+offset, "branch"))
1096 return WT_STATUS_ONBRANCH;
f766b367
JH
1097 if (!strcasecmp(var+offset, "updated")
1098 || !strcasecmp(var+offset, "added"))
1099 return WT_STATUS_UPDATED;
1100 if (!strcasecmp(var+offset, "changed"))
1101 return WT_STATUS_CHANGED;
1102 if (!strcasecmp(var+offset, "untracked"))
1103 return WT_STATUS_UNTRACKED;
1104 if (!strcasecmp(var+offset, "nobranch"))
1105 return WT_STATUS_NOBRANCH;
1106 if (!strcasecmp(var+offset, "unmerged"))
1107 return WT_STATUS_UNMERGED;
8b8e8624 1108 return -1;
f766b367
JH
1109}
1110
1111static int git_status_config(const char *k, const char *v, void *cb)
1112{
1113 struct wt_status *s = cb;
1114
1115 if (!strcmp(k, "status.submodulesummary")) {
1116 int is_bool;
1117 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
1118 if (is_bool && s->submodule_summary)
1119 s->submodule_summary = -1;
1120 return 0;
1121 }
1122 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
1123 s->use_color = git_config_colorbool(k, v, -1);
1124 return 0;
1125 }
1126 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
1127 int slot = parse_status_slot(k, 13);
8b8e8624
JK
1128 if (slot < 0)
1129 return 0;
f766b367
JH
1130 if (!v)
1131 return config_error_nonbool(k);
1132 color_parse(v, k, s->color_palette[slot]);
1133 return 0;
1134 }
1135 if (!strcmp(k, "status.relativepaths")) {
1136 s->relative_paths = git_config_bool(k, v);
1137 return 0;
1138 }
1139 if (!strcmp(k, "status.showuntrackedfiles")) {
1140 if (!v)
1141 return config_error_nonbool(k);
1142 else if (!strcmp(v, "no"))
1143 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
1144 else if (!strcmp(v, "normal"))
1145 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
1146 else if (!strcmp(v, "all"))
1147 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
1148 else
8a6179bc 1149 return error(_("Invalid untracked files mode '%s'"), v);
f766b367
JH
1150 return 0;
1151 }
1152 return git_diff_ui_config(k, v, NULL);
1153}
1154
3a5d13a3
JH
1155int cmd_status(int argc, const char **argv, const char *prefix)
1156{
d249b098 1157 struct wt_status s;
4bb6644d 1158 int fd;
76e2f7ce 1159 unsigned char sha1[20];
9e4b7ab6 1160 static struct option builtin_status_options[] = {
fd03881a 1161 OPT__VERBOSE(&verbose, "be verbose"),
dd2be243
JK
1162 OPT_SET_INT('s', "short", &status_format,
1163 "show status concisely", STATUS_FORMAT_SHORT),
05a59a08
DKF
1164 OPT_BOOLEAN('b', "branch", &status_show_branch,
1165 "show branch information"),
6f157871 1166 OPT_SET_INT(0, "porcelain", &status_format,
ba9d7fe1 1167 "machine-readable output",
6f157871 1168 STATUS_FORMAT_PORCELAIN),
173e6c88
JH
1169 OPT_BOOLEAN('z', "null", &null_termination,
1170 "terminate entries with NUL"),
76e2f7ce
JH
1171 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1172 "mode",
1173 "show untracked files, optional modes: all, normal, no. (Default: all)",
1174 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
2381e39e
JH
1175 OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
1176 "show ignored files"),
46a958b3
JL
1177 { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
1178 "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
1179 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
76e2f7ce
JH
1180 OPT_END(),
1181 };
1182
5d3dd915
NTND
1183 if (argc == 2 && !strcmp(argv[1], "-h"))
1184 usage_with_options(builtin_status_usage, builtin_status_options);
1185
dd2be243 1186 if (null_termination && status_format == STATUS_FORMAT_LONG)
6f157871 1187 status_format = STATUS_FORMAT_PORCELAIN;
d249b098
JH
1188
1189 wt_status_prepare(&s);
302ad7a9 1190 gitmodules_config();
d249b098 1191 git_config(git_status_config, &s);
37f7a857 1192 determine_whence(&s);
76e2f7ce 1193 argc = parse_options(argc, argv, prefix,
9e4b7ab6
JH
1194 builtin_status_options,
1195 builtin_status_usage, 0);
76e2f7ce 1196 handle_untracked_files_arg(&s);
2381e39e
JH
1197 if (show_ignored_in_status)
1198 s.show_ignored_files = 1;
76e2f7ce
JH
1199 if (*argv)
1200 s.pathspec = get_pathspec(prefix, argv);
1201
149794dd 1202 read_cache_preload(s.pathspec);
688cd6d2 1203 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
4bb6644d
MH
1204
1205 fd = hold_locked_index(&index_lock, 0);
ccdc4ec3
JH
1206 if (0 <= fd)
1207 update_index_if_able(&the_index, &index_lock);
4bb6644d 1208
76e2f7ce 1209 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
46a958b3 1210 s.ignore_submodule_arg = ignore_submodule_arg;
76e2f7ce
JH
1211 wt_status_collect(&s);
1212
8661768f
JK
1213 if (s.relative_paths)
1214 s.prefix = prefix;
d249b098
JH
1215 if (s.use_color == -1)
1216 s.use_color = git_use_color_default;
38920dd6
MH
1217 if (diff_use_color_default == -1)
1218 diff_use_color_default = git_use_color_default;
1219
dd2be243
JK
1220 switch (status_format) {
1221 case STATUS_FORMAT_SHORT:
05a59a08 1222 wt_shortstatus_print(&s, null_termination, status_show_branch);
dd2be243 1223 break;
6f157871 1224 case STATUS_FORMAT_PORCELAIN:
4a7cc2fd 1225 wt_porcelain_print(&s, null_termination);
6f157871 1226 break;
dd2be243 1227 case STATUS_FORMAT_LONG:
173e6c88 1228 s.verbose = verbose;
46a958b3 1229 s.ignore_submodule_arg = ignore_submodule_arg;
173e6c88 1230 wt_status_print(&s);
dd2be243 1231 break;
173e6c88 1232 }
76e2f7ce 1233 return 0;
f5bbc322
KH
1234}
1235
f5bbc322
KH
1236static void print_summary(const char *prefix, const unsigned char *sha1)
1237{
1238 struct rev_info rev;
1239 struct commit *commit;
49ff9a7a 1240 struct strbuf format = STRBUF_INIT;
c85db254
JK
1241 unsigned char junk_sha1[20];
1242 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
49ff9a7a
JK
1243 struct pretty_print_context pctx = {0};
1244 struct strbuf author_ident = STRBUF_INIT;
1245 struct strbuf committer_ident = STRBUF_INIT;
f5bbc322
KH
1246
1247 commit = lookup_commit(sha1);
1248 if (!commit)
8a6179bc 1249 die(_("couldn't look up newly created commit"));
f5bbc322 1250 if (!commit || parse_commit(commit))
8a6179bc 1251 die(_("could not parse newly created commit"));
f5bbc322 1252
49ff9a7a
JK
1253 strbuf_addstr(&format, "format:%h] %s");
1254
1255 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
1256 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
1257 if (strbuf_cmp(&author_ident, &committer_ident)) {
1258 strbuf_addstr(&format, "\n Author: ");
1259 strbuf_addbuf_percentquote(&format, &author_ident);
1260 }
1a893064 1261 if (!user_ident_sufficiently_given()) {
49ff9a7a
JK
1262 strbuf_addstr(&format, "\n Committer: ");
1263 strbuf_addbuf_percentquote(&format, &committer_ident);
b706fcfe
JK
1264 if (advice_implicit_identity) {
1265 strbuf_addch(&format, '\n');
fc88e316 1266 strbuf_addstr(&format, _(implicit_ident_advice));
b706fcfe 1267 }
49ff9a7a
JK
1268 }
1269 strbuf_release(&author_ident);
1270 strbuf_release(&committer_ident);
1271
f5bbc322
KH
1272 init_revisions(&rev, prefix);
1273 setup_revisions(0, NULL, &rev, NULL);
1274
f5bbc322
KH
1275 rev.diff = 1;
1276 rev.diffopt.output_format =
1277 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1278
1279 rev.verbose_header = 1;
1280 rev.show_root_diff = 1;
49ff9a7a 1281 get_commit_format(format.buf, &rev);
bf82a150 1282 rev.always_show_header = 0;
3eb2a15e 1283 rev.diffopt.detect_rename = 1;
3eb2a15e 1284 rev.diffopt.break_opt = 0;
15964563 1285 diff_setup_done(&rev.diffopt);
f5bbc322 1286
c5ee71fd 1287 printf("[%s%s ",
c85db254
JK
1288 !prefixcmp(head, "refs/heads/") ?
1289 head + 11 :
1290 !strcmp(head, "HEAD") ?
7f5673d7 1291 _("detached HEAD") :
c85db254 1292 head,
7f5673d7 1293 initial_commit ? _(" (root-commit)") : "");
f5bbc322 1294
bf82a150 1295 if (!log_tree_commit(&rev, commit)) {
a45e1a87
TRC
1296 rev.always_show_header = 1;
1297 rev.use_terminator = 1;
1298 log_tree_commit(&rev, commit);
bf82a150 1299 }
a45e1a87 1300
fc6f19fe 1301 strbuf_release(&format);
f5bbc322
KH
1302}
1303
186458b1 1304static int git_commit_config(const char *k, const char *v, void *cb)
f5bbc322 1305{
d249b098
JH
1306 struct wt_status *s = cb;
1307
984c6e7e 1308 if (!strcmp(k, "commit.template"))
395de250 1309 return git_config_pathname(&template_file, k, v);
bed575e4
JHI
1310 if (!strcmp(k, "commit.status")) {
1311 include_status = git_config_bool(k, v);
1312 return 0;
1313 }
f5bbc322 1314
d249b098 1315 return git_status_config(k, v, s);
f5bbc322
KH
1316}
1317
6f6bee3b
TR
1318static const char post_rewrite_hook[] = "hooks/post-rewrite";
1319
1320static int run_rewrite_hook(const unsigned char *oldsha1,
1321 const unsigned char *newsha1)
1322{
1323 /* oldsha1 SP newsha1 LF NUL */
1324 static char buf[2*40 + 3];
1325 struct child_process proc;
1326 const char *argv[3];
1327 int code;
1328 size_t n;
1329
1330 if (access(git_path(post_rewrite_hook), X_OK) < 0)
1331 return 0;
1332
1333 argv[0] = git_path(post_rewrite_hook);
1334 argv[1] = "amend";
1335 argv[2] = NULL;
1336
1337 memset(&proc, 0, sizeof(proc));
1338 proc.argv = argv;
1339 proc.in = -1;
1340 proc.stdout_to_stderr = 1;
1341
1342 code = start_command(&proc);
1343 if (code)
1344 return code;
1345 n = snprintf(buf, sizeof(buf), "%s %s\n",
1346 sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1347 write_in_full(proc.in, buf, n);
1348 close(proc.in);
1349 return finish_command(&proc);
1350}
1351
f5bbc322
KH
1352int cmd_commit(int argc, const char **argv, const char *prefix)
1353{
f285a2d7 1354 struct strbuf sb = STRBUF_INIT;
4c28e4ad 1355 struct strbuf author_ident = STRBUF_INIT;
f5bbc322 1356 const char *index_file, *reflog_msg;
99a12694 1357 char *nl, *p;
f5bbc322
KH
1358 unsigned char commit_sha1[20];
1359 struct ref_lock *ref_lock;
6bb6b034 1360 struct commit_list *parents = NULL, **pptr = &parents;
cf10f9fd
MV
1361 struct stat statbuf;
1362 int allow_fast_forward = 1;
d249b098 1363 struct wt_status s;
f5bbc322 1364
5d3dd915
NTND
1365 if (argc == 2 && !strcmp(argv[1], "-h"))
1366 usage_with_options(builtin_commit_usage, builtin_commit_options);
1367
d249b098
JH
1368 wt_status_prepare(&s);
1369 git_config(git_commit_config, &s);
37f7a857 1370 determine_whence(&s);
f5bbc322 1371
d249b098
JH
1372 if (s.use_color == -1)
1373 s.use_color = git_use_color_default;
d249b098
JH
1374 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1375 prefix, &s);
3fa509df
JH
1376 if (dry_run) {
1377 if (diff_use_color_default == -1)
1378 diff_use_color_default = git_use_color_default;
d249b098 1379 return dry_run_commit(argc, argv, prefix, &s);
3fa509df 1380 }
50b7e70f 1381 index_file = prepare_index(argc, argv, prefix, 0);
f5bbc322 1382
ec84bd00
PB
1383 /* Set up everything for writing the commit object. This includes
1384 running hooks, writing the trees, and interacting with the user. */
4c28e4ad 1385 if (!prepare_to_commit(index_file, prefix, &s, &author_ident)) {
2888605c 1386 rollback_index_files();
f5bbc322
KH
1387 return 1;
1388 }
1389
f5bbc322 1390 /* Determine parents */
643cb5f7 1391 reflog_msg = getenv("GIT_REFLOG_ACTION");
f5bbc322 1392 if (initial_commit) {
643cb5f7
CC
1393 if (!reflog_msg)
1394 reflog_msg = "commit (initial)";
f5bbc322
KH
1395 } else if (amend) {
1396 struct commit_list *c;
1397 struct commit *commit;
1398
643cb5f7
CC
1399 if (!reflog_msg)
1400 reflog_msg = "commit (amend)";
f5bbc322
KH
1401 commit = lookup_commit(head_sha1);
1402 if (!commit || parse_commit(commit))
8a6179bc 1403 die(_("could not parse HEAD commit"));
f5bbc322
KH
1404
1405 for (c = commit->parents; c; c = c->next)
6bb6b034 1406 pptr = &commit_list_insert(c->item, pptr)->next;
37f7a857 1407 } else if (whence == FROM_MERGE) {
f285a2d7 1408 struct strbuf m = STRBUF_INIT;
f5bbc322
KH
1409 FILE *fp;
1410
643cb5f7
CC
1411 if (!reflog_msg)
1412 reflog_msg = "commit (merge)";
6bb6b034 1413 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
f5bbc322
KH
1414 fp = fopen(git_path("MERGE_HEAD"), "r");
1415 if (fp == NULL)
8a6179bc 1416 die_errno(_("could not open '%s' for reading"),
d824cbba 1417 git_path("MERGE_HEAD"));
7c3fd25d
LT
1418 while (strbuf_getline(&m, fp, '\n') != EOF) {
1419 unsigned char sha1[20];
1420 if (get_sha1_hex(m.buf, sha1) < 0)
8a6179bc 1421 die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
6bb6b034 1422 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
7c3fd25d 1423 }
f5bbc322
KH
1424 fclose(fp);
1425 strbuf_release(&m);
cf10f9fd
MV
1426 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1427 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
8a6179bc 1428 die_errno(_("could not read MERGE_MODE"));
cf10f9fd
MV
1429 if (!strcmp(sb.buf, "no-ff"))
1430 allow_fast_forward = 0;
1431 }
1432 if (allow_fast_forward)
1433 parents = reduce_heads(parents);
f5bbc322 1434 } else {
643cb5f7 1435 if (!reflog_msg)
37f7a857
JS
1436 reflog_msg = (whence == FROM_CHERRY_PICK)
1437 ? "commit (cherry-pick)"
1438 : "commit";
6bb6b034 1439 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
f5bbc322 1440 }
f5bbc322 1441
ec84bd00 1442 /* Finally, get the commit message */
cf10f9fd 1443 strbuf_reset(&sb);
740001a5 1444 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
0721c314 1445 int saved_errno = errno;
740001a5 1446 rollback_index_files();
8a6179bc 1447 die(_("could not read commit message: %s"), strerror(saved_errno));
740001a5 1448 }
99a12694
KH
1449
1450 /* Truncate the message just before the diff, if any. */
0b38227f
JK
1451 if (verbose) {
1452 p = strstr(sb.buf, "\ndiff --git ");
1453 if (p != NULL)
1454 strbuf_setlen(&sb, p - sb.buf + 1);
1455 }
99a12694 1456
5f065737
AR
1457 if (cleanup_mode != CLEANUP_NONE)
1458 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
c9b5fde7 1459 if (message_is_empty(&sb) && !allow_empty_message) {
2888605c 1460 rollback_index_files();
8a6179bc 1461 fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
fdc7c811 1462 exit(1);
2888605c 1463 }
f5bbc322 1464
6bb6b034 1465 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
4c28e4ad 1466 author_ident.buf)) {
2888605c 1467 rollback_index_files();
8a6179bc 1468 die(_("failed to write commit object"));
2888605c 1469 }
4c28e4ad 1470 strbuf_release(&author_ident);
f5bbc322
KH
1471
1472 ref_lock = lock_any_ref_for_update("HEAD",
1473 initial_commit ? NULL : head_sha1,
1474 0);
1475
6bb6b034 1476 nl = strchr(sb.buf, '\n');
741707b1
JS
1477 if (nl)
1478 strbuf_setlen(&sb, nl + 1 - sb.buf);
1479 else
1480 strbuf_addch(&sb, '\n');
741707b1
JS
1481 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1482 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
f5bbc322 1483
2888605c
JH
1484 if (!ref_lock) {
1485 rollback_index_files();
8a6179bc 1486 die(_("cannot lock HEAD ref"));
2888605c
JH
1487 }
1488 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1489 rollback_index_files();
8a6179bc 1490 die(_("cannot update HEAD ref"));
2888605c 1491 }
f5bbc322 1492
d7e5c0cb 1493 unlink(git_path("CHERRY_PICK_HEAD"));
f5bbc322
KH
1494 unlink(git_path("MERGE_HEAD"));
1495 unlink(git_path("MERGE_MSG"));
cf10f9fd 1496 unlink(git_path("MERGE_MODE"));
5a95b855 1497 unlink(git_path("SQUASH_MSG"));
f5bbc322 1498
5a9dd399 1499 if (commit_index_files())
8a6179bc 1500 die (_("Repository has been updated, but unable to write\n"
5a9dd399 1501 "new_index file. Check that disk is not full or quota is\n"
8a6179bc 1502 "not exceeded, and then \"git reset HEAD\" to recover."));
f5bbc322 1503
cb6020bb 1504 rerere(0);
2888605c 1505 run_hook(get_index_file(), "post-commit", NULL);
6f6bee3b 1506 if (amend && !no_post_rewrite) {
6360d343
TR
1507 struct notes_rewrite_cfg *cfg;
1508 cfg = init_copy_notes_for_rewrite("amend");
1509 if (cfg) {
1510 copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
1511 finish_copy_notes_for_rewrite(cfg);
1512 }
6f6bee3b
TR
1513 run_rewrite_hook(head_sha1, commit_sha1);
1514 }
f5bbc322
KH
1515 if (!quiet)
1516 print_summary(prefix, commit_sha1);
1517
1518 return 0;
1519}