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