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