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