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