revert: accept arbitrary rev-list options
[git/dscho.git] / builtin / commit.c
blobddf77e48e1d9fa1e6db0ac49008857b85a9b5e41
1 /*
2 * Builtin "git commit"
4 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
5 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
6 */
8 #include "cache.h"
9 #include "cache-tree.h"
10 #include "color.h"
11 #include "dir.h"
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"
24 #include "string-list.h"
25 #include "rerere.h"
26 #include "unpack-trees.h"
27 #include "quote.h"
29 static const char * const builtin_commit_usage[] = {
30 "git commit [options] [--] <filepattern>...",
31 NULL
34 static const char * const builtin_status_usage[] = {
35 "git status [options] [--] <filepattern>...",
36 NULL
39 static const char implicit_ident_advice[] =
40 "Your name and email address were configured automatically based\n"
41 "on your username and hostname. Please check that they are accurate.\n"
42 "You can suppress this message by setting them explicitly:\n"
43 "\n"
44 " git config --global user.name \"Your Name\"\n"
45 " git config --global user.email you@example.com\n"
46 "\n"
47 "If the identity used for this commit is wrong, you can fix it with:\n"
48 "\n"
49 " git commit --amend --author='Your Name <you@example.com>'\n";
51 static unsigned char head_sha1[20];
53 static char *use_message_buffer;
54 static const char commit_editmsg[] = "COMMIT_EDITMSG";
55 static struct lock_file index_lock; /* real index */
56 static struct lock_file false_lock; /* used only for partial commits */
57 static enum {
58 COMMIT_AS_IS = 1,
59 COMMIT_NORMAL,
60 COMMIT_PARTIAL,
61 } commit_style;
63 static const char *logfile, *force_author;
64 static const char *template_file;
65 static char *edit_message, *use_message;
66 static char *author_name, *author_email, *author_date;
67 static int all, edit_flag, also, interactive, only, amend, signoff;
68 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69 static int no_post_rewrite, allow_empty_message;
70 static char *untracked_files_arg, *force_date;
72 * The default commit message cleanup mode will remove the lines
73 * beginning with # (shell comments) and leading and trailing
74 * whitespaces (empty lines or containing only whitespaces)
75 * if editor is used, and only the whitespaces if the message
76 * is specified explicitly.
78 static enum {
79 CLEANUP_SPACE,
80 CLEANUP_NONE,
81 CLEANUP_ALL,
82 } cleanup_mode;
83 static char *cleanup_arg;
85 static int use_editor = 1, initial_commit, in_merge, include_status = 1;
86 static int show_ignored_in_status;
87 static const char *only_include_assumed;
88 static struct strbuf message;
90 static int null_termination;
91 static enum {
92 STATUS_FORMAT_LONG,
93 STATUS_FORMAT_SHORT,
94 STATUS_FORMAT_PORCELAIN,
95 } status_format = STATUS_FORMAT_LONG;
97 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
99 struct strbuf *buf = opt->value;
100 if (unset)
101 strbuf_setlen(buf, 0);
102 else {
103 strbuf_addstr(buf, arg);
104 strbuf_addstr(buf, "\n\n");
106 return 0;
109 static struct option builtin_commit_options[] = {
110 OPT__QUIET(&quiet),
111 OPT__VERBOSE(&verbose),
113 OPT_GROUP("Commit message options"),
114 OPT_FILENAME('F', "file", &logfile, "read log from file"),
115 OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
116 OPT_STRING(0, "date", &force_date, "DATE", "override date for commit"),
117 OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
118 OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
119 OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
120 OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
121 OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
122 OPT_FILENAME('t', "template", &template_file, "use specified template file"),
123 OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
124 OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
125 OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
126 /* end commit message options */
128 OPT_GROUP("Commit contents options"),
129 OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
130 OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
131 OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
132 OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
133 OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
134 OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
135 OPT_SET_INT(0, "short", &status_format, "show status concisely",
136 STATUS_FORMAT_SHORT),
137 OPT_SET_INT(0, "porcelain", &status_format,
138 "show porcelain output format", STATUS_FORMAT_PORCELAIN),
139 OPT_BOOLEAN('z', "null", &null_termination,
140 "terminate entries with NUL"),
141 OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
142 OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
143 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
144 /* end commit contents options */
146 { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
147 "ok to record an empty change",
148 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
149 { OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
150 "ok to record a change with an empty message",
151 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
153 OPT_END()
156 static void rollback_index_files(void)
158 switch (commit_style) {
159 case COMMIT_AS_IS:
160 break; /* nothing to do */
161 case COMMIT_NORMAL:
162 rollback_lock_file(&index_lock);
163 break;
164 case COMMIT_PARTIAL:
165 rollback_lock_file(&index_lock);
166 rollback_lock_file(&false_lock);
167 break;
171 static int commit_index_files(void)
173 int err = 0;
175 switch (commit_style) {
176 case COMMIT_AS_IS:
177 break; /* nothing to do */
178 case COMMIT_NORMAL:
179 err = commit_lock_file(&index_lock);
180 break;
181 case COMMIT_PARTIAL:
182 err = commit_lock_file(&index_lock);
183 rollback_lock_file(&false_lock);
184 break;
187 return err;
191 * Take a union of paths in the index and the named tree (typically, "HEAD"),
192 * and return the paths that match the given pattern in list.
194 static int list_paths(struct string_list *list, const char *with_tree,
195 const char *prefix, const char **pattern)
197 int i;
198 char *m;
200 for (i = 0; pattern[i]; i++)
202 m = xcalloc(1, i);
204 if (with_tree)
205 overlay_tree_on_cache(with_tree, prefix);
207 for (i = 0; i < active_nr; i++) {
208 struct cache_entry *ce = active_cache[i];
209 struct string_list_item *item;
211 if (ce->ce_flags & CE_UPDATE)
212 continue;
213 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
214 continue;
215 item = string_list_insert(ce->name, list);
216 if (ce_skip_worktree(ce))
217 item->util = item; /* better a valid pointer than a fake one */
220 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
223 static void add_remove_files(struct string_list *list)
225 int i;
226 for (i = 0; i < list->nr; i++) {
227 struct stat st;
228 struct string_list_item *p = &(list->items[i]);
230 /* p->util is skip-worktree */
231 if (p->util)
232 continue;
234 if (!lstat(p->string, &st)) {
235 if (add_to_cache(p->string, &st, 0))
236 die("updating files failed");
237 } else
238 remove_file_from_cache(p->string);
242 static void create_base_index(void)
244 struct tree *tree;
245 struct unpack_trees_options opts;
246 struct tree_desc t;
248 if (initial_commit) {
249 discard_cache();
250 return;
253 memset(&opts, 0, sizeof(opts));
254 opts.head_idx = 1;
255 opts.index_only = 1;
256 opts.merge = 1;
257 opts.src_index = &the_index;
258 opts.dst_index = &the_index;
260 opts.fn = oneway_merge;
261 tree = parse_tree_indirect(head_sha1);
262 if (!tree)
263 die("failed to unpack HEAD tree object");
264 parse_tree(tree);
265 init_tree_desc(&t, tree->buffer, tree->size);
266 if (unpack_trees(1, &t, &opts))
267 exit(128); /* We've already reported the error, finish dying */
270 static void refresh_cache_or_die(int refresh_flags)
273 * refresh_flags contains REFRESH_QUIET, so the only errors
274 * are for unmerged entries.
276 if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
277 die_resolve_conflict("commit");
280 static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
282 int fd;
283 struct string_list partial;
284 const char **pathspec = NULL;
285 int refresh_flags = REFRESH_QUIET;
287 if (is_status)
288 refresh_flags |= REFRESH_UNMERGED;
289 if (interactive) {
290 if (interactive_add(argc, argv, prefix) != 0)
291 die("interactive add failed");
292 if (read_cache_preload(NULL) < 0)
293 die("index file corrupt");
294 commit_style = COMMIT_AS_IS;
295 return get_index_file();
298 if (*argv)
299 pathspec = get_pathspec(prefix, argv);
301 if (read_cache_preload(pathspec) < 0)
302 die("index file corrupt");
305 * Non partial, non as-is commit.
307 * (1) get the real index;
308 * (2) update the_index as necessary;
309 * (3) write the_index out to the real index (still locked);
310 * (4) return the name of the locked index file.
312 * The caller should run hooks on the locked real index, and
313 * (A) if all goes well, commit the real index;
314 * (B) on failure, rollback the real index.
316 if (all || (also && pathspec && *pathspec)) {
317 fd = hold_locked_index(&index_lock, 1);
318 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
319 refresh_cache_or_die(refresh_flags);
320 if (write_cache(fd, active_cache, active_nr) ||
321 close_lock_file(&index_lock))
322 die("unable to write new_index file");
323 commit_style = COMMIT_NORMAL;
324 return index_lock.filename;
328 * As-is commit.
330 * (1) return the name of the real index file.
332 * The caller should run hooks on the real index,
333 * and create commit from the_index.
334 * We still need to refresh the index here.
336 if (!pathspec || !*pathspec) {
337 fd = hold_locked_index(&index_lock, 1);
338 refresh_cache_or_die(refresh_flags);
339 if (write_cache(fd, active_cache, active_nr) ||
340 commit_locked_index(&index_lock))
341 die("unable to write new_index file");
342 commit_style = COMMIT_AS_IS;
343 return get_index_file();
347 * A partial commit.
349 * (0) find the set of affected paths;
350 * (1) get lock on the real index file;
351 * (2) update the_index with the given paths;
352 * (3) write the_index out to the real index (still locked);
353 * (4) get lock on the false index file;
354 * (5) reset the_index from HEAD;
355 * (6) update the_index the same way as (2);
356 * (7) write the_index out to the false index file;
357 * (8) return the name of the false index file (still locked);
359 * The caller should run hooks on the locked false index, and
360 * create commit from it. Then
361 * (A) if all goes well, commit the real index;
362 * (B) on failure, rollback the real index;
363 * In either case, rollback the false index.
365 commit_style = COMMIT_PARTIAL;
367 if (in_merge)
368 die("cannot do a partial commit during a merge.");
370 memset(&partial, 0, sizeof(partial));
371 partial.strdup_strings = 1;
372 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
373 exit(1);
375 discard_cache();
376 if (read_cache() < 0)
377 die("cannot read the index");
379 fd = hold_locked_index(&index_lock, 1);
380 add_remove_files(&partial);
381 refresh_cache(REFRESH_QUIET);
382 if (write_cache(fd, active_cache, active_nr) ||
383 close_lock_file(&index_lock))
384 die("unable to write new_index file");
386 fd = hold_lock_file_for_update(&false_lock,
387 git_path("next-index-%"PRIuMAX,
388 (uintmax_t) getpid()),
389 LOCK_DIE_ON_ERROR);
391 create_base_index();
392 add_remove_files(&partial);
393 refresh_cache(REFRESH_QUIET);
395 if (write_cache(fd, active_cache, active_nr) ||
396 close_lock_file(&false_lock))
397 die("unable to write temporary index file");
399 discard_cache();
400 read_cache_from(false_lock.filename);
402 return false_lock.filename;
405 static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
406 struct wt_status *s)
408 unsigned char sha1[20];
410 if (s->relative_paths)
411 s->prefix = prefix;
413 if (amend) {
414 s->amend = 1;
415 s->reference = "HEAD^1";
417 s->verbose = verbose;
418 s->index_file = index_file;
419 s->fp = fp;
420 s->nowarn = nowarn;
421 s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
423 wt_status_collect(s);
425 switch (status_format) {
426 case STATUS_FORMAT_SHORT:
427 wt_shortstatus_print(s, null_termination);
428 break;
429 case STATUS_FORMAT_PORCELAIN:
430 wt_porcelain_print(s, null_termination);
431 break;
432 case STATUS_FORMAT_LONG:
433 wt_status_print(s);
434 break;
437 return s->commitable;
440 static int is_a_merge(const unsigned char *sha1)
442 struct commit *commit = lookup_commit(sha1);
443 if (!commit || parse_commit(commit))
444 die("could not parse HEAD commit");
445 return !!(commit->parents && commit->parents->next);
448 static const char sign_off_header[] = "Signed-off-by: ";
450 static void determine_author_info(void)
452 char *name, *email, *date;
454 name = getenv("GIT_AUTHOR_NAME");
455 email = getenv("GIT_AUTHOR_EMAIL");
456 date = getenv("GIT_AUTHOR_DATE");
458 if (use_message && !renew_authorship) {
459 const char *a, *lb, *rb, *eol;
461 a = strstr(use_message_buffer, "\nauthor ");
462 if (!a)
463 die("invalid commit: %s", use_message);
465 lb = strstr(a + 8, " <");
466 rb = strstr(a + 8, "> ");
467 eol = strchr(a + 8, '\n');
468 if (!lb || !rb || !eol)
469 die("invalid commit: %s", use_message);
471 name = xstrndup(a + 8, lb - (a + 8));
472 email = xstrndup(lb + 2, rb - (lb + 2));
473 date = xstrndup(rb + 2, eol - (rb + 2));
476 if (force_author) {
477 const char *lb = strstr(force_author, " <");
478 const char *rb = strchr(force_author, '>');
480 if (!lb || !rb)
481 die("malformed --author parameter");
482 name = xstrndup(force_author, lb - force_author);
483 email = xstrndup(lb + 2, rb - (lb + 2));
486 if (force_date)
487 date = force_date;
489 author_name = name;
490 author_email = email;
491 author_date = date;
494 static int ends_rfc2822_footer(struct strbuf *sb)
496 int ch;
497 int hit = 0;
498 int i, j, k;
499 int len = sb->len;
500 int first = 1;
501 const char *buf = sb->buf;
503 for (i = len - 1; i > 0; i--) {
504 if (hit && buf[i] == '\n')
505 break;
506 hit = (buf[i] == '\n');
509 while (i < len - 1 && buf[i] == '\n')
510 i++;
512 for (; i < len; i = k) {
513 for (k = i; k < len && buf[k] != '\n'; k++)
514 ; /* do nothing */
515 k++;
517 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
518 continue;
520 first = 0;
522 for (j = 0; i + j < len; j++) {
523 ch = buf[i + j];
524 if (ch == ':')
525 break;
526 if (isalnum(ch) ||
527 (ch == '-'))
528 continue;
529 return 0;
532 return 1;
535 static int prepare_to_commit(const char *index_file, const char *prefix,
536 struct wt_status *s)
538 struct stat statbuf;
539 int commitable, saved_color_setting;
540 struct strbuf sb = STRBUF_INIT;
541 char *buffer;
542 FILE *fp;
543 const char *hook_arg1 = NULL;
544 const char *hook_arg2 = NULL;
545 int ident_shown = 0;
547 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
548 return 0;
550 if (message.len) {
551 strbuf_addbuf(&sb, &message);
552 hook_arg1 = "message";
553 } else if (logfile && !strcmp(logfile, "-")) {
554 if (isatty(0))
555 fprintf(stderr, "(reading log message from standard input)\n");
556 if (strbuf_read(&sb, 0, 0) < 0)
557 die_errno("could not read log from standard input");
558 hook_arg1 = "message";
559 } else if (logfile) {
560 if (strbuf_read_file(&sb, logfile, 0) < 0)
561 die_errno("could not read log file '%s'",
562 logfile);
563 hook_arg1 = "message";
564 } else if (use_message) {
565 buffer = strstr(use_message_buffer, "\n\n");
566 if (!buffer || buffer[2] == '\0')
567 die("commit has empty message");
568 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
569 hook_arg1 = "commit";
570 hook_arg2 = use_message;
571 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
572 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
573 die_errno("could not read MERGE_MSG");
574 hook_arg1 = "merge";
575 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
576 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
577 die_errno("could not read SQUASH_MSG");
578 hook_arg1 = "squash";
579 } else if (template_file && !stat(template_file, &statbuf)) {
580 if (strbuf_read_file(&sb, template_file, 0) < 0)
581 die_errno("could not read '%s'", template_file);
582 hook_arg1 = "template";
586 * This final case does not modify the template message,
587 * it just sets the argument to the prepare-commit-msg hook.
589 else if (in_merge)
590 hook_arg1 = "merge";
592 fp = fopen(git_path(commit_editmsg), "w");
593 if (fp == NULL)
594 die_errno("could not open '%s'", git_path(commit_editmsg));
596 if (cleanup_mode != CLEANUP_NONE)
597 stripspace(&sb, 0);
599 if (signoff) {
600 struct strbuf sob = STRBUF_INIT;
601 int i;
603 strbuf_addstr(&sob, sign_off_header);
604 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
605 getenv("GIT_COMMITTER_EMAIL")));
606 strbuf_addch(&sob, '\n');
607 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
608 ; /* do nothing */
609 if (prefixcmp(sb.buf + i, sob.buf)) {
610 if (!i || !ends_rfc2822_footer(&sb))
611 strbuf_addch(&sb, '\n');
612 strbuf_addbuf(&sb, &sob);
614 strbuf_release(&sob);
617 if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
618 die_errno("could not write commit template");
620 strbuf_release(&sb);
622 determine_author_info();
624 /* This checks if committer ident is explicitly given */
625 git_committer_info(0);
626 if (use_editor && include_status) {
627 char *author_ident;
628 const char *committer_ident;
630 if (in_merge)
631 fprintf(fp,
632 "#\n"
633 "# It looks like you may be committing a MERGE.\n"
634 "# If this is not correct, please remove the file\n"
635 "# %s\n"
636 "# and try again.\n"
637 "#\n",
638 git_path("MERGE_HEAD"));
640 fprintf(fp,
641 "\n"
642 "# Please enter the commit message for your changes.");
643 if (cleanup_mode == CLEANUP_ALL)
644 fprintf(fp,
645 " Lines starting\n"
646 "# with '#' will be ignored, and an empty"
647 " message aborts the commit.\n");
648 else /* CLEANUP_SPACE, that is. */
649 fprintf(fp,
650 " Lines starting\n"
651 "# with '#' will be kept; you may remove them"
652 " yourself if you want to.\n"
653 "# An empty message aborts the commit.\n");
654 if (only_include_assumed)
655 fprintf(fp, "# %s\n", only_include_assumed);
657 author_ident = xstrdup(fmt_name(author_name, author_email));
658 committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
659 getenv("GIT_COMMITTER_EMAIL"));
660 if (strcmp(author_ident, committer_ident))
661 fprintf(fp,
662 "%s"
663 "# Author: %s\n",
664 ident_shown++ ? "" : "#\n",
665 author_ident);
666 free(author_ident);
668 if (!user_ident_sufficiently_given())
669 fprintf(fp,
670 "%s"
671 "# Committer: %s\n",
672 ident_shown++ ? "" : "#\n",
673 committer_ident);
675 if (ident_shown)
676 fprintf(fp, "#\n");
678 saved_color_setting = s->use_color;
679 s->use_color = 0;
680 commitable = run_status(fp, index_file, prefix, 1, s);
681 s->use_color = saved_color_setting;
682 } else {
683 unsigned char sha1[20];
684 const char *parent = "HEAD";
686 if (!active_nr && read_cache() < 0)
687 die("Cannot read index");
689 if (amend)
690 parent = "HEAD^1";
692 if (get_sha1(parent, sha1))
693 commitable = !!active_nr;
694 else
695 commitable = index_differs_from(parent, 0);
698 fclose(fp);
700 if (!commitable && !in_merge && !allow_empty &&
701 !(amend && is_a_merge(head_sha1))) {
702 run_status(stdout, index_file, prefix, 0, s);
703 return 0;
707 * Re-read the index as pre-commit hook could have updated it,
708 * and write it out as a tree. We must do this before we invoke
709 * the editor and after we invoke run_status above.
711 discard_cache();
712 read_cache_from(index_file);
713 if (!active_cache_tree)
714 active_cache_tree = cache_tree();
715 if (cache_tree_update(active_cache_tree,
716 active_cache, active_nr, 0, 0) < 0) {
717 error("Error building trees");
718 return 0;
721 if (run_hook(index_file, "prepare-commit-msg",
722 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
723 return 0;
725 if (use_editor) {
726 char index[PATH_MAX];
727 const char *env[2] = { index, NULL };
728 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
729 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
730 fprintf(stderr,
731 "Please supply the message using either -m or -F option.\n");
732 exit(1);
736 if (!no_verify &&
737 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
738 return 0;
741 return 1;
745 * Find out if the message in the strbuf contains only whitespace and
746 * Signed-off-by lines.
748 static int message_is_empty(struct strbuf *sb)
750 struct strbuf tmpl = STRBUF_INIT;
751 const char *nl;
752 int eol, i, start = 0;
754 if (cleanup_mode == CLEANUP_NONE && sb->len)
755 return 0;
757 /* See if the template is just a prefix of the message. */
758 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
759 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
760 if (start + tmpl.len <= sb->len &&
761 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
762 start += tmpl.len;
764 strbuf_release(&tmpl);
766 /* Check if the rest is just whitespace and Signed-of-by's. */
767 for (i = start; i < sb->len; i++) {
768 nl = memchr(sb->buf + i, '\n', sb->len - i);
769 if (nl)
770 eol = nl - sb->buf;
771 else
772 eol = sb->len;
774 if (strlen(sign_off_header) <= eol - i &&
775 !prefixcmp(sb->buf + i, sign_off_header)) {
776 i = eol;
777 continue;
779 while (i < eol)
780 if (!isspace(sb->buf[i++]))
781 return 0;
784 return 1;
787 static const char *find_author_by_nickname(const char *name)
789 struct rev_info revs;
790 struct commit *commit;
791 struct strbuf buf = STRBUF_INIT;
792 const char *av[20];
793 int ac = 0;
795 init_revisions(&revs, NULL);
796 strbuf_addf(&buf, "--author=%s", name);
797 av[++ac] = "--all";
798 av[++ac] = "-i";
799 av[++ac] = buf.buf;
800 av[++ac] = NULL;
801 setup_revisions(ac, av, &revs, NULL);
802 prepare_revision_walk(&revs);
803 commit = get_revision(&revs);
804 if (commit) {
805 struct pretty_print_context ctx = {0};
806 ctx.date_mode = DATE_NORMAL;
807 strbuf_release(&buf);
808 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
809 return strbuf_detach(&buf, NULL);
811 die("No existing author found with '%s'", name);
815 static void handle_untracked_files_arg(struct wt_status *s)
817 if (!untracked_files_arg)
818 ; /* default already initialized */
819 else if (!strcmp(untracked_files_arg, "no"))
820 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
821 else if (!strcmp(untracked_files_arg, "normal"))
822 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
823 else if (!strcmp(untracked_files_arg, "all"))
824 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
825 else
826 die("Invalid untracked files mode '%s'", untracked_files_arg);
829 static int parse_and_validate_options(int argc, const char *argv[],
830 const char * const usage[],
831 const char *prefix,
832 struct wt_status *s)
834 int f = 0;
836 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
839 if (force_author && !strchr(force_author, '>'))
840 force_author = find_author_by_nickname(force_author);
842 if (force_author && renew_authorship)
843 die("Using both --reset-author and --author does not make sense");
845 if (logfile || message.len || use_message)
846 use_editor = 0;
847 if (edit_flag)
848 use_editor = 1;
849 if (!use_editor)
850 setenv("GIT_EDITOR", ":", 1);
852 if (get_sha1("HEAD", head_sha1))
853 initial_commit = 1;
855 /* Sanity check options */
856 if (amend && initial_commit)
857 die("You have nothing to amend.");
858 if (amend && in_merge)
859 die("You are in the middle of a merge -- cannot amend.");
861 if (use_message)
862 f++;
863 if (edit_message)
864 f++;
865 if (logfile)
866 f++;
867 if (f > 1)
868 die("Only one of -c/-C/-F can be used.");
869 if (message.len && f > 0)
870 die("Option -m cannot be combined with -c/-C/-F.");
871 if (edit_message)
872 use_message = edit_message;
873 if (amend && !use_message)
874 use_message = "HEAD";
875 if (!use_message && renew_authorship)
876 die("--reset-author can be used only with -C, -c or --amend.");
877 if (use_message) {
878 unsigned char sha1[20];
879 static char utf8[] = "UTF-8";
880 const char *out_enc;
881 char *enc, *end;
882 struct commit *commit;
884 if (get_sha1(use_message, sha1))
885 die("could not lookup commit %s", use_message);
886 commit = lookup_commit_reference(sha1);
887 if (!commit || parse_commit(commit))
888 die("could not parse commit %s", use_message);
890 enc = strstr(commit->buffer, "\nencoding");
891 if (enc) {
892 end = strchr(enc + 10, '\n');
893 enc = xstrndup(enc + 10, end - (enc + 10));
894 } else {
895 enc = utf8;
897 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
899 if (strcmp(out_enc, enc))
900 use_message_buffer =
901 reencode_string(commit->buffer, out_enc, enc);
904 * If we failed to reencode the buffer, just copy it
905 * byte for byte so the user can try to fix it up.
906 * This also handles the case where input and output
907 * encodings are identical.
909 if (use_message_buffer == NULL)
910 use_message_buffer = xstrdup(commit->buffer);
911 if (enc != utf8)
912 free(enc);
915 if (!!also + !!only + !!all + !!interactive > 1)
916 die("Only one of --include/--only/--all/--interactive can be used.");
917 if (argc == 0 && (also || (only && !amend)))
918 die("No paths with --include/--only does not make sense.");
919 if (argc == 0 && only && amend)
920 only_include_assumed = "Clever... amending the last one with dirty index.";
921 if (argc > 0 && !also && !only)
922 only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
923 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
924 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
925 else if (!strcmp(cleanup_arg, "verbatim"))
926 cleanup_mode = CLEANUP_NONE;
927 else if (!strcmp(cleanup_arg, "whitespace"))
928 cleanup_mode = CLEANUP_SPACE;
929 else if (!strcmp(cleanup_arg, "strip"))
930 cleanup_mode = CLEANUP_ALL;
931 else
932 die("Invalid cleanup mode %s", cleanup_arg);
934 handle_untracked_files_arg(s);
936 if (all && argc > 0)
937 die("Paths with -a does not make sense.");
938 else if (interactive && argc > 0)
939 die("Paths with --interactive does not make sense.");
941 if (null_termination && status_format == STATUS_FORMAT_LONG)
942 status_format = STATUS_FORMAT_PORCELAIN;
943 if (status_format != STATUS_FORMAT_LONG)
944 dry_run = 1;
946 return argc;
949 static int dry_run_commit(int argc, const char **argv, const char *prefix,
950 struct wt_status *s)
952 int commitable;
953 const char *index_file;
955 index_file = prepare_index(argc, argv, prefix, 1);
956 commitable = run_status(stdout, index_file, prefix, 0, s);
957 rollback_index_files();
959 return commitable ? 0 : 1;
962 static int parse_status_slot(const char *var, int offset)
964 if (!strcasecmp(var+offset, "header"))
965 return WT_STATUS_HEADER;
966 if (!strcasecmp(var+offset, "updated")
967 || !strcasecmp(var+offset, "added"))
968 return WT_STATUS_UPDATED;
969 if (!strcasecmp(var+offset, "changed"))
970 return WT_STATUS_CHANGED;
971 if (!strcasecmp(var+offset, "untracked"))
972 return WT_STATUS_UNTRACKED;
973 if (!strcasecmp(var+offset, "nobranch"))
974 return WT_STATUS_NOBRANCH;
975 if (!strcasecmp(var+offset, "unmerged"))
976 return WT_STATUS_UNMERGED;
977 return -1;
980 static int git_status_config(const char *k, const char *v, void *cb)
982 struct wt_status *s = cb;
984 if (!strcmp(k, "status.submodulesummary")) {
985 int is_bool;
986 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
987 if (is_bool && s->submodule_summary)
988 s->submodule_summary = -1;
989 return 0;
991 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
992 s->use_color = git_config_colorbool(k, v, -1);
993 return 0;
995 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
996 int slot = parse_status_slot(k, 13);
997 if (slot < 0)
998 return 0;
999 if (!v)
1000 return config_error_nonbool(k);
1001 color_parse(v, k, s->color_palette[slot]);
1002 return 0;
1004 if (!strcmp(k, "status.relativepaths")) {
1005 s->relative_paths = git_config_bool(k, v);
1006 return 0;
1008 if (!strcmp(k, "status.showuntrackedfiles")) {
1009 if (!v)
1010 return config_error_nonbool(k);
1011 else if (!strcmp(v, "no"))
1012 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
1013 else if (!strcmp(v, "normal"))
1014 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
1015 else if (!strcmp(v, "all"))
1016 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
1017 else
1018 return error("Invalid untracked files mode '%s'", v);
1019 return 0;
1021 return git_diff_ui_config(k, v, NULL);
1024 int cmd_status(int argc, const char **argv, const char *prefix)
1026 struct wt_status s;
1027 int fd;
1028 unsigned char sha1[20];
1029 static struct option builtin_status_options[] = {
1030 OPT__VERBOSE(&verbose),
1031 OPT_SET_INT('s', "short", &status_format,
1032 "show status concisely", STATUS_FORMAT_SHORT),
1033 OPT_SET_INT(0, "porcelain", &status_format,
1034 "show porcelain output format",
1035 STATUS_FORMAT_PORCELAIN),
1036 OPT_BOOLEAN('z', "null", &null_termination,
1037 "terminate entries with NUL"),
1038 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1039 "mode",
1040 "show untracked files, optional modes: all, normal, no. (Default: all)",
1041 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1042 OPT_BOOLEAN(0, "ignored", &show_ignored_in_status,
1043 "show ignored files"),
1044 OPT_END(),
1047 if (null_termination && status_format == STATUS_FORMAT_LONG)
1048 status_format = STATUS_FORMAT_PORCELAIN;
1050 wt_status_prepare(&s);
1051 git_config(git_status_config, &s);
1052 in_merge = file_exists(git_path("MERGE_HEAD"));
1053 argc = parse_options(argc, argv, prefix,
1054 builtin_status_options,
1055 builtin_status_usage, 0);
1056 handle_untracked_files_arg(&s);
1057 if (show_ignored_in_status)
1058 s.show_ignored_files = 1;
1059 if (*argv)
1060 s.pathspec = get_pathspec(prefix, argv);
1062 read_cache_preload(s.pathspec);
1063 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1065 fd = hold_locked_index(&index_lock, 0);
1066 if (0 <= fd) {
1067 if (!write_cache(fd, active_cache, active_nr))
1068 commit_locked_index(&index_lock);
1069 rollback_lock_file(&index_lock);
1072 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1073 s.in_merge = in_merge;
1074 wt_status_collect(&s);
1076 if (s.relative_paths)
1077 s.prefix = prefix;
1078 if (s.use_color == -1)
1079 s.use_color = git_use_color_default;
1080 if (diff_use_color_default == -1)
1081 diff_use_color_default = git_use_color_default;
1083 switch (status_format) {
1084 case STATUS_FORMAT_SHORT:
1085 wt_shortstatus_print(&s, null_termination);
1086 break;
1087 case STATUS_FORMAT_PORCELAIN:
1088 wt_porcelain_print(&s, null_termination);
1089 break;
1090 case STATUS_FORMAT_LONG:
1091 s.verbose = verbose;
1092 wt_status_print(&s);
1093 break;
1095 return 0;
1098 static void print_summary(const char *prefix, const unsigned char *sha1)
1100 struct rev_info rev;
1101 struct commit *commit;
1102 struct strbuf format = STRBUF_INIT;
1103 unsigned char junk_sha1[20];
1104 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
1105 struct pretty_print_context pctx = {0};
1106 struct strbuf author_ident = STRBUF_INIT;
1107 struct strbuf committer_ident = STRBUF_INIT;
1109 commit = lookup_commit(sha1);
1110 if (!commit)
1111 die("couldn't look up newly created commit");
1112 if (!commit || parse_commit(commit))
1113 die("could not parse newly created commit");
1115 strbuf_addstr(&format, "format:%h] %s");
1117 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
1118 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
1119 if (strbuf_cmp(&author_ident, &committer_ident)) {
1120 strbuf_addstr(&format, "\n Author: ");
1121 strbuf_addbuf_percentquote(&format, &author_ident);
1123 if (!user_ident_sufficiently_given()) {
1124 strbuf_addstr(&format, "\n Committer: ");
1125 strbuf_addbuf_percentquote(&format, &committer_ident);
1126 if (advice_implicit_identity) {
1127 strbuf_addch(&format, '\n');
1128 strbuf_addstr(&format, implicit_ident_advice);
1131 strbuf_release(&author_ident);
1132 strbuf_release(&committer_ident);
1134 init_revisions(&rev, prefix);
1135 setup_revisions(0, NULL, &rev, NULL);
1137 rev.abbrev = 0;
1138 rev.diff = 1;
1139 rev.diffopt.output_format =
1140 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1142 rev.verbose_header = 1;
1143 rev.show_root_diff = 1;
1144 get_commit_format(format.buf, &rev);
1145 rev.always_show_header = 0;
1146 rev.diffopt.detect_rename = 1;
1147 rev.diffopt.rename_limit = 100;
1148 rev.diffopt.break_opt = 0;
1149 diff_setup_done(&rev.diffopt);
1151 printf("[%s%s ",
1152 !prefixcmp(head, "refs/heads/") ?
1153 head + 11 :
1154 !strcmp(head, "HEAD") ?
1155 "detached HEAD" :
1156 head,
1157 initial_commit ? " (root-commit)" : "");
1159 if (!log_tree_commit(&rev, commit)) {
1160 struct pretty_print_context ctx = {0};
1161 struct strbuf buf = STRBUF_INIT;
1162 ctx.date_mode = DATE_NORMAL;
1163 format_commit_message(commit, format.buf + 7, &buf, &ctx);
1164 printf("%s\n", buf.buf);
1165 strbuf_release(&buf);
1167 strbuf_release(&format);
1170 static int git_commit_config(const char *k, const char *v, void *cb)
1172 struct wt_status *s = cb;
1174 if (!strcmp(k, "commit.template"))
1175 return git_config_pathname(&template_file, k, v);
1176 if (!strcmp(k, "commit.status")) {
1177 include_status = git_config_bool(k, v);
1178 return 0;
1181 return git_status_config(k, v, s);
1184 static const char post_rewrite_hook[] = "hooks/post-rewrite";
1186 static int run_rewrite_hook(const unsigned char *oldsha1,
1187 const unsigned char *newsha1)
1189 /* oldsha1 SP newsha1 LF NUL */
1190 static char buf[2*40 + 3];
1191 struct child_process proc;
1192 const char *argv[3];
1193 int code;
1194 size_t n;
1196 if (access(git_path(post_rewrite_hook), X_OK) < 0)
1197 return 0;
1199 argv[0] = git_path(post_rewrite_hook);
1200 argv[1] = "amend";
1201 argv[2] = NULL;
1203 memset(&proc, 0, sizeof(proc));
1204 proc.argv = argv;
1205 proc.in = -1;
1206 proc.stdout_to_stderr = 1;
1208 code = start_command(&proc);
1209 if (code)
1210 return code;
1211 n = snprintf(buf, sizeof(buf), "%s %s\n",
1212 sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1213 write_in_full(proc.in, buf, n);
1214 close(proc.in);
1215 return finish_command(&proc);
1218 int cmd_commit(int argc, const char **argv, const char *prefix)
1220 struct strbuf sb = STRBUF_INIT;
1221 const char *index_file, *reflog_msg;
1222 char *nl, *p;
1223 unsigned char commit_sha1[20];
1224 struct ref_lock *ref_lock;
1225 struct commit_list *parents = NULL, **pptr = &parents;
1226 struct stat statbuf;
1227 int allow_fast_forward = 1;
1228 struct wt_status s;
1230 wt_status_prepare(&s);
1231 git_config(git_commit_config, &s);
1232 in_merge = file_exists(git_path("MERGE_HEAD"));
1233 s.in_merge = in_merge;
1235 if (s.use_color == -1)
1236 s.use_color = git_use_color_default;
1237 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1238 prefix, &s);
1239 if (dry_run) {
1240 if (diff_use_color_default == -1)
1241 diff_use_color_default = git_use_color_default;
1242 return dry_run_commit(argc, argv, prefix, &s);
1244 index_file = prepare_index(argc, argv, prefix, 0);
1246 /* Set up everything for writing the commit object. This includes
1247 running hooks, writing the trees, and interacting with the user. */
1248 if (!prepare_to_commit(index_file, prefix, &s)) {
1249 rollback_index_files();
1250 return 1;
1253 /* Determine parents */
1254 if (initial_commit) {
1255 reflog_msg = "commit (initial)";
1256 } else if (amend) {
1257 struct commit_list *c;
1258 struct commit *commit;
1260 reflog_msg = "commit (amend)";
1261 commit = lookup_commit(head_sha1);
1262 if (!commit || parse_commit(commit))
1263 die("could not parse HEAD commit");
1265 for (c = commit->parents; c; c = c->next)
1266 pptr = &commit_list_insert(c->item, pptr)->next;
1267 } else if (in_merge) {
1268 struct strbuf m = STRBUF_INIT;
1269 FILE *fp;
1271 reflog_msg = "commit (merge)";
1272 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1273 fp = fopen(git_path("MERGE_HEAD"), "r");
1274 if (fp == NULL)
1275 die_errno("could not open '%s' for reading",
1276 git_path("MERGE_HEAD"));
1277 while (strbuf_getline(&m, fp, '\n') != EOF) {
1278 unsigned char sha1[20];
1279 if (get_sha1_hex(m.buf, sha1) < 0)
1280 die("Corrupt MERGE_HEAD file (%s)", m.buf);
1281 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1283 fclose(fp);
1284 strbuf_release(&m);
1285 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1286 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1287 die_errno("could not read MERGE_MODE");
1288 if (!strcmp(sb.buf, "no-ff"))
1289 allow_fast_forward = 0;
1291 if (allow_fast_forward)
1292 parents = reduce_heads(parents);
1293 } else {
1294 reflog_msg = "commit";
1295 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1298 /* Finally, get the commit message */
1299 strbuf_reset(&sb);
1300 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1301 int saved_errno = errno;
1302 rollback_index_files();
1303 die("could not read commit message: %s", strerror(saved_errno));
1306 /* Truncate the message just before the diff, if any. */
1307 if (verbose) {
1308 p = strstr(sb.buf, "\ndiff --git ");
1309 if (p != NULL)
1310 strbuf_setlen(&sb, p - sb.buf + 1);
1313 if (cleanup_mode != CLEANUP_NONE)
1314 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1315 if (message_is_empty(&sb) && !allow_empty_message) {
1316 rollback_index_files();
1317 fprintf(stderr, "Aborting commit due to empty commit message.\n");
1318 exit(1);
1321 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1322 fmt_ident(author_name, author_email, author_date,
1323 IDENT_ERROR_ON_NO_NAME))) {
1324 rollback_index_files();
1325 die("failed to write commit object");
1328 ref_lock = lock_any_ref_for_update("HEAD",
1329 initial_commit ? NULL : head_sha1,
1332 nl = strchr(sb.buf, '\n');
1333 if (nl)
1334 strbuf_setlen(&sb, nl + 1 - sb.buf);
1335 else
1336 strbuf_addch(&sb, '\n');
1337 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1338 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1340 if (!ref_lock) {
1341 rollback_index_files();
1342 die("cannot lock HEAD ref");
1344 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1345 rollback_index_files();
1346 die("cannot update HEAD ref");
1349 unlink(git_path("MERGE_HEAD"));
1350 unlink(git_path("MERGE_MSG"));
1351 unlink(git_path("MERGE_MODE"));
1352 unlink(git_path("SQUASH_MSG"));
1354 if (commit_index_files())
1355 die ("Repository has been updated, but unable to write\n"
1356 "new_index file. Check that disk is not full or quota is\n"
1357 "not exceeded, and then \"git reset HEAD\" to recover.");
1359 rerere(0);
1360 run_hook(get_index_file(), "post-commit", NULL);
1361 if (amend && !no_post_rewrite) {
1362 struct notes_rewrite_cfg *cfg;
1363 cfg = init_copy_notes_for_rewrite("amend");
1364 if (cfg) {
1365 copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
1366 finish_copy_notes_for_rewrite(cfg);
1368 run_rewrite_hook(head_sha1, commit_sha1);
1370 if (!quiet)
1371 print_summary(prefix, commit_sha1);
1373 return 0;