4 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
5 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
9 #include "cache-tree.h"
17 #include "wt-status.h"
18 #include "run-command.h"
23 #include "parse-options.h"
24 #include "string-list.h"
26 #include "unpack-trees.h"
29 static const char * const builtin_commit_usage[] = {
30 "git commit [options] [--] <filepattern>...",
34 static const char * const builtin_status_usage[] = {
35 "git status [options] [--] <filepattern>...",
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"
44 " git config --global user.name \"Your Name\"\n"
45 " git config --global user.email you@example.com\n"
47 "If the identity used for this commit is wrong, you can fix it with:\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 */
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 char *untracked_files_arg, *force_date;
71 * The default commit message cleanup mode will remove the lines
72 * beginning with # (shell comments) and leading and trailing
73 * whitespaces (empty lines or containing only whitespaces)
74 * if editor is used, and only the whitespaces if the message
75 * is specified explicitly.
82 static char *cleanup_arg;
84 static int use_editor = 1, initial_commit, in_merge, include_status = 1;
85 static const char *only_include_assumed;
86 static struct strbuf message;
88 static int null_termination;
92 STATUS_FORMAT_PORCELAIN,
93 } status_format = STATUS_FORMAT_LONG;
95 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
97 struct strbuf *buf = opt->value;
99 strbuf_setlen(buf, 0);
101 strbuf_addstr(buf, arg);
102 strbuf_addstr(buf, "\n\n");
107 static struct option builtin_commit_options[] = {
109 OPT__VERBOSE(&verbose),
111 OPT_GROUP("Commit message options"),
112 OPT_FILENAME('F', "file", &logfile, "read log from file"),
113 OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
114 OPT_STRING(0, "date", &force_date, "DATE", "override date for commit"),
115 OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
116 OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
117 OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
118 OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
119 OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
120 OPT_FILENAME('t', "template", &template_file, "use specified template file"),
121 OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
122 OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
123 OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
124 /* end commit message options */
126 OPT_GROUP("Commit contents options"),
127 OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
128 OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
129 OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
130 OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
131 OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
132 OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
133 OPT_SET_INT(0, "short", &status_format, "show status concisely",
134 STATUS_FORMAT_SHORT),
135 OPT_SET_INT(0, "porcelain", &status_format,
136 "show porcelain output format", STATUS_FORMAT_PORCELAIN),
137 OPT_BOOLEAN('z', "null", &null_termination,
138 "terminate entries with NUL"),
139 OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
140 { 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" },
141 OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
142 /* end commit contents options */
147 static void rollback_index_files(void)
149 switch (commit_style) {
151 break; /* nothing to do */
153 rollback_lock_file(&index_lock);
156 rollback_lock_file(&index_lock);
157 rollback_lock_file(&false_lock);
162 static int commit_index_files(void)
166 switch (commit_style) {
168 break; /* nothing to do */
170 err = commit_lock_file(&index_lock);
173 err = commit_lock_file(&index_lock);
174 rollback_lock_file(&false_lock);
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.
185 static int list_paths(struct string_list *list, const char *with_tree,
186 const char *prefix, const char **pattern)
191 for (i = 0; pattern[i]; i++)
196 overlay_tree_on_cache(with_tree, prefix);
198 for (i = 0; i < active_nr; i++) {
199 struct cache_entry *ce = active_cache[i];
200 struct string_list_item *item;
202 if (ce->ce_flags & CE_UPDATE)
204 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
206 item = string_list_insert(ce->name, list);
207 if (ce_skip_worktree(ce))
208 item->util = item; /* better a valid pointer than a fake one */
211 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
214 static void add_remove_files(struct string_list *list)
217 for (i = 0; i < list->nr; i++) {
219 struct string_list_item *p = &(list->items[i]);
221 /* p->util is skip-worktree */
225 if (!lstat(p->string, &st)) {
226 if (add_to_cache(p->string, &st, 0))
227 die("updating files failed");
229 remove_file_from_cache(p->string);
233 static void create_base_index(void)
236 struct unpack_trees_options opts;
239 if (initial_commit) {
244 memset(&opts, 0, sizeof(opts));
248 opts.src_index = &the_index;
249 opts.dst_index = &the_index;
251 opts.fn = oneway_merge;
252 tree = parse_tree_indirect(head_sha1);
254 die("failed to unpack HEAD tree object");
256 init_tree_desc(&t, tree->buffer, tree->size);
257 if (unpack_trees(1, &t, &opts))
258 exit(128); /* We've already reported the error, finish dying */
261 static void refresh_cache_or_die(int refresh_flags)
264 * refresh_flags contains REFRESH_QUIET, so the only errors
265 * are for unmerged entries.
267 if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
268 die_resolve_conflict("commit");
271 static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
274 struct string_list partial;
275 const char **pathspec = NULL;
276 int refresh_flags = REFRESH_QUIET;
279 refresh_flags |= REFRESH_UNMERGED;
281 if (interactive_add(argc, argv, prefix) != 0)
282 die("interactive add failed");
283 if (read_cache_preload(NULL) < 0)
284 die("index file corrupt");
285 commit_style = COMMIT_AS_IS;
286 return get_index_file();
290 pathspec = get_pathspec(prefix, argv);
292 if (read_cache_preload(pathspec) < 0)
293 die("index file corrupt");
296 * Non partial, non as-is commit.
298 * (1) get the real index;
299 * (2) update the_index as necessary;
300 * (3) write the_index out to the real index (still locked);
301 * (4) return the name of the locked index file.
303 * The caller should run hooks on the locked real index, and
304 * (A) if all goes well, commit the real index;
305 * (B) on failure, rollback the real index.
307 if (all || (also && pathspec && *pathspec)) {
308 int fd = hold_locked_index(&index_lock, 1);
309 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
310 refresh_cache_or_die(refresh_flags);
311 if (write_cache(fd, active_cache, active_nr) ||
312 close_lock_file(&index_lock))
313 die("unable to write new_index file");
314 commit_style = COMMIT_NORMAL;
315 return index_lock.filename;
321 * (1) return the name of the real index file.
323 * The caller should run hooks on the real index, and run
324 * hooks on the real index, and create commit from the_index.
325 * We still need to refresh the index here.
327 if (!pathspec || !*pathspec) {
328 fd = hold_locked_index(&index_lock, 1);
329 refresh_cache_or_die(refresh_flags);
330 if (write_cache(fd, active_cache, active_nr) ||
331 commit_locked_index(&index_lock))
332 die("unable to write new_index file");
333 commit_style = COMMIT_AS_IS;
334 return get_index_file();
340 * (0) find the set of affected paths;
341 * (1) get lock on the real index file;
342 * (2) update the_index with the given paths;
343 * (3) write the_index out to the real index (still locked);
344 * (4) get lock on the false index file;
345 * (5) reset the_index from HEAD;
346 * (6) update the_index the same way as (2);
347 * (7) write the_index out to the false index file;
348 * (8) return the name of the false index file (still locked);
350 * The caller should run hooks on the locked false index, and
351 * create commit from it. Then
352 * (A) if all goes well, commit the real index;
353 * (B) on failure, rollback the real index;
354 * In either case, rollback the false index.
356 commit_style = COMMIT_PARTIAL;
359 die("cannot do a partial commit during a merge.");
361 memset(&partial, 0, sizeof(partial));
362 partial.strdup_strings = 1;
363 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
367 if (read_cache() < 0)
368 die("cannot read the index");
370 fd = hold_locked_index(&index_lock, 1);
371 add_remove_files(&partial);
372 refresh_cache(REFRESH_QUIET);
373 if (write_cache(fd, active_cache, active_nr) ||
374 close_lock_file(&index_lock))
375 die("unable to write new_index file");
377 fd = hold_lock_file_for_update(&false_lock,
378 git_path("next-index-%"PRIuMAX,
379 (uintmax_t) getpid()),
383 add_remove_files(&partial);
384 refresh_cache(REFRESH_QUIET);
386 if (write_cache(fd, active_cache, active_nr) ||
387 close_lock_file(&false_lock))
388 die("unable to write temporary index file");
391 read_cache_from(false_lock.filename);
393 return false_lock.filename;
396 static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
399 unsigned char sha1[20];
401 if (s->relative_paths)
406 s->reference = "HEAD^1";
408 s->verbose = verbose;
409 s->index_file = index_file;
412 s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
414 wt_status_collect(s);
416 switch (status_format) {
417 case STATUS_FORMAT_SHORT:
418 wt_shortstatus_print(s, null_termination);
420 case STATUS_FORMAT_PORCELAIN:
421 wt_porcelain_print(s, null_termination);
423 case STATUS_FORMAT_LONG:
428 return s->commitable;
431 static int is_a_merge(const unsigned char *sha1)
433 struct commit *commit = lookup_commit(sha1);
434 if (!commit || parse_commit(commit))
435 die("could not parse HEAD commit");
436 return !!(commit->parents && commit->parents->next);
439 static const char sign_off_header[] = "Signed-off-by: ";
441 static void determine_author_info(void)
443 char *name, *email, *date;
445 name = getenv("GIT_AUTHOR_NAME");
446 email = getenv("GIT_AUTHOR_EMAIL");
447 date = getenv("GIT_AUTHOR_DATE");
449 if (use_message && !renew_authorship) {
450 const char *a, *lb, *rb, *eol;
452 a = strstr(use_message_buffer, "\nauthor ");
454 die("invalid commit: %s", use_message);
456 lb = strstr(a + 8, " <");
457 rb = strstr(a + 8, "> ");
458 eol = strchr(a + 8, '\n');
459 if (!lb || !rb || !eol)
460 die("invalid commit: %s", use_message);
462 name = xstrndup(a + 8, lb - (a + 8));
463 email = xstrndup(lb + 2, rb - (lb + 2));
464 date = xstrndup(rb + 2, eol - (rb + 2));
468 const char *lb = strstr(force_author, " <");
469 const char *rb = strchr(force_author, '>');
472 die("malformed --author parameter");
473 name = xstrndup(force_author, lb - force_author);
474 email = xstrndup(lb + 2, rb - (lb + 2));
481 author_email = email;
485 static int ends_rfc2822_footer(struct strbuf *sb)
492 const char *buf = sb->buf;
494 for (i = len - 1; i > 0; i--) {
495 if (hit && buf[i] == '\n')
497 hit = (buf[i] == '\n');
500 while (i < len - 1 && buf[i] == '\n')
503 for (; i < len; i = k) {
504 for (k = i; k < len && buf[k] != '\n'; k++)
508 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
513 for (j = 0; i + j < len; j++) {
526 static int prepare_to_commit(const char *index_file, const char *prefix,
530 int commitable, saved_color_setting;
531 struct strbuf sb = STRBUF_INIT;
534 const char *hook_arg1 = NULL;
535 const char *hook_arg2 = NULL;
538 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
542 strbuf_addbuf(&sb, &message);
543 hook_arg1 = "message";
544 } else if (logfile && !strcmp(logfile, "-")) {
546 fprintf(stderr, "(reading log message from standard input)\n");
547 if (strbuf_read(&sb, 0, 0) < 0)
548 die_errno("could not read log from standard input");
549 hook_arg1 = "message";
550 } else if (logfile) {
551 if (strbuf_read_file(&sb, logfile, 0) < 0)
552 die_errno("could not read log file '%s'",
554 hook_arg1 = "message";
555 } else if (use_message) {
556 buffer = strstr(use_message_buffer, "\n\n");
557 if (!buffer || buffer[2] == '\0')
558 die("commit has empty message");
559 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
560 hook_arg1 = "commit";
561 hook_arg2 = use_message;
562 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
563 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
564 die_errno("could not read MERGE_MSG");
566 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
567 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
568 die_errno("could not read SQUASH_MSG");
569 hook_arg1 = "squash";
570 } else if (template_file && !stat(template_file, &statbuf)) {
571 if (strbuf_read_file(&sb, template_file, 0) < 0)
572 die_errno("could not read '%s'", template_file);
573 hook_arg1 = "template";
577 * This final case does not modify the template message,
578 * it just sets the argument to the prepare-commit-msg hook.
583 fp = fopen(git_path(commit_editmsg), "w");
585 die_errno("could not open '%s'", git_path(commit_editmsg));
587 if (cleanup_mode != CLEANUP_NONE)
591 struct strbuf sob = STRBUF_INIT;
594 strbuf_addstr(&sob, sign_off_header);
595 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
596 getenv("GIT_COMMITTER_EMAIL")));
597 strbuf_addch(&sob, '\n');
598 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
600 if (prefixcmp(sb.buf + i, sob.buf)) {
601 if (!i || !ends_rfc2822_footer(&sb))
602 strbuf_addch(&sb, '\n');
603 strbuf_addbuf(&sb, &sob);
605 strbuf_release(&sob);
608 if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
609 die_errno("could not write commit template");
613 determine_author_info();
615 /* This checks if committer ident is explicitly given */
616 git_committer_info(0);
617 if (use_editor && include_status) {
619 const char *committer_ident;
624 "# It looks like you may be committing a MERGE.\n"
625 "# If this is not correct, please remove the file\n"
629 git_path("MERGE_HEAD"));
633 "# Please enter the commit message for your changes.");
634 if (cleanup_mode == CLEANUP_ALL)
637 "# with '#' will be ignored, and an empty"
638 " message aborts the commit.\n");
639 else /* CLEANUP_SPACE, that is. */
642 "# with '#' will be kept; you may remove them"
643 " yourself if you want to.\n"
644 "# An empty message aborts the commit.\n");
645 if (only_include_assumed)
646 fprintf(fp, "# %s\n", only_include_assumed);
648 author_ident = xstrdup(fmt_name(author_name, author_email));
649 committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
650 getenv("GIT_COMMITTER_EMAIL"));
651 if (strcmp(author_ident, committer_ident))
655 ident_shown++ ? "" : "#\n",
659 if (!user_ident_sufficiently_given())
663 ident_shown++ ? "" : "#\n",
669 saved_color_setting = s->use_color;
671 commitable = run_status(fp, index_file, prefix, 1, s);
672 s->use_color = saved_color_setting;
674 unsigned char sha1[20];
675 const char *parent = "HEAD";
677 if (!active_nr && read_cache() < 0)
678 die("Cannot read index");
683 if (get_sha1(parent, sha1))
684 commitable = !!active_nr;
686 commitable = index_differs_from(parent, 0);
691 if (!commitable && !in_merge && !allow_empty &&
692 !(amend && is_a_merge(head_sha1))) {
693 run_status(stdout, index_file, prefix, 0, s);
698 * Re-read the index as pre-commit hook could have updated it,
699 * and write it out as a tree. We must do this before we invoke
700 * the editor and after we invoke run_status above.
703 read_cache_from(index_file);
704 if (!active_cache_tree)
705 active_cache_tree = cache_tree();
706 if (cache_tree_update(active_cache_tree,
707 active_cache, active_nr, 0, 0) < 0) {
708 error("Error building trees");
712 if (run_hook(index_file, "prepare-commit-msg",
713 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
717 char index[PATH_MAX];
718 const char *env[2] = { index, NULL };
719 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
720 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
722 "Please supply the message using either -m or -F option.\n");
728 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
736 * Find out if the message in the strbuf contains only whitespace and
737 * Signed-off-by lines.
739 static int message_is_empty(struct strbuf *sb)
741 struct strbuf tmpl = STRBUF_INIT;
743 int eol, i, start = 0;
745 if (cleanup_mode == CLEANUP_NONE && sb->len)
748 /* See if the template is just a prefix of the message. */
749 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
750 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
751 if (start + tmpl.len <= sb->len &&
752 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
755 strbuf_release(&tmpl);
757 /* Check if the rest is just whitespace and Signed-of-by's. */
758 for (i = start; i < sb->len; i++) {
759 nl = memchr(sb->buf + i, '\n', sb->len - i);
765 if (strlen(sign_off_header) <= eol - i &&
766 !prefixcmp(sb->buf + i, sign_off_header)) {
771 if (!isspace(sb->buf[i++]))
778 static const char *find_author_by_nickname(const char *name)
780 struct rev_info revs;
781 struct commit *commit;
782 struct strbuf buf = STRBUF_INIT;
786 init_revisions(&revs, NULL);
787 strbuf_addf(&buf, "--author=%s", name);
792 setup_revisions(ac, av, &revs, NULL);
793 prepare_revision_walk(&revs);
794 commit = get_revision(&revs);
796 struct pretty_print_context ctx = {0};
797 ctx.date_mode = DATE_NORMAL;
798 strbuf_release(&buf);
799 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
800 return strbuf_detach(&buf, NULL);
802 die("No existing author found with '%s'", name);
806 static void handle_untracked_files_arg(struct wt_status *s)
808 if (!untracked_files_arg)
809 ; /* default already initialized */
810 else if (!strcmp(untracked_files_arg, "no"))
811 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
812 else if (!strcmp(untracked_files_arg, "normal"))
813 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
814 else if (!strcmp(untracked_files_arg, "all"))
815 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
817 die("Invalid untracked files mode '%s'", untracked_files_arg);
820 static int parse_and_validate_options(int argc, const char *argv[],
821 const char * const usage[],
827 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
830 if (force_author && !strchr(force_author, '>'))
831 force_author = find_author_by_nickname(force_author);
833 if (force_author && renew_authorship)
834 die("Using both --reset-author and --author does not make sense");
836 if (logfile || message.len || use_message)
841 setenv("GIT_EDITOR", ":", 1);
843 if (get_sha1("HEAD", head_sha1))
846 /* Sanity check options */
847 if (amend && initial_commit)
848 die("You have nothing to amend.");
849 if (amend && in_merge)
850 die("You are in the middle of a merge -- cannot amend.");
859 die("Only one of -c/-C/-F can be used.");
860 if (message.len && f > 0)
861 die("Option -m cannot be combined with -c/-C/-F.");
863 use_message = edit_message;
864 if (amend && !use_message)
865 use_message = "HEAD";
866 if (!use_message && renew_authorship)
867 die("--reset-author can be used only with -C, -c or --amend.");
869 unsigned char sha1[20];
870 static char utf8[] = "UTF-8";
873 struct commit *commit;
875 if (get_sha1(use_message, sha1))
876 die("could not lookup commit %s", use_message);
877 commit = lookup_commit_reference(sha1);
878 if (!commit || parse_commit(commit))
879 die("could not parse commit %s", use_message);
881 enc = strstr(commit->buffer, "\nencoding");
883 end = strchr(enc + 10, '\n');
884 enc = xstrndup(enc + 10, end - (enc + 10));
888 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
890 if (strcmp(out_enc, enc))
892 reencode_string(commit->buffer, out_enc, enc);
895 * If we failed to reencode the buffer, just copy it
896 * byte for byte so the user can try to fix it up.
897 * This also handles the case where input and output
898 * encodings are identical.
900 if (use_message_buffer == NULL)
901 use_message_buffer = xstrdup(commit->buffer);
906 if (!!also + !!only + !!all + !!interactive > 1)
907 die("Only one of --include/--only/--all/--interactive can be used.");
908 if (argc == 0 && (also || (only && !amend)))
909 die("No paths with --include/--only does not make sense.");
910 if (argc == 0 && only && amend)
911 only_include_assumed = "Clever... amending the last one with dirty index.";
912 if (argc > 0 && !also && !only)
913 only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
914 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
915 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
916 else if (!strcmp(cleanup_arg, "verbatim"))
917 cleanup_mode = CLEANUP_NONE;
918 else if (!strcmp(cleanup_arg, "whitespace"))
919 cleanup_mode = CLEANUP_SPACE;
920 else if (!strcmp(cleanup_arg, "strip"))
921 cleanup_mode = CLEANUP_ALL;
923 die("Invalid cleanup mode %s", cleanup_arg);
925 handle_untracked_files_arg(s);
928 die("Paths with -a does not make sense.");
929 else if (interactive && argc > 0)
930 die("Paths with --interactive does not make sense.");
932 if (null_termination && status_format == STATUS_FORMAT_LONG)
933 status_format = STATUS_FORMAT_PORCELAIN;
934 if (status_format != STATUS_FORMAT_LONG)
940 static int dry_run_commit(int argc, const char **argv, const char *prefix,
944 const char *index_file;
946 index_file = prepare_index(argc, argv, prefix, 1);
947 commitable = run_status(stdout, index_file, prefix, 0, s);
948 rollback_index_files();
950 return commitable ? 0 : 1;
953 static int parse_status_slot(const char *var, int offset)
955 if (!strcasecmp(var+offset, "header"))
956 return WT_STATUS_HEADER;
957 if (!strcasecmp(var+offset, "updated")
958 || !strcasecmp(var+offset, "added"))
959 return WT_STATUS_UPDATED;
960 if (!strcasecmp(var+offset, "changed"))
961 return WT_STATUS_CHANGED;
962 if (!strcasecmp(var+offset, "untracked"))
963 return WT_STATUS_UNTRACKED;
964 if (!strcasecmp(var+offset, "nobranch"))
965 return WT_STATUS_NOBRANCH;
966 if (!strcasecmp(var+offset, "unmerged"))
967 return WT_STATUS_UNMERGED;
971 static int git_status_config(const char *k, const char *v, void *cb)
973 struct wt_status *s = cb;
975 if (!strcmp(k, "status.submodulesummary")) {
977 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
978 if (is_bool && s->submodule_summary)
979 s->submodule_summary = -1;
982 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
983 s->use_color = git_config_colorbool(k, v, -1);
986 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
987 int slot = parse_status_slot(k, 13);
991 return config_error_nonbool(k);
992 color_parse(v, k, s->color_palette[slot]);
995 if (!strcmp(k, "status.relativepaths")) {
996 s->relative_paths = git_config_bool(k, v);
999 if (!strcmp(k, "status.showuntrackedfiles")) {
1001 return config_error_nonbool(k);
1002 else if (!strcmp(v, "no"))
1003 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
1004 else if (!strcmp(v, "normal"))
1005 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
1006 else if (!strcmp(v, "all"))
1007 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
1009 return error("Invalid untracked files mode '%s'", v);
1012 return git_diff_ui_config(k, v, NULL);
1015 int cmd_status(int argc, const char **argv, const char *prefix)
1018 unsigned char sha1[20];
1019 static struct option builtin_status_options[] = {
1020 OPT__VERBOSE(&verbose),
1021 OPT_SET_INT('s', "short", &status_format,
1022 "show status concisely", STATUS_FORMAT_SHORT),
1023 OPT_SET_INT(0, "porcelain", &status_format,
1024 "show porcelain output format",
1025 STATUS_FORMAT_PORCELAIN),
1026 OPT_BOOLEAN('z', "null", &null_termination,
1027 "terminate entries with NUL"),
1028 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1030 "show untracked files, optional modes: all, normal, no. (Default: all)",
1031 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1035 if (null_termination && status_format == STATUS_FORMAT_LONG)
1036 status_format = STATUS_FORMAT_PORCELAIN;
1038 wt_status_prepare(&s);
1039 git_config(git_status_config, &s);
1040 in_merge = file_exists(git_path("MERGE_HEAD"));
1041 argc = parse_options(argc, argv, prefix,
1042 builtin_status_options,
1043 builtin_status_usage, 0);
1044 handle_untracked_files_arg(&s);
1047 s.pathspec = get_pathspec(prefix, argv);
1049 read_cache_preload(s.pathspec);
1050 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1051 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1052 s.in_merge = in_merge;
1053 wt_status_collect(&s);
1055 if (s.relative_paths)
1057 if (s.use_color == -1)
1058 s.use_color = git_use_color_default;
1059 if (diff_use_color_default == -1)
1060 diff_use_color_default = git_use_color_default;
1062 switch (status_format) {
1063 case STATUS_FORMAT_SHORT:
1064 wt_shortstatus_print(&s, null_termination);
1066 case STATUS_FORMAT_PORCELAIN:
1067 wt_porcelain_print(&s, null_termination);
1069 case STATUS_FORMAT_LONG:
1070 s.verbose = verbose;
1071 wt_status_print(&s);
1077 static void print_summary(const char *prefix, const unsigned char *sha1)
1079 struct rev_info rev;
1080 struct commit *commit;
1081 struct strbuf format = STRBUF_INIT;
1082 unsigned char junk_sha1[20];
1083 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
1084 struct pretty_print_context pctx = {0};
1085 struct strbuf author_ident = STRBUF_INIT;
1086 struct strbuf committer_ident = STRBUF_INIT;
1088 commit = lookup_commit(sha1);
1090 die("couldn't look up newly created commit");
1091 if (!commit || parse_commit(commit))
1092 die("could not parse newly created commit");
1094 strbuf_addstr(&format, "format:%h] %s");
1096 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
1097 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
1098 if (strbuf_cmp(&author_ident, &committer_ident)) {
1099 strbuf_addstr(&format, "\n Author: ");
1100 strbuf_addbuf_percentquote(&format, &author_ident);
1102 if (!user_ident_sufficiently_given()) {
1103 strbuf_addstr(&format, "\n Committer: ");
1104 strbuf_addbuf_percentquote(&format, &committer_ident);
1105 if (advice_implicit_identity) {
1106 strbuf_addch(&format, '\n');
1107 strbuf_addstr(&format, implicit_ident_advice);
1110 strbuf_release(&author_ident);
1111 strbuf_release(&committer_ident);
1113 init_revisions(&rev, prefix);
1114 setup_revisions(0, NULL, &rev, NULL);
1118 rev.diffopt.output_format =
1119 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1121 rev.verbose_header = 1;
1122 rev.show_root_diff = 1;
1123 get_commit_format(format.buf, &rev);
1124 rev.always_show_header = 0;
1125 rev.diffopt.detect_rename = 1;
1126 rev.diffopt.rename_limit = 100;
1127 rev.diffopt.break_opt = 0;
1128 diff_setup_done(&rev.diffopt);
1131 !prefixcmp(head, "refs/heads/") ?
1133 !strcmp(head, "HEAD") ?
1136 initial_commit ? " (root-commit)" : "");
1138 if (!log_tree_commit(&rev, commit)) {
1139 struct pretty_print_context ctx = {0};
1140 struct strbuf buf = STRBUF_INIT;
1141 ctx.date_mode = DATE_NORMAL;
1142 format_commit_message(commit, format.buf + 7, &buf, &ctx);
1143 printf("%s\n", buf.buf);
1144 strbuf_release(&buf);
1146 strbuf_release(&format);
1149 static int git_commit_config(const char *k, const char *v, void *cb)
1151 struct wt_status *s = cb;
1153 if (!strcmp(k, "commit.template"))
1154 return git_config_pathname(&template_file, k, v);
1155 if (!strcmp(k, "commit.status")) {
1156 include_status = git_config_bool(k, v);
1160 return git_status_config(k, v, s);
1163 int cmd_commit(int argc, const char **argv, const char *prefix)
1165 struct strbuf sb = STRBUF_INIT;
1166 const char *index_file, *reflog_msg;
1168 unsigned char commit_sha1[20];
1169 struct ref_lock *ref_lock;
1170 struct commit_list *parents = NULL, **pptr = &parents;
1171 struct stat statbuf;
1172 int allow_fast_forward = 1;
1175 wt_status_prepare(&s);
1176 git_config(git_commit_config, &s);
1177 in_merge = file_exists(git_path("MERGE_HEAD"));
1178 s.in_merge = in_merge;
1180 if (s.use_color == -1)
1181 s.use_color = git_use_color_default;
1182 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1185 if (diff_use_color_default == -1)
1186 diff_use_color_default = git_use_color_default;
1187 return dry_run_commit(argc, argv, prefix, &s);
1189 index_file = prepare_index(argc, argv, prefix, 0);
1191 /* Set up everything for writing the commit object. This includes
1192 running hooks, writing the trees, and interacting with the user. */
1193 if (!prepare_to_commit(index_file, prefix, &s)) {
1194 rollback_index_files();
1198 /* Determine parents */
1199 if (initial_commit) {
1200 reflog_msg = "commit (initial)";
1202 struct commit_list *c;
1203 struct commit *commit;
1205 reflog_msg = "commit (amend)";
1206 commit = lookup_commit(head_sha1);
1207 if (!commit || parse_commit(commit))
1208 die("could not parse HEAD commit");
1210 for (c = commit->parents; c; c = c->next)
1211 pptr = &commit_list_insert(c->item, pptr)->next;
1212 } else if (in_merge) {
1213 struct strbuf m = STRBUF_INIT;
1216 reflog_msg = "commit (merge)";
1217 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1218 fp = fopen(git_path("MERGE_HEAD"), "r");
1220 die_errno("could not open '%s' for reading",
1221 git_path("MERGE_HEAD"));
1222 while (strbuf_getline(&m, fp, '\n') != EOF) {
1223 unsigned char sha1[20];
1224 if (get_sha1_hex(m.buf, sha1) < 0)
1225 die("Corrupt MERGE_HEAD file (%s)", m.buf);
1226 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1230 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1231 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1232 die_errno("could not read MERGE_MODE");
1233 if (!strcmp(sb.buf, "no-ff"))
1234 allow_fast_forward = 0;
1236 if (allow_fast_forward)
1237 parents = reduce_heads(parents);
1239 reflog_msg = "commit";
1240 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1243 /* Finally, get the commit message */
1245 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1246 int saved_errno = errno;
1247 rollback_index_files();
1248 die("could not read commit message: %s", strerror(saved_errno));
1251 /* Truncate the message just before the diff, if any. */
1253 p = strstr(sb.buf, "\ndiff --git ");
1255 strbuf_setlen(&sb, p - sb.buf + 1);
1258 if (cleanup_mode != CLEANUP_NONE)
1259 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1260 if (message_is_empty(&sb)) {
1261 rollback_index_files();
1262 fprintf(stderr, "Aborting commit due to empty commit message.\n");
1266 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1267 fmt_ident(author_name, author_email, author_date,
1268 IDENT_ERROR_ON_NO_NAME))) {
1269 rollback_index_files();
1270 die("failed to write commit object");
1273 ref_lock = lock_any_ref_for_update("HEAD",
1274 initial_commit ? NULL : head_sha1,
1277 nl = strchr(sb.buf, '\n');
1279 strbuf_setlen(&sb, nl + 1 - sb.buf);
1281 strbuf_addch(&sb, '\n');
1282 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1283 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1286 rollback_index_files();
1287 die("cannot lock HEAD ref");
1289 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1290 rollback_index_files();
1291 die("cannot update HEAD ref");
1294 unlink(git_path("MERGE_HEAD"));
1295 unlink(git_path("MERGE_MSG"));
1296 unlink(git_path("MERGE_MODE"));
1297 unlink(git_path("SQUASH_MSG"));
1299 if (commit_index_files())
1300 die ("Repository has been updated, but unable to write\n"
1301 "new_index file. Check that disk is not full or quota is\n"
1302 "not exceeded, and then \"git reset HEAD\" to recover.");
1305 run_hook(get_index_file(), "post-commit", NULL);
1307 print_summary(prefix, commit_sha1);