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