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