commit: show interesting ident information in summary
[git.git] / builtin-commit.c
blobb923038b0a55d99fd392b47d3cc4cd2bad19ecbd
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"
28 static const char * const builtin_commit_usage[] = {
29 "git commit [options] [--] <filepattern>...",
30 NULL
33 static const char * const builtin_status_usage[] = {
34 "git status [options] [--] <filepattern>...",
35 NULL
38 static const char implicit_ident_advice[] =
39 "Your name and email address were configured automatically based\n"
40 "on your username and hostname. Please check that they are accurate.\n"
41 "You can suppress this message by setting them explicitly:\n"
42 "\n"
43 " git config --global user.name Your Name\n"
44 " git config --global user.email you@example.com\n"
45 "\n"
46 "If the identity used for this commit is wrong, you can fix it with:\n"
47 "\n"
48 " git commit --amend --author='Your Name <you@example.com>'\n";
50 static unsigned char head_sha1[20], merge_head_sha1[20];
52 static char *use_message_buffer;
53 static const char commit_editmsg[] = "COMMIT_EDITMSG";
54 static struct lock_file index_lock; /* real index */
55 static struct lock_file false_lock; /* used only for partial commits */
56 static enum {
57 COMMIT_AS_IS = 1,
58 COMMIT_NORMAL,
59 COMMIT_PARTIAL,
60 } commit_style;
62 static const char *logfile, *force_author;
63 static const char *template_file;
64 static char *edit_message, *use_message;
65 static char *author_name, *author_email, *author_date;
66 static int all, edit_flag, also, interactive, only, amend, signoff;
67 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
68 static char *untracked_files_arg;
70 * The default commit message cleanup mode will remove the lines
71 * beginning with # (shell comments) and leading and trailing
72 * whitespaces (empty lines or containing only whitespaces)
73 * if editor is used, and only the whitespaces if the message
74 * is specified explicitly.
76 static enum {
77 CLEANUP_SPACE,
78 CLEANUP_NONE,
79 CLEANUP_ALL,
80 } cleanup_mode;
81 static char *cleanup_arg;
83 static int use_editor = 1, initial_commit, in_merge;
84 static const char *only_include_assumed;
85 static struct strbuf message;
87 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
89 struct strbuf *buf = opt->value;
90 if (unset)
91 strbuf_setlen(buf, 0);
92 else {
93 strbuf_addstr(buf, arg);
94 strbuf_addstr(buf, "\n\n");
96 return 0;
99 static struct option builtin_commit_options[] = {
100 OPT__QUIET(&quiet),
101 OPT__VERBOSE(&verbose),
102 OPT_GROUP("Commit message options"),
104 OPT_FILENAME('F', "file", &logfile, "read log from file"),
105 OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
106 OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
107 OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
108 OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
109 OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
110 OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
111 OPT_FILENAME('t', "template", &template_file, "use specified template file"),
112 OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
114 OPT_GROUP("Commit contents options"),
115 OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
116 OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
117 OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
118 OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
119 OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
120 OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
121 OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
122 { 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" },
123 OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
124 OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
126 OPT_END()
129 static void rollback_index_files(void)
131 switch (commit_style) {
132 case COMMIT_AS_IS:
133 break; /* nothing to do */
134 case COMMIT_NORMAL:
135 rollback_lock_file(&index_lock);
136 break;
137 case COMMIT_PARTIAL:
138 rollback_lock_file(&index_lock);
139 rollback_lock_file(&false_lock);
140 break;
144 static int commit_index_files(void)
146 int err = 0;
148 switch (commit_style) {
149 case COMMIT_AS_IS:
150 break; /* nothing to do */
151 case COMMIT_NORMAL:
152 err = commit_lock_file(&index_lock);
153 break;
154 case COMMIT_PARTIAL:
155 err = commit_lock_file(&index_lock);
156 rollback_lock_file(&false_lock);
157 break;
160 return err;
164 * Take a union of paths in the index and the named tree (typically, "HEAD"),
165 * and return the paths that match the given pattern in list.
167 static int list_paths(struct string_list *list, const char *with_tree,
168 const char *prefix, const char **pattern)
170 int i;
171 char *m;
173 for (i = 0; pattern[i]; i++)
175 m = xcalloc(1, i);
177 if (with_tree)
178 overlay_tree_on_cache(with_tree, prefix);
180 for (i = 0; i < active_nr; i++) {
181 struct cache_entry *ce = active_cache[i];
182 if (ce->ce_flags & CE_UPDATE)
183 continue;
184 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
185 continue;
186 string_list_insert(ce->name, list);
189 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
192 static void add_remove_files(struct string_list *list)
194 int i;
195 for (i = 0; i < list->nr; i++) {
196 struct stat st;
197 struct string_list_item *p = &(list->items[i]);
199 if (!lstat(p->string, &st)) {
200 if (add_to_cache(p->string, &st, 0))
201 die("updating files failed");
202 } else
203 remove_file_from_cache(p->string);
207 static void create_base_index(void)
209 struct tree *tree;
210 struct unpack_trees_options opts;
211 struct tree_desc t;
213 if (initial_commit) {
214 discard_cache();
215 return;
218 memset(&opts, 0, sizeof(opts));
219 opts.head_idx = 1;
220 opts.index_only = 1;
221 opts.merge = 1;
222 opts.src_index = &the_index;
223 opts.dst_index = &the_index;
225 opts.fn = oneway_merge;
226 tree = parse_tree_indirect(head_sha1);
227 if (!tree)
228 die("failed to unpack HEAD tree object");
229 parse_tree(tree);
230 init_tree_desc(&t, tree->buffer, tree->size);
231 if (unpack_trees(1, &t, &opts))
232 exit(128); /* We've already reported the error, finish dying */
235 static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
237 int fd;
238 struct string_list partial;
239 const char **pathspec = NULL;
240 int refresh_flags = REFRESH_QUIET;
242 if (is_status)
243 refresh_flags |= REFRESH_UNMERGED;
244 if (interactive) {
245 if (interactive_add(argc, argv, prefix) != 0)
246 die("interactive add failed");
247 if (read_cache_preload(NULL) < 0)
248 die("index file corrupt");
249 commit_style = COMMIT_AS_IS;
250 return get_index_file();
253 if (*argv)
254 pathspec = get_pathspec(prefix, argv);
256 if (read_cache_preload(pathspec) < 0)
257 die("index file corrupt");
260 * Non partial, non as-is commit.
262 * (1) get the real index;
263 * (2) update the_index as necessary;
264 * (3) write the_index out to the real index (still locked);
265 * (4) return the name of the locked index file.
267 * The caller should run hooks on the locked real index, and
268 * (A) if all goes well, commit the real index;
269 * (B) on failure, rollback the real index.
271 if (all || (also && pathspec && *pathspec)) {
272 int fd = hold_locked_index(&index_lock, 1);
273 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
274 refresh_cache(refresh_flags);
275 if (write_cache(fd, active_cache, active_nr) ||
276 close_lock_file(&index_lock))
277 die("unable to write new_index file");
278 commit_style = COMMIT_NORMAL;
279 return index_lock.filename;
283 * As-is commit.
285 * (1) return the name of the real index file.
287 * The caller should run hooks on the real index, and run
288 * hooks on the real index, and create commit from the_index.
289 * We still need to refresh the index here.
291 if (!pathspec || !*pathspec) {
292 fd = hold_locked_index(&index_lock, 1);
293 refresh_cache(refresh_flags);
294 if (write_cache(fd, active_cache, active_nr) ||
295 commit_locked_index(&index_lock))
296 die("unable to write new_index file");
297 commit_style = COMMIT_AS_IS;
298 return get_index_file();
302 * A partial commit.
304 * (0) find the set of affected paths;
305 * (1) get lock on the real index file;
306 * (2) update the_index with the given paths;
307 * (3) write the_index out to the real index (still locked);
308 * (4) get lock on the false index file;
309 * (5) reset the_index from HEAD;
310 * (6) update the_index the same way as (2);
311 * (7) write the_index out to the false index file;
312 * (8) return the name of the false index file (still locked);
314 * The caller should run hooks on the locked false index, and
315 * create commit from it. Then
316 * (A) if all goes well, commit the real index;
317 * (B) on failure, rollback the real index;
318 * In either case, rollback the false index.
320 commit_style = COMMIT_PARTIAL;
322 if (file_exists(git_path("MERGE_HEAD")))
323 die("cannot do a partial commit during a merge.");
325 memset(&partial, 0, sizeof(partial));
326 partial.strdup_strings = 1;
327 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
328 exit(1);
330 discard_cache();
331 if (read_cache() < 0)
332 die("cannot read the index");
334 fd = hold_locked_index(&index_lock, 1);
335 add_remove_files(&partial);
336 refresh_cache(REFRESH_QUIET);
337 if (write_cache(fd, active_cache, active_nr) ||
338 close_lock_file(&index_lock))
339 die("unable to write new_index file");
341 fd = hold_lock_file_for_update(&false_lock,
342 git_path("next-index-%"PRIuMAX,
343 (uintmax_t) getpid()),
344 LOCK_DIE_ON_ERROR);
346 create_base_index();
347 add_remove_files(&partial);
348 refresh_cache(REFRESH_QUIET);
350 if (write_cache(fd, active_cache, active_nr) ||
351 close_lock_file(&false_lock))
352 die("unable to write temporary index file");
354 discard_cache();
355 read_cache_from(false_lock.filename);
357 return false_lock.filename;
360 static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
361 struct wt_status *s)
363 if (s->relative_paths)
364 s->prefix = prefix;
366 if (amend) {
367 s->amend = 1;
368 s->reference = "HEAD^1";
370 s->verbose = verbose;
371 s->index_file = index_file;
372 s->fp = fp;
373 s->nowarn = nowarn;
375 wt_status_print(s);
377 return s->commitable;
380 static int is_a_merge(const unsigned char *sha1)
382 struct commit *commit = lookup_commit(sha1);
383 if (!commit || parse_commit(commit))
384 die("could not parse HEAD commit");
385 return !!(commit->parents && commit->parents->next);
388 static const char sign_off_header[] = "Signed-off-by: ";
390 static void determine_author_info(void)
392 char *name, *email, *date;
394 name = getenv("GIT_AUTHOR_NAME");
395 email = getenv("GIT_AUTHOR_EMAIL");
396 date = getenv("GIT_AUTHOR_DATE");
398 if (use_message && !renew_authorship) {
399 const char *a, *lb, *rb, *eol;
401 a = strstr(use_message_buffer, "\nauthor ");
402 if (!a)
403 die("invalid commit: %s", use_message);
405 lb = strstr(a + 8, " <");
406 rb = strstr(a + 8, "> ");
407 eol = strchr(a + 8, '\n');
408 if (!lb || !rb || !eol)
409 die("invalid commit: %s", use_message);
411 name = xstrndup(a + 8, lb - (a + 8));
412 email = xstrndup(lb + 2, rb - (lb + 2));
413 date = xstrndup(rb + 2, eol - (rb + 2));
416 if (force_author) {
417 const char *lb = strstr(force_author, " <");
418 const char *rb = strchr(force_author, '>');
420 if (!lb || !rb)
421 die("malformed --author parameter");
422 name = xstrndup(force_author, lb - force_author);
423 email = xstrndup(lb + 2, rb - (lb + 2));
426 author_name = name;
427 author_email = email;
428 author_date = date;
431 static int ends_rfc2822_footer(struct strbuf *sb)
433 int ch;
434 int hit = 0;
435 int i, j, k;
436 int len = sb->len;
437 int first = 1;
438 const char *buf = sb->buf;
440 for (i = len - 1; i > 0; i--) {
441 if (hit && buf[i] == '\n')
442 break;
443 hit = (buf[i] == '\n');
446 while (i < len - 1 && buf[i] == '\n')
447 i++;
449 for (; i < len; i = k) {
450 for (k = i; k < len && buf[k] != '\n'; k++)
451 ; /* do nothing */
452 k++;
454 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
455 continue;
457 first = 0;
459 for (j = 0; i + j < len; j++) {
460 ch = buf[i + j];
461 if (ch == ':')
462 break;
463 if (isalnum(ch) ||
464 (ch == '-'))
465 continue;
466 return 0;
469 return 1;
472 static int prepare_to_commit(const char *index_file, const char *prefix,
473 struct wt_status *s)
475 struct stat statbuf;
476 int commitable, saved_color_setting;
477 struct strbuf sb = STRBUF_INIT;
478 char *buffer;
479 FILE *fp;
480 const char *hook_arg1 = NULL;
481 const char *hook_arg2 = NULL;
482 int ident_shown = 0;
484 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
485 return 0;
487 if (message.len) {
488 strbuf_addbuf(&sb, &message);
489 hook_arg1 = "message";
490 } else if (logfile && !strcmp(logfile, "-")) {
491 if (isatty(0))
492 fprintf(stderr, "(reading log message from standard input)\n");
493 if (strbuf_read(&sb, 0, 0) < 0)
494 die_errno("could not read log from standard input");
495 hook_arg1 = "message";
496 } else if (logfile) {
497 if (strbuf_read_file(&sb, logfile, 0) < 0)
498 die_errno("could not read log file '%s'",
499 logfile);
500 hook_arg1 = "message";
501 } else if (use_message) {
502 buffer = strstr(use_message_buffer, "\n\n");
503 if (!buffer || buffer[2] == '\0')
504 die("commit has empty message");
505 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
506 hook_arg1 = "commit";
507 hook_arg2 = use_message;
508 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
509 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
510 die_errno("could not read MERGE_MSG");
511 hook_arg1 = "merge";
512 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
513 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
514 die_errno("could not read SQUASH_MSG");
515 hook_arg1 = "squash";
516 } else if (template_file && !stat(template_file, &statbuf)) {
517 if (strbuf_read_file(&sb, template_file, 0) < 0)
518 die_errno("could not read '%s'", template_file);
519 hook_arg1 = "template";
523 * This final case does not modify the template message,
524 * it just sets the argument to the prepare-commit-msg hook.
526 else if (in_merge)
527 hook_arg1 = "merge";
529 fp = fopen(git_path(commit_editmsg), "w");
530 if (fp == NULL)
531 die_errno("could not open '%s'", git_path(commit_editmsg));
533 if (cleanup_mode != CLEANUP_NONE)
534 stripspace(&sb, 0);
536 if (signoff) {
537 struct strbuf sob = STRBUF_INIT;
538 int i;
540 strbuf_addstr(&sob, sign_off_header);
541 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
542 getenv("GIT_COMMITTER_EMAIL")));
543 strbuf_addch(&sob, '\n');
544 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
545 ; /* do nothing */
546 if (prefixcmp(sb.buf + i, sob.buf)) {
547 if (!i || !ends_rfc2822_footer(&sb))
548 strbuf_addch(&sb, '\n');
549 strbuf_addbuf(&sb, &sob);
551 strbuf_release(&sob);
554 if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
555 die_errno("could not write commit template");
557 strbuf_release(&sb);
559 determine_author_info();
561 /* This checks if committer ident is explicitly given */
562 git_committer_info(0);
563 if (use_editor) {
564 char *author_ident;
565 const char *committer_ident;
567 if (in_merge)
568 fprintf(fp,
569 "#\n"
570 "# It looks like you may be committing a MERGE.\n"
571 "# If this is not correct, please remove the file\n"
572 "# %s\n"
573 "# and try again.\n"
574 "#\n",
575 git_path("MERGE_HEAD"));
577 fprintf(fp,
578 "\n"
579 "# Please enter the commit message for your changes.");
580 if (cleanup_mode == CLEANUP_ALL)
581 fprintf(fp,
582 " Lines starting\n"
583 "# with '#' will be ignored, and an empty"
584 " message aborts the commit.\n");
585 else /* CLEANUP_SPACE, that is. */
586 fprintf(fp,
587 " Lines starting\n"
588 "# with '#' will be kept; you may remove them"
589 " yourself if you want to.\n"
590 "# An empty message aborts the commit.\n");
591 if (only_include_assumed)
592 fprintf(fp, "# %s\n", only_include_assumed);
594 author_ident = xstrdup(fmt_name(author_name, author_email));
595 committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
596 getenv("GIT_COMMITTER_EMAIL"));
597 if (strcmp(author_ident, committer_ident))
598 fprintf(fp,
599 "%s"
600 "# Author: %s\n",
601 ident_shown++ ? "" : "#\n",
602 author_ident);
603 free(author_ident);
605 if (!user_ident_explicitly_given)
606 fprintf(fp,
607 "%s"
608 "# Committer: %s\n",
609 ident_shown++ ? "" : "#\n",
610 committer_ident);
612 if (ident_shown)
613 fprintf(fp, "#\n");
615 saved_color_setting = s->use_color;
616 s->use_color = 0;
617 commitable = run_status(fp, index_file, prefix, 1, s);
618 s->use_color = saved_color_setting;
619 } else {
620 unsigned char sha1[20];
621 const char *parent = "HEAD";
623 if (!active_nr && read_cache() < 0)
624 die("Cannot read index");
626 if (amend)
627 parent = "HEAD^1";
629 if (get_sha1(parent, sha1))
630 commitable = !!active_nr;
631 else
632 commitable = index_differs_from(parent, 0);
635 fclose(fp);
637 if (!commitable && !in_merge && !allow_empty &&
638 !(amend && is_a_merge(head_sha1))) {
639 run_status(stdout, index_file, prefix, 0, s);
640 return 0;
644 * Re-read the index as pre-commit hook could have updated it,
645 * and write it out as a tree. We must do this before we invoke
646 * the editor and after we invoke run_status above.
648 discard_cache();
649 read_cache_from(index_file);
650 if (!active_cache_tree)
651 active_cache_tree = cache_tree();
652 if (cache_tree_update(active_cache_tree,
653 active_cache, active_nr, 0, 0) < 0) {
654 error("Error building trees");
655 return 0;
658 if (run_hook(index_file, "prepare-commit-msg",
659 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
660 return 0;
662 if (use_editor) {
663 char index[PATH_MAX];
664 const char *env[2] = { index, NULL };
665 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
666 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
667 fprintf(stderr,
668 "Please supply the message using either -m or -F option.\n");
669 exit(1);
673 if (!no_verify &&
674 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
675 return 0;
678 return 1;
682 * Find out if the message in the strbuf contains only whitespace and
683 * Signed-off-by lines.
685 static int message_is_empty(struct strbuf *sb)
687 struct strbuf tmpl = STRBUF_INIT;
688 const char *nl;
689 int eol, i, start = 0;
691 if (cleanup_mode == CLEANUP_NONE && sb->len)
692 return 0;
694 /* See if the template is just a prefix of the message. */
695 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
696 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
697 if (start + tmpl.len <= sb->len &&
698 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
699 start += tmpl.len;
701 strbuf_release(&tmpl);
703 /* Check if the rest is just whitespace and Signed-of-by's. */
704 for (i = start; i < sb->len; i++) {
705 nl = memchr(sb->buf + i, '\n', sb->len - i);
706 if (nl)
707 eol = nl - sb->buf;
708 else
709 eol = sb->len;
711 if (strlen(sign_off_header) <= eol - i &&
712 !prefixcmp(sb->buf + i, sign_off_header)) {
713 i = eol;
714 continue;
716 while (i < eol)
717 if (!isspace(sb->buf[i++]))
718 return 0;
721 return 1;
724 static const char *find_author_by_nickname(const char *name)
726 struct rev_info revs;
727 struct commit *commit;
728 struct strbuf buf = STRBUF_INIT;
729 const char *av[20];
730 int ac = 0;
732 init_revisions(&revs, NULL);
733 strbuf_addf(&buf, "--author=%s", name);
734 av[++ac] = "--all";
735 av[++ac] = "-i";
736 av[++ac] = buf.buf;
737 av[++ac] = NULL;
738 setup_revisions(ac, av, &revs, NULL);
739 prepare_revision_walk(&revs);
740 commit = get_revision(&revs);
741 if (commit) {
742 struct pretty_print_context ctx = {0};
743 ctx.date_mode = DATE_NORMAL;
744 strbuf_release(&buf);
745 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
746 return strbuf_detach(&buf, NULL);
748 die("No existing author found with '%s'", name);
751 static int parse_and_validate_options(int argc, const char *argv[],
752 const char * const usage[],
753 const char *prefix,
754 struct wt_status *s)
756 int f = 0;
758 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
761 if (force_author && !strchr(force_author, '>'))
762 force_author = find_author_by_nickname(force_author);
764 if (force_author && renew_authorship)
765 die("Using both --reset-author and --author does not make sense");
767 if (logfile || message.len || use_message)
768 use_editor = 0;
769 if (edit_flag)
770 use_editor = 1;
771 if (!use_editor)
772 setenv("GIT_EDITOR", ":", 1);
774 if (get_sha1("HEAD", head_sha1))
775 initial_commit = 1;
777 if (!get_sha1("MERGE_HEAD", merge_head_sha1))
778 in_merge = 1;
780 /* Sanity check options */
781 if (amend && initial_commit)
782 die("You have nothing to amend.");
783 if (amend && in_merge)
784 die("You are in the middle of a merge -- cannot amend.");
786 if (use_message)
787 f++;
788 if (edit_message)
789 f++;
790 if (logfile)
791 f++;
792 if (f > 1)
793 die("Only one of -c/-C/-F can be used.");
794 if (message.len && f > 0)
795 die("Option -m cannot be combined with -c/-C/-F.");
796 if (edit_message)
797 use_message = edit_message;
798 if (amend && !use_message)
799 use_message = "HEAD";
800 if (!use_message && renew_authorship)
801 die("--reset-author can be used only with -C, -c or --amend.");
802 if (use_message) {
803 unsigned char sha1[20];
804 static char utf8[] = "UTF-8";
805 const char *out_enc;
806 char *enc, *end;
807 struct commit *commit;
809 if (get_sha1(use_message, sha1))
810 die("could not lookup commit %s", use_message);
811 commit = lookup_commit_reference(sha1);
812 if (!commit || parse_commit(commit))
813 die("could not parse commit %s", use_message);
815 enc = strstr(commit->buffer, "\nencoding");
816 if (enc) {
817 end = strchr(enc + 10, '\n');
818 enc = xstrndup(enc + 10, end - (enc + 10));
819 } else {
820 enc = utf8;
822 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
824 if (strcmp(out_enc, enc))
825 use_message_buffer =
826 reencode_string(commit->buffer, out_enc, enc);
829 * If we failed to reencode the buffer, just copy it
830 * byte for byte so the user can try to fix it up.
831 * This also handles the case where input and output
832 * encodings are identical.
834 if (use_message_buffer == NULL)
835 use_message_buffer = xstrdup(commit->buffer);
836 if (enc != utf8)
837 free(enc);
840 if (!!also + !!only + !!all + !!interactive > 1)
841 die("Only one of --include/--only/--all/--interactive can be used.");
842 if (argc == 0 && (also || (only && !amend)))
843 die("No paths with --include/--only does not make sense.");
844 if (argc == 0 && only && amend)
845 only_include_assumed = "Clever... amending the last one with dirty index.";
846 if (argc > 0 && !also && !only)
847 only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
848 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
849 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
850 else if (!strcmp(cleanup_arg, "verbatim"))
851 cleanup_mode = CLEANUP_NONE;
852 else if (!strcmp(cleanup_arg, "whitespace"))
853 cleanup_mode = CLEANUP_SPACE;
854 else if (!strcmp(cleanup_arg, "strip"))
855 cleanup_mode = CLEANUP_ALL;
856 else
857 die("Invalid cleanup mode %s", cleanup_arg);
859 if (!untracked_files_arg)
860 ; /* default already initialized */
861 else if (!strcmp(untracked_files_arg, "no"))
862 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
863 else if (!strcmp(untracked_files_arg, "normal"))
864 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
865 else if (!strcmp(untracked_files_arg, "all"))
866 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
867 else
868 die("Invalid untracked files mode '%s'", untracked_files_arg);
870 if (all && argc > 0)
871 die("Paths with -a does not make sense.");
872 else if (interactive && argc > 0)
873 die("Paths with --interactive does not make sense.");
875 return argc;
878 static int dry_run_commit(int argc, const char **argv, const char *prefix,
879 struct wt_status *s)
881 int commitable;
882 const char *index_file;
884 index_file = prepare_index(argc, argv, prefix, 1);
885 commitable = run_status(stdout, index_file, prefix, 0, s);
886 rollback_index_files();
888 return commitable ? 0 : 1;
891 static int parse_status_slot(const char *var, int offset)
893 if (!strcasecmp(var+offset, "header"))
894 return WT_STATUS_HEADER;
895 if (!strcasecmp(var+offset, "updated")
896 || !strcasecmp(var+offset, "added"))
897 return WT_STATUS_UPDATED;
898 if (!strcasecmp(var+offset, "changed"))
899 return WT_STATUS_CHANGED;
900 if (!strcasecmp(var+offset, "untracked"))
901 return WT_STATUS_UNTRACKED;
902 if (!strcasecmp(var+offset, "nobranch"))
903 return WT_STATUS_NOBRANCH;
904 if (!strcasecmp(var+offset, "unmerged"))
905 return WT_STATUS_UNMERGED;
906 return -1;
909 static int git_status_config(const char *k, const char *v, void *cb)
911 struct wt_status *s = cb;
913 if (!strcmp(k, "status.submodulesummary")) {
914 int is_bool;
915 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
916 if (is_bool && s->submodule_summary)
917 s->submodule_summary = -1;
918 return 0;
920 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
921 s->use_color = git_config_colorbool(k, v, -1);
922 return 0;
924 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
925 int slot = parse_status_slot(k, 13);
926 if (slot < 0)
927 return 0;
928 if (!v)
929 return config_error_nonbool(k);
930 color_parse(v, k, s->color_palette[slot]);
931 return 0;
933 if (!strcmp(k, "status.relativepaths")) {
934 s->relative_paths = git_config_bool(k, v);
935 return 0;
937 if (!strcmp(k, "status.showuntrackedfiles")) {
938 if (!v)
939 return config_error_nonbool(k);
940 else if (!strcmp(v, "no"))
941 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
942 else if (!strcmp(v, "normal"))
943 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
944 else if (!strcmp(v, "all"))
945 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
946 else
947 return error("Invalid untracked files mode '%s'", v);
948 return 0;
950 return git_diff_ui_config(k, v, NULL);
953 int cmd_status(int argc, const char **argv, const char *prefix)
955 struct wt_status s;
957 wt_status_prepare(&s);
958 git_config(git_status_config, &s);
959 if (s.use_color == -1)
960 s.use_color = git_use_color_default;
961 if (diff_use_color_default == -1)
962 diff_use_color_default = git_use_color_default;
964 argc = parse_and_validate_options(argc, argv, builtin_status_usage,
965 prefix, &s);
966 return dry_run_commit(argc, argv, prefix, &s);
969 static void print_summary(const char *prefix, const unsigned char *sha1)
971 struct rev_info rev;
972 struct commit *commit;
973 struct strbuf format = STRBUF_INIT;
974 unsigned char junk_sha1[20];
975 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
976 struct pretty_print_context pctx = {0};
977 struct strbuf author_ident = STRBUF_INIT;
978 struct strbuf committer_ident = STRBUF_INIT;
980 commit = lookup_commit(sha1);
981 if (!commit)
982 die("couldn't look up newly created commit");
983 if (!commit || parse_commit(commit))
984 die("could not parse newly created commit");
986 strbuf_addstr(&format, "format:%h] %s");
988 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
989 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
990 if (strbuf_cmp(&author_ident, &committer_ident)) {
991 strbuf_addstr(&format, "\n Author: ");
992 strbuf_addbuf_percentquote(&format, &author_ident);
994 if (!user_ident_explicitly_given) {
995 strbuf_addstr(&format, "\n Committer: ");
996 strbuf_addbuf_percentquote(&format, &committer_ident);
997 strbuf_addch(&format, '\n');
998 strbuf_addstr(&format, implicit_ident_advice);
1000 strbuf_release(&author_ident);
1001 strbuf_release(&committer_ident);
1003 init_revisions(&rev, prefix);
1004 setup_revisions(0, NULL, &rev, NULL);
1006 rev.abbrev = 0;
1007 rev.diff = 1;
1008 rev.diffopt.output_format =
1009 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1011 rev.verbose_header = 1;
1012 rev.show_root_diff = 1;
1013 get_commit_format(format.buf, &rev);
1014 strbuf_release(&format);
1015 rev.always_show_header = 0;
1016 rev.diffopt.detect_rename = 1;
1017 rev.diffopt.rename_limit = 100;
1018 rev.diffopt.break_opt = 0;
1019 diff_setup_done(&rev.diffopt);
1021 printf("[%s%s ",
1022 !prefixcmp(head, "refs/heads/") ?
1023 head + 11 :
1024 !strcmp(head, "HEAD") ?
1025 "detached HEAD" :
1026 head,
1027 initial_commit ? " (root-commit)" : "");
1029 if (!log_tree_commit(&rev, commit)) {
1030 struct pretty_print_context ctx = {0};
1031 struct strbuf buf = STRBUF_INIT;
1032 ctx.date_mode = DATE_NORMAL;
1033 format_commit_message(commit, format.buf + 7, &buf, &ctx);
1034 printf("%s\n", buf.buf);
1035 strbuf_release(&buf);
1039 static int git_commit_config(const char *k, const char *v, void *cb)
1041 struct wt_status *s = cb;
1043 if (!strcmp(k, "commit.template"))
1044 return git_config_pathname(&template_file, k, v);
1046 return git_status_config(k, v, s);
1049 int cmd_commit(int argc, const char **argv, const char *prefix)
1051 struct strbuf sb = STRBUF_INIT;
1052 const char *index_file, *reflog_msg;
1053 char *nl, *p;
1054 unsigned char commit_sha1[20];
1055 struct ref_lock *ref_lock;
1056 struct commit_list *parents = NULL, **pptr = &parents;
1057 struct stat statbuf;
1058 int allow_fast_forward = 1;
1059 struct wt_status s;
1061 wt_status_prepare(&s);
1062 git_config(git_commit_config, &s);
1064 if (s.use_color == -1)
1065 s.use_color = git_use_color_default;
1067 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1068 prefix, &s);
1069 if (dry_run) {
1070 if (diff_use_color_default == -1)
1071 diff_use_color_default = git_use_color_default;
1072 return dry_run_commit(argc, argv, prefix, &s);
1074 index_file = prepare_index(argc, argv, prefix, 0);
1076 /* Set up everything for writing the commit object. This includes
1077 running hooks, writing the trees, and interacting with the user. */
1078 if (!prepare_to_commit(index_file, prefix, &s)) {
1079 rollback_index_files();
1080 return 1;
1083 /* Determine parents */
1084 if (initial_commit) {
1085 reflog_msg = "commit (initial)";
1086 } else if (amend) {
1087 struct commit_list *c;
1088 struct commit *commit;
1090 reflog_msg = "commit (amend)";
1091 commit = lookup_commit(head_sha1);
1092 if (!commit || parse_commit(commit))
1093 die("could not parse HEAD commit");
1095 for (c = commit->parents; c; c = c->next)
1096 pptr = &commit_list_insert(c->item, pptr)->next;
1097 } else if (in_merge) {
1098 struct strbuf m = STRBUF_INIT;
1099 FILE *fp;
1101 reflog_msg = "commit (merge)";
1102 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1103 fp = fopen(git_path("MERGE_HEAD"), "r");
1104 if (fp == NULL)
1105 die_errno("could not open '%s' for reading",
1106 git_path("MERGE_HEAD"));
1107 while (strbuf_getline(&m, fp, '\n') != EOF) {
1108 unsigned char sha1[20];
1109 if (get_sha1_hex(m.buf, sha1) < 0)
1110 die("Corrupt MERGE_HEAD file (%s)", m.buf);
1111 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1113 fclose(fp);
1114 strbuf_release(&m);
1115 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1116 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1117 die_errno("could not read MERGE_MODE");
1118 if (!strcmp(sb.buf, "no-ff"))
1119 allow_fast_forward = 0;
1121 if (allow_fast_forward)
1122 parents = reduce_heads(parents);
1123 } else {
1124 reflog_msg = "commit";
1125 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1128 /* Finally, get the commit message */
1129 strbuf_reset(&sb);
1130 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1131 int saved_errno = errno;
1132 rollback_index_files();
1133 die("could not read commit message: %s", strerror(saved_errno));
1136 /* Truncate the message just before the diff, if any. */
1137 if (verbose) {
1138 p = strstr(sb.buf, "\ndiff --git ");
1139 if (p != NULL)
1140 strbuf_setlen(&sb, p - sb.buf + 1);
1143 if (cleanup_mode != CLEANUP_NONE)
1144 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1145 if (message_is_empty(&sb)) {
1146 rollback_index_files();
1147 fprintf(stderr, "Aborting commit due to empty commit message.\n");
1148 exit(1);
1151 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1152 fmt_ident(author_name, author_email, author_date,
1153 IDENT_ERROR_ON_NO_NAME))) {
1154 rollback_index_files();
1155 die("failed to write commit object");
1158 ref_lock = lock_any_ref_for_update("HEAD",
1159 initial_commit ? NULL : head_sha1,
1162 nl = strchr(sb.buf, '\n');
1163 if (nl)
1164 strbuf_setlen(&sb, nl + 1 - sb.buf);
1165 else
1166 strbuf_addch(&sb, '\n');
1167 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1168 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1170 if (!ref_lock) {
1171 rollback_index_files();
1172 die("cannot lock HEAD ref");
1174 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1175 rollback_index_files();
1176 die("cannot update HEAD ref");
1179 unlink(git_path("MERGE_HEAD"));
1180 unlink(git_path("MERGE_MSG"));
1181 unlink(git_path("MERGE_MODE"));
1182 unlink(git_path("SQUASH_MSG"));
1184 if (commit_index_files())
1185 die ("Repository has been updated, but unable to write\n"
1186 "new_index file. Check that disk is not full or quota is\n"
1187 "not exceeded, and then \"git reset HEAD\" to recover.");
1189 rerere();
1190 run_hook(get_index_file(), "post-commit", NULL);
1191 if (!quiet)
1192 print_summary(prefix, commit_sha1);
1194 return 0;