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