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)
194 for (i = 0; pattern[i]; i++)
199 overlay_tree_on_cache(with_tree, prefix);
201 for (i = 0; i < active_nr; i++) {
202 struct cache_entry *ce = active_cache[i];
203 struct string_list_item *item;
205 if (ce->ce_flags & CE_UPDATE)
207 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
209 item = string_list_insert(ce->name, list);
210 if (ce_skip_worktree(ce))
211 item->util = item; /* better a valid pointer than a fake one */
214 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
217 static void add_remove_files(struct string_list *list)
220 for (i = 0; i < list->nr; i++) {
222 struct string_list_item *p = &(list->items[i]);
224 /* p->util is skip-worktree */
228 if (!lstat(p->string, &st)) {
229 if (add_to_cache(p->string, &st, 0))
230 die("updating files failed");
232 remove_file_from_cache(p->string);
236 static void create_base_index(void)
239 struct unpack_trees_options opts;
242 if (initial_commit) {
247 memset(&opts, 0, sizeof(opts));
251 opts.src_index = &the_index;
252 opts.dst_index = &the_index;
254 opts.fn = oneway_merge;
255 tree = parse_tree_indirect(head_sha1);
257 die("failed to unpack HEAD tree object");
259 init_tree_desc(&t, tree->buffer, tree->size);
260 if (unpack_trees(1, &t, &opts))
261 exit(128); /* We've already reported the error, finish dying */
264 static void refresh_cache_or_die(int refresh_flags)
267 * refresh_flags contains REFRESH_QUIET, so the only errors
268 * are for unmerged entries.
270 if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
271 die_resolve_conflict("commit");
274 static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
277 struct string_list partial;
278 const char **pathspec = NULL;
279 int refresh_flags = REFRESH_QUIET;
282 refresh_flags |= REFRESH_UNMERGED;
284 if (interactive_add(argc, argv, prefix) != 0)
285 die("interactive add failed");
286 if (read_cache_preload(NULL) < 0)
287 die("index file corrupt");
288 commit_style = COMMIT_AS_IS;
289 return get_index_file();
293 pathspec = get_pathspec(prefix, argv);
295 if (read_cache_preload(pathspec) < 0)
296 die("index file corrupt");
299 * Non partial, non as-is commit.
301 * (1) get the real index;
302 * (2) update the_index as necessary;
303 * (3) write the_index out to the real index (still locked);
304 * (4) return the name of the locked index file.
306 * The caller should run hooks on the locked real index, and
307 * (A) if all goes well, commit the real index;
308 * (B) on failure, rollback the real index.
310 if (all || (also && pathspec && *pathspec)) {
311 int fd = hold_locked_index(&index_lock, 1);
312 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
313 refresh_cache_or_die(refresh_flags);
314 if (write_cache(fd, active_cache, active_nr) ||
315 close_lock_file(&index_lock))
316 die("unable to write new_index file");
317 commit_style = COMMIT_NORMAL;
318 return index_lock.filename;
324 * (1) return the name of the real index file.
326 * The caller should run hooks on the real index, and run
327 * hooks on the real index, and create commit from the_index.
328 * We still need to refresh the index here.
330 if (!only && (!pathspec || !*pathspec)) {
331 fd = hold_locked_index(&index_lock, 1);
332 refresh_cache_or_die(refresh_flags);
333 if (write_cache(fd, active_cache, active_nr) ||
334 commit_locked_index(&index_lock))
335 die("unable to write new_index file");
336 commit_style = COMMIT_AS_IS;
337 return get_index_file();
343 * (0) find the set of affected paths;
344 * (1) get lock on the real index file;
345 * (2) update the_index with the given paths;
346 * (3) write the_index out to the real index (still locked);
347 * (4) get lock on the false index file;
348 * (5) reset the_index from HEAD;
349 * (6) update the_index the same way as (2);
350 * (7) write the_index out to the false index file;
351 * (8) return the name of the false index file (still locked);
353 * The caller should run hooks on the locked false index, and
354 * create commit from it. Then
355 * (A) if all goes well, commit the real index;
356 * (B) on failure, rollback the real index;
357 * In either case, rollback the false index.
359 commit_style = COMMIT_PARTIAL;
362 die("cannot do a partial commit during a merge.");
364 memset(&partial, 0, sizeof(partial));
365 partial.strdup_strings = 1;
366 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
370 if (read_cache() < 0)
371 die("cannot read the index");
373 fd = hold_locked_index(&index_lock, 1);
374 add_remove_files(&partial);
375 refresh_cache(REFRESH_QUIET);
376 if (write_cache(fd, active_cache, active_nr) ||
377 close_lock_file(&index_lock))
378 die("unable to write new_index file");
380 fd = hold_lock_file_for_update(&false_lock,
381 git_path("next-index-%"PRIuMAX,
382 (uintmax_t) getpid()),
386 add_remove_files(&partial);
387 refresh_cache(REFRESH_QUIET);
389 if (write_cache(fd, active_cache, active_nr) ||
390 close_lock_file(&false_lock))
391 die("unable to write temporary index file");
394 read_cache_from(false_lock.filename);
396 return false_lock.filename;
399 static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
402 unsigned char sha1[20];
404 if (s->relative_paths)
409 s->reference = "HEAD^1";
411 s->verbose = verbose;
412 s->index_file = index_file;
415 s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
417 wt_status_collect(s);
419 switch (status_format) {
420 case STATUS_FORMAT_SHORT:
421 wt_shortstatus_print(s, null_termination);
423 case STATUS_FORMAT_PORCELAIN:
424 wt_porcelain_print(s, null_termination);
426 case STATUS_FORMAT_LONG:
431 return s->commitable;
434 static int is_a_merge(const unsigned char *sha1)
436 struct commit *commit = lookup_commit(sha1);
437 if (!commit || parse_commit(commit))
438 die("could not parse HEAD commit");
439 return !!(commit->parents && commit->parents->next);
442 static const char sign_off_header[] = "Signed-off-by: ";
444 static void determine_author_info(void)
446 char *name, *email, *date;
448 name = getenv("GIT_AUTHOR_NAME");
449 email = getenv("GIT_AUTHOR_EMAIL");
450 date = getenv("GIT_AUTHOR_DATE");
452 if (use_message && !renew_authorship) {
453 const char *a, *lb, *rb, *eol;
455 a = strstr(use_message_buffer, "\nauthor ");
457 die("invalid commit: %s", use_message);
459 lb = strstr(a + 8, " <");
460 rb = strstr(a + 8, "> ");
461 eol = strchr(a + 8, '\n');
462 if (!lb || !rb || !eol)
463 die("invalid commit: %s", use_message);
465 name = xstrndup(a + 8, lb - (a + 8));
466 email = xstrndup(lb + 2, rb - (lb + 2));
467 date = xstrndup(rb + 2, eol - (rb + 2));
471 const char *lb = strstr(force_author, " <");
472 const char *rb = strchr(force_author, '>');
475 die("malformed --author parameter");
476 name = xstrndup(force_author, lb - force_author);
477 email = xstrndup(lb + 2, rb - (lb + 2));
484 author_email = email;
488 static int ends_rfc2822_footer(struct strbuf *sb)
495 const char *buf = sb->buf;
497 for (i = len - 1; i > 0; i--) {
498 if (hit && buf[i] == '\n')
500 hit = (buf[i] == '\n');
503 while (i < len - 1 && buf[i] == '\n')
506 for (; i < len; i = k) {
507 for (k = i; k < len && buf[k] != '\n'; k++)
511 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
516 for (j = 0; i + j < len; j++) {
529 static int prepare_to_commit(const char *index_file, const char *prefix,
533 int commitable, saved_color_setting;
534 struct strbuf sb = STRBUF_INIT;
537 const char *hook_arg1 = NULL;
538 const char *hook_arg2 = NULL;
541 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
545 strbuf_addbuf(&sb, &message);
546 hook_arg1 = "message";
547 } else if (logfile && !strcmp(logfile, "-")) {
549 fprintf(stderr, "(reading log message from standard input)\n");
550 if (strbuf_read(&sb, 0, 0) < 0)
551 die_errno("could not read log from standard input");
552 hook_arg1 = "message";
553 } else if (logfile) {
554 if (strbuf_read_file(&sb, logfile, 0) < 0)
555 die_errno("could not read log file '%s'",
557 hook_arg1 = "message";
558 } else if (use_message) {
559 buffer = strstr(use_message_buffer, "\n\n");
560 if (!buffer || buffer[2] == '\0')
561 die("commit has empty message");
562 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
563 hook_arg1 = "commit";
564 hook_arg2 = use_message;
565 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
566 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
567 die_errno("could not read MERGE_MSG");
569 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
570 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
571 die_errno("could not read SQUASH_MSG");
572 hook_arg1 = "squash";
573 } else if (template_file && !stat(template_file, &statbuf)) {
574 if (strbuf_read_file(&sb, template_file, 0) < 0)
575 die_errno("could not read '%s'", template_file);
576 hook_arg1 = "template";
580 * This final case does not modify the template message,
581 * it just sets the argument to the prepare-commit-msg hook.
586 fp = fopen(git_path(commit_editmsg), "w");
588 die_errno("could not open '%s'", git_path(commit_editmsg));
590 if (cleanup_mode != CLEANUP_NONE)
594 struct strbuf sob = STRBUF_INIT;
597 strbuf_addstr(&sob, sign_off_header);
598 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
599 getenv("GIT_COMMITTER_EMAIL")));
600 strbuf_addch(&sob, '\n');
601 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
603 if (prefixcmp(sb.buf + i, sob.buf)) {
604 if (!i || !ends_rfc2822_footer(&sb))
605 strbuf_addch(&sb, '\n');
606 strbuf_addbuf(&sb, &sob);
608 strbuf_release(&sob);
611 if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
612 die_errno("could not write commit template");
616 determine_author_info();
618 /* This checks if committer ident is explicitly given */
619 git_committer_info(0);
620 if (use_editor && include_status) {
622 const char *committer_ident;
627 "# It looks like you may be committing a MERGE.\n"
628 "# If this is not correct, please remove the file\n"
632 git_path("MERGE_HEAD"));
636 "# Please enter the commit message for your changes.");
637 if (cleanup_mode == CLEANUP_ALL)
640 "# with '#' will be ignored, and an empty"
641 " message aborts the commit.\n");
642 else /* CLEANUP_SPACE, that is. */
645 "# with '#' will be kept; you may remove them"
646 " yourself if you want to.\n"
647 "# An empty message aborts the commit.\n");
648 if (only_include_assumed)
649 fprintf(fp, "# %s\n", only_include_assumed);
651 author_ident = xstrdup(fmt_name(author_name, author_email));
652 committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
653 getenv("GIT_COMMITTER_EMAIL"));
654 if (strcmp(author_ident, committer_ident))
658 ident_shown++ ? "" : "#\n",
662 if (!user_ident_sufficiently_given())
666 ident_shown++ ? "" : "#\n",
672 saved_color_setting = s->use_color;
674 commitable = run_status(fp, index_file, prefix, 1, s);
675 s->use_color = saved_color_setting;
677 unsigned char sha1[20];
678 const char *parent = "HEAD";
680 if (!active_nr && read_cache() < 0)
681 die("Cannot read index");
686 if (get_sha1(parent, sha1))
687 commitable = !!active_nr;
689 commitable = index_differs_from(parent, 0);
694 if (!commitable && !in_merge && !allow_empty &&
695 !(amend && is_a_merge(head_sha1))) {
696 run_status(stdout, index_file, prefix, 0, s);
701 * Re-read the index as pre-commit hook could have updated it,
702 * and write it out as a tree. We must do this before we invoke
703 * the editor and after we invoke run_status above.
706 read_cache_from(index_file);
707 if (!active_cache_tree)
708 active_cache_tree = cache_tree();
709 if (cache_tree_update(active_cache_tree,
710 active_cache, active_nr, 0, 0) < 0) {
711 error("Error building trees");
715 if (run_hook(index_file, "prepare-commit-msg",
716 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
720 char index[PATH_MAX];
721 const char *env[2] = { index, NULL };
722 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
723 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
725 "Please supply the message using either -m or -F option.\n");
731 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
739 * Find out if the message in the strbuf contains only whitespace and
740 * Signed-off-by lines.
742 static int message_is_empty(struct strbuf *sb)
744 struct strbuf tmpl = STRBUF_INIT;
746 int eol, i, start = 0;
748 if (cleanup_mode == CLEANUP_NONE && sb->len)
751 /* See if the template is just a prefix of the message. */
752 if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
753 stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
754 if (start + tmpl.len <= sb->len &&
755 memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
758 strbuf_release(&tmpl);
760 /* Check if the rest is just whitespace and Signed-of-by's. */
761 for (i = start; i < sb->len; i++) {
762 nl = memchr(sb->buf + i, '\n', sb->len - i);
768 if (strlen(sign_off_header) <= eol - i &&
769 !prefixcmp(sb->buf + i, sign_off_header)) {
774 if (!isspace(sb->buf[i++]))
781 static const char *find_author_by_nickname(const char *name)
783 struct rev_info revs;
784 struct commit *commit;
785 struct strbuf buf = STRBUF_INIT;
789 init_revisions(&revs, NULL);
790 strbuf_addf(&buf, "--author=%s", name);
795 setup_revisions(ac, av, &revs, NULL);
796 prepare_revision_walk(&revs);
797 commit = get_revision(&revs);
799 struct pretty_print_context ctx = {0};
800 ctx.date_mode = DATE_NORMAL;
801 strbuf_release(&buf);
802 format_commit_message(commit, "%an <%ae>", &buf, &ctx);
803 return strbuf_detach(&buf, NULL);
805 die("No existing author found with '%s'", name);
809 static void handle_untracked_files_arg(struct wt_status *s)
811 if (!untracked_files_arg)
812 ; /* default already initialized */
813 else if (!strcmp(untracked_files_arg, "no"))
814 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
815 else if (!strcmp(untracked_files_arg, "normal"))
816 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
817 else if (!strcmp(untracked_files_arg, "all"))
818 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
820 die("Invalid untracked files mode '%s'", untracked_files_arg);
823 static int parse_and_validate_options(int argc, const char *argv[],
824 const char * const usage[],
830 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
833 if (force_author && !strchr(force_author, '>'))
834 force_author = find_author_by_nickname(force_author);
836 if (force_author && renew_authorship)
837 die("Using both --reset-author and --author does not make sense");
839 if (logfile || message.len || use_message)
844 setenv("GIT_EDITOR", ":", 1);
846 if (get_sha1("HEAD", head_sha1))
849 /* Sanity check options */
850 if (amend && initial_commit)
851 die("You have nothing to amend.");
852 if (amend && in_merge)
853 die("You are in the middle of a merge -- cannot amend.");
862 die("Only one of -c/-C/-F can be used.");
863 if (message.len && f > 0)
864 die("Option -m cannot be combined with -c/-C/-F.");
866 use_message = edit_message;
867 if (amend && !use_message)
868 use_message = "HEAD";
869 if (!use_message && renew_authorship)
870 die("--reset-author can be used only with -C, -c or --amend.");
872 unsigned char sha1[20];
873 static char utf8[] = "UTF-8";
876 struct commit *commit;
878 if (get_sha1(use_message, sha1))
879 die("could not lookup commit %s", use_message);
880 commit = lookup_commit_reference(sha1);
881 if (!commit || parse_commit(commit))
882 die("could not parse commit %s", use_message);
884 enc = strstr(commit->buffer, "\nencoding");
886 end = strchr(enc + 10, '\n');
887 enc = xstrndup(enc + 10, end - (enc + 10));
891 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
893 if (strcmp(out_enc, enc))
895 reencode_string(commit->buffer, out_enc, enc);
898 * If we failed to reencode the buffer, just copy it
899 * byte for byte so the user can try to fix it up.
900 * This also handles the case where input and output
901 * encodings are identical.
903 if (use_message_buffer == NULL)
904 use_message_buffer = xstrdup(commit->buffer);
909 if (!!also + !!only + !!all + !!interactive > 1)
910 die("Only one of --include/--only/--all/--interactive can be used.");
911 if (argc == 0 && (also || (only && !amend)))
912 die("No paths with --include/--only does not make sense.");
913 if (argc == 0 && only && amend)
914 only_include_assumed = "Clever... amending the last one with dirty index.";
915 if (argc > 0 && !also && !only)
916 only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
917 if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
918 cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
919 else if (!strcmp(cleanup_arg, "verbatim"))
920 cleanup_mode = CLEANUP_NONE;
921 else if (!strcmp(cleanup_arg, "whitespace"))
922 cleanup_mode = CLEANUP_SPACE;
923 else if (!strcmp(cleanup_arg, "strip"))
924 cleanup_mode = CLEANUP_ALL;
926 die("Invalid cleanup mode %s", cleanup_arg);
928 handle_untracked_files_arg(s);
931 die("Paths with -a does not make sense.");
932 else if (interactive && argc > 0)
933 die("Paths with --interactive does not make sense.");
935 if (null_termination && status_format == STATUS_FORMAT_LONG)
936 status_format = STATUS_FORMAT_PORCELAIN;
937 if (status_format != STATUS_FORMAT_LONG)
943 static int dry_run_commit(int argc, const char **argv, const char *prefix,
947 const char *index_file;
949 index_file = prepare_index(argc, argv, prefix, 1);
950 commitable = run_status(stdout, index_file, prefix, 0, s);
951 rollback_index_files();
953 return commitable ? 0 : 1;
956 static int parse_status_slot(const char *var, int offset)
958 if (!strcasecmp(var+offset, "header"))
959 return WT_STATUS_HEADER;
960 if (!strcasecmp(var+offset, "updated")
961 || !strcasecmp(var+offset, "added"))
962 return WT_STATUS_UPDATED;
963 if (!strcasecmp(var+offset, "changed"))
964 return WT_STATUS_CHANGED;
965 if (!strcasecmp(var+offset, "untracked"))
966 return WT_STATUS_UNTRACKED;
967 if (!strcasecmp(var+offset, "nobranch"))
968 return WT_STATUS_NOBRANCH;
969 if (!strcasecmp(var+offset, "unmerged"))
970 return WT_STATUS_UNMERGED;
974 static int git_status_config(const char *k, const char *v, void *cb)
976 struct wt_status *s = cb;
978 if (!strcmp(k, "status.submodulesummary")) {
980 s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
981 if (is_bool && s->submodule_summary)
982 s->submodule_summary = -1;
985 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
986 s->use_color = git_config_colorbool(k, v, -1);
989 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
990 int slot = parse_status_slot(k, 13);
994 return config_error_nonbool(k);
995 color_parse(v, k, s->color_palette[slot]);
998 if (!strcmp(k, "status.relativepaths")) {
999 s->relative_paths = git_config_bool(k, v);
1002 if (!strcmp(k, "status.showuntrackedfiles")) {
1004 return config_error_nonbool(k);
1005 else if (!strcmp(v, "no"))
1006 s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
1007 else if (!strcmp(v, "normal"))
1008 s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
1009 else if (!strcmp(v, "all"))
1010 s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
1012 return error("Invalid untracked files mode '%s'", v);
1015 return git_diff_ui_config(k, v, NULL);
1018 int cmd_status(int argc, const char **argv, const char *prefix)
1021 unsigned char sha1[20];
1022 static struct option builtin_status_options[] = {
1023 OPT__VERBOSE(&verbose),
1024 OPT_SET_INT('s', "short", &status_format,
1025 "show status concisely", STATUS_FORMAT_SHORT),
1026 OPT_SET_INT(0, "porcelain", &status_format,
1027 "show porcelain output format",
1028 STATUS_FORMAT_PORCELAIN),
1029 OPT_BOOLEAN('z', "null", &null_termination,
1030 "terminate entries with NUL"),
1031 { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
1033 "show untracked files, optional modes: all, normal, no. (Default: all)",
1034 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1038 if (null_termination && status_format == STATUS_FORMAT_LONG)
1039 status_format = STATUS_FORMAT_PORCELAIN;
1041 wt_status_prepare(&s);
1042 git_config(git_status_config, &s);
1043 in_merge = file_exists(git_path("MERGE_HEAD"));
1044 argc = parse_options(argc, argv, prefix,
1045 builtin_status_options,
1046 builtin_status_usage, 0);
1047 handle_untracked_files_arg(&s);
1050 s.pathspec = get_pathspec(prefix, argv);
1052 read_cache_preload(s.pathspec);
1053 refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
1054 s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
1055 s.in_merge = in_merge;
1056 wt_status_collect(&s);
1058 if (s.relative_paths)
1060 if (s.use_color == -1)
1061 s.use_color = git_use_color_default;
1062 if (diff_use_color_default == -1)
1063 diff_use_color_default = git_use_color_default;
1065 switch (status_format) {
1066 case STATUS_FORMAT_SHORT:
1067 wt_shortstatus_print(&s, null_termination);
1069 case STATUS_FORMAT_PORCELAIN:
1070 wt_porcelain_print(&s, null_termination);
1072 case STATUS_FORMAT_LONG:
1073 s.verbose = verbose;
1074 wt_status_print(&s);
1080 static void print_summary(const char *prefix, const unsigned char *sha1)
1082 struct rev_info rev;
1083 struct commit *commit;
1084 struct strbuf format = STRBUF_INIT;
1085 unsigned char junk_sha1[20];
1086 const char *head = resolve_ref("HEAD", junk_sha1, 0, NULL);
1087 struct pretty_print_context pctx = {0};
1088 struct strbuf author_ident = STRBUF_INIT;
1089 struct strbuf committer_ident = STRBUF_INIT;
1091 commit = lookup_commit(sha1);
1093 die("couldn't look up newly created commit");
1094 if (!commit || parse_commit(commit))
1095 die("could not parse newly created commit");
1097 strbuf_addstr(&format, "format:%h] %s");
1099 format_commit_message(commit, "%an <%ae>", &author_ident, &pctx);
1100 format_commit_message(commit, "%cn <%ce>", &committer_ident, &pctx);
1101 if (strbuf_cmp(&author_ident, &committer_ident)) {
1102 strbuf_addstr(&format, "\n Author: ");
1103 strbuf_addbuf_percentquote(&format, &author_ident);
1105 if (!user_ident_sufficiently_given()) {
1106 strbuf_addstr(&format, "\n Committer: ");
1107 strbuf_addbuf_percentquote(&format, &committer_ident);
1108 if (advice_implicit_identity) {
1109 strbuf_addch(&format, '\n');
1110 strbuf_addstr(&format, implicit_ident_advice);
1113 strbuf_release(&author_ident);
1114 strbuf_release(&committer_ident);
1116 init_revisions(&rev, prefix);
1117 setup_revisions(0, NULL, &rev, NULL);
1121 rev.diffopt.output_format =
1122 DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;
1124 rev.verbose_header = 1;
1125 rev.show_root_diff = 1;
1126 get_commit_format(format.buf, &rev);
1127 rev.always_show_header = 0;
1128 rev.diffopt.detect_rename = 1;
1129 rev.diffopt.rename_limit = 100;
1130 rev.diffopt.break_opt = 0;
1131 diff_setup_done(&rev.diffopt);
1134 !prefixcmp(head, "refs/heads/") ?
1136 !strcmp(head, "HEAD") ?
1139 initial_commit ? " (root-commit)" : "");
1141 if (!log_tree_commit(&rev, commit)) {
1142 struct pretty_print_context ctx = {0};
1143 struct strbuf buf = STRBUF_INIT;
1144 ctx.date_mode = DATE_NORMAL;
1145 format_commit_message(commit, format.buf + 7, &buf, &ctx);
1146 printf("%s\n", buf.buf);
1147 strbuf_release(&buf);
1149 strbuf_release(&format);
1152 static int git_commit_config(const char *k, const char *v, void *cb)
1154 struct wt_status *s = cb;
1156 if (!strcmp(k, "commit.template"))
1157 return git_config_pathname(&template_file, k, v);
1158 if (!strcmp(k, "commit.status")) {
1159 include_status = git_config_bool(k, v);
1163 return git_status_config(k, v, s);
1166 int cmd_commit(int argc, const char **argv, const char *prefix)
1168 struct strbuf sb = STRBUF_INIT;
1169 const char *index_file, *reflog_msg;
1171 unsigned char commit_sha1[20];
1172 struct ref_lock *ref_lock;
1173 struct commit_list *parents = NULL, **pptr = &parents;
1174 struct stat statbuf;
1175 int allow_fast_forward = 1;
1178 wt_status_prepare(&s);
1179 git_config(git_commit_config, &s);
1180 in_merge = file_exists(git_path("MERGE_HEAD"));
1181 s.in_merge = in_merge;
1183 if (s.use_color == -1)
1184 s.use_color = git_use_color_default;
1185 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1188 if (diff_use_color_default == -1)
1189 diff_use_color_default = git_use_color_default;
1190 return dry_run_commit(argc, argv, prefix, &s);
1192 index_file = prepare_index(argc, argv, prefix, 0);
1194 /* Set up everything for writing the commit object. This includes
1195 running hooks, writing the trees, and interacting with the user. */
1196 if (!prepare_to_commit(index_file, prefix, &s)) {
1197 rollback_index_files();
1201 /* Determine parents */
1202 if (initial_commit) {
1203 reflog_msg = "commit (initial)";
1205 struct commit_list *c;
1206 struct commit *commit;
1208 reflog_msg = "commit (amend)";
1209 commit = lookup_commit(head_sha1);
1210 if (!commit || parse_commit(commit))
1211 die("could not parse HEAD commit");
1213 for (c = commit->parents; c; c = c->next)
1214 pptr = &commit_list_insert(c->item, pptr)->next;
1215 } else if (in_merge) {
1216 struct strbuf m = STRBUF_INIT;
1219 reflog_msg = "commit (merge)";
1220 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1221 fp = fopen(git_path("MERGE_HEAD"), "r");
1223 die_errno("could not open '%s' for reading",
1224 git_path("MERGE_HEAD"));
1225 while (strbuf_getline(&m, fp, '\n') != EOF) {
1226 unsigned char sha1[20];
1227 if (get_sha1_hex(m.buf, sha1) < 0)
1228 die("Corrupt MERGE_HEAD file (%s)", m.buf);
1229 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1233 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1234 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1235 die_errno("could not read MERGE_MODE");
1236 if (!strcmp(sb.buf, "no-ff"))
1237 allow_fast_forward = 0;
1239 if (allow_fast_forward)
1240 parents = reduce_heads(parents);
1242 reflog_msg = "commit";
1243 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1246 /* Finally, get the commit message */
1248 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1249 int saved_errno = errno;
1250 rollback_index_files();
1251 die("could not read commit message: %s", strerror(saved_errno));
1254 /* Truncate the message just before the diff, if any. */
1256 p = strstr(sb.buf, "\ndiff --git ");
1258 strbuf_setlen(&sb, p - sb.buf + 1);
1261 if (cleanup_mode != CLEANUP_NONE)
1262 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1263 if (message_is_empty(&sb)) {
1264 rollback_index_files();
1265 fprintf(stderr, "Aborting commit due to empty commit message.\n");
1269 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1270 fmt_ident(author_name, author_email, author_date,
1271 IDENT_ERROR_ON_NO_NAME))) {
1272 rollback_index_files();
1273 die("failed to write commit object");
1276 ref_lock = lock_any_ref_for_update("HEAD",
1277 initial_commit ? NULL : head_sha1,
1280 nl = strchr(sb.buf, '\n');
1282 strbuf_setlen(&sb, nl + 1 - sb.buf);
1284 strbuf_addch(&sb, '\n');
1285 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1286 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1289 rollback_index_files();
1290 die("cannot lock HEAD ref");
1292 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1293 rollback_index_files();
1294 die("cannot update HEAD ref");
1297 unlink(git_path("MERGE_HEAD"));
1298 unlink(git_path("MERGE_MSG"));
1299 unlink(git_path("MERGE_MODE"));
1300 unlink(git_path("SQUASH_MSG"));
1302 if (commit_index_files())
1303 die ("Repository has been updated, but unable to write\n"
1304 "new_index file. Check that disk is not full or quota is\n"
1305 "not exceeded, and then \"git reset HEAD\" to recover.");
1308 run_hook(get_index_file(), "post-commit", NULL);
1310 print_summary(prefix, commit_sha1);