fixup.cc5711424b7ae36276a40c06ede5d95f87ca20f0
[git/dscho.git] / builtin-commit.c
blob55676fd874466c70445e81c69cf397cd01380aaf
1 /*
2 * Builtin "git commit"
4 * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
5 * Based on git-commit.sh by Junio C Hamano and Linus Torvalds
6 */
8 #include "cache.h"
9 #include "cache-tree.h"
10 #include "color.h"
11 #include "dir.h"
12 #include "builtin.h"
13 #include "diff.h"
14 #include "diffcore.h"
15 #include "commit.h"
16 #include "revision.h"
17 #include "wt-status.h"
18 #include "run-command.h"
19 #include "refs.h"
20 #include "log-tree.h"
21 #include "strbuf.h"
22 #include "utf8.h"
23 #include "parse-options.h"
24 #include "string-list.h"
25 #include "rerere.h"
26 #include "unpack-trees.h"
27 #include "quote.h"
29 static const char * const builtin_commit_usage[] = {
30 "git commit [options] [--] <filepattern>...",
31 NULL
34 static const char * const builtin_status_usage[] = {
35 "git status [options] [--] <filepattern>...",
36 NULL
39 static const char implicit_ident_advice[] =
40 "Your name and email address were configured automatically based\n"
41 "on your username and hostname. Please check that they are accurate.\n"
42 "You can suppress this message by setting them explicitly:\n"
43 "\n"
44 " git config --global user.name Your Name\n"
45 " git config --global user.email you@example.com\n"
46 "\n"
47 "If the identity used for this commit is wrong, you can fix it with:\n"
48 "\n"
49 " git commit --amend --author='Your Name <you@example.com>'\n";
51 static unsigned char head_sha1[20];
53 static char *use_message_buffer;
54 static const char commit_editmsg[] = "COMMIT_EDITMSG";
55 static struct lock_file index_lock; /* real index */
56 static struct lock_file false_lock; /* used only for partial commits */
57 static enum {
58 COMMIT_AS_IS = 1,
59 COMMIT_NORMAL,
60 COMMIT_PARTIAL,
61 } commit_style;
63 static const char *logfile, *force_author;
64 static const char *template_file;
65 static char *edit_message, *use_message;
66 static char *author_name, *author_email, *author_date;
67 static int all, edit_flag, also, interactive, only, amend, signoff;
68 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69 static 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.
77 static enum {
78 CLEANUP_SPACE,
79 CLEANUP_NONE,
80 CLEANUP_ALL,
81 } cleanup_mode;
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;
89 static enum {
90 STATUS_FORMAT_LONG,
91 STATUS_FORMAT_SHORT,
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;
98 if (unset)
99 strbuf_setlen(buf, 0);
100 else {
101 strbuf_addstr(buf, arg);
102 strbuf_addstr(buf, "\n\n");
104 return 0;
107 static struct option builtin_commit_options[] = {
108 OPT__QUIET(&quiet),
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 */
144 OPT_END()
147 static void rollback_index_files(void)
149 switch (commit_style) {
150 case COMMIT_AS_IS:
151 break; /* nothing to do */
152 case COMMIT_NORMAL:
153 rollback_lock_file(&index_lock);
154 break;
155 case COMMIT_PARTIAL:
156 rollback_lock_file(&index_lock);
157 rollback_lock_file(&false_lock);
158 break;
162 static int commit_index_files(void)
164 int err = 0;
166 switch (commit_style) {
167 case COMMIT_AS_IS:
168 break; /* nothing to do */
169 case COMMIT_NORMAL:
170 err = commit_lock_file(&index_lock);
171 break;
172 case COMMIT_PARTIAL:
173 err = commit_lock_file(&index_lock);
174 rollback_lock_file(&false_lock);
175 break;
178 return err;
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)
188 int i;
189 char *m;
191 for (i = 0; pattern[i]; i++)
193 m = xcalloc(1, i);
195 if (with_tree)
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)
203 continue;
204 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
205 continue;
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)
216 int i;
217 for (i = 0; i < list->nr; i++) {
218 struct stat st;
219 struct string_list_item *p = &(list->items[i]);
221 /* p->util is skip-worktree */
222 if (p->util)
223 continue;
225 if (!lstat(p->string, &st)) {
226 if (add_to_cache(p->string, &st, 0))
227 die("updating files failed");
228 } else
229 remove_file_from_cache(p->string);
233 static void create_base_index(void)
235 struct tree *tree;
236 struct unpack_trees_options opts;
237 struct tree_desc t;
239 if (initial_commit) {
240 discard_cache();
241 return;
244 memset(&opts, 0, sizeof(opts));
245 opts.head_idx = 1;
246 opts.index_only = 1;
247 opts.merge = 1;
248 opts.src_index = &the_index;
249 opts.dst_index = &the_index;
251 opts.fn = oneway_merge;
252 tree = parse_tree_indirect(head_sha1);
253 if (!tree)
254 die("failed to unpack HEAD tree object");
255 parse_tree(tree);
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)
273 int fd;
274 struct string_list partial;
275 const char **pathspec = NULL;
276 int refresh_flags = REFRESH_QUIET;
278 if (is_status)
279 refresh_flags |= REFRESH_UNMERGED;
280 if (interactive) {
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();
289 if (*argv)
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;
319 * As-is commit.
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();
338 * A partial commit.
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;
358 if (in_merge)
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))
364 exit(1);
366 discard_cache();
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()),
380 LOCK_DIE_ON_ERROR);
382 create_base_index();
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");
390 discard_cache();
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,
397 struct wt_status *s)
399 unsigned char sha1[20];
401 if (s->relative_paths)
402 s->prefix = prefix;
404 if (amend) {
405 s->amend = 1;
406 s->reference = "HEAD^1";
408 s->verbose = verbose;
409 s->index_file = index_file;
410 s->fp = fp;
411 s->nowarn = nowarn;
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);
419 break;
420 case STATUS_FORMAT_PORCELAIN:
421 wt_porcelain_print(s, null_termination);
422 break;
423 case STATUS_FORMAT_LONG:
424 wt_status_print(s);
425 break;
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 ");
453 if (!a)
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));
467 if (force_author) {
468 const char *lb = strstr(force_author, " <");
469 const char *rb = strchr(force_author, '>');
471 if (!lb || !rb)
472 die("malformed --author parameter");
473 name = xstrndup(force_author, lb - force_author);
474 email = xstrndup(lb + 2, rb - (lb + 2));
477 if (force_date)
478 date = force_date;
480 author_name = name;
481 author_email = email;
482 author_date = date;
485 static int ends_rfc2822_footer(struct strbuf *sb)
487 int ch;
488 int hit = 0;
489 int i, j, k;
490 int len = sb->len;
491 int first = 1;
492 const char *buf = sb->buf;
494 for (i = len - 1; i > 0; i--) {
495 if (hit && buf[i] == '\n')
496 break;
497 hit = (buf[i] == '\n');
500 while (i < len - 1 && buf[i] == '\n')
501 i++;
503 for (; i < len; i = k) {
504 for (k = i; k < len && buf[k] != '\n'; k++)
505 ; /* do nothing */
506 k++;
508 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
509 continue;
511 first = 0;
513 for (j = 0; i + j < len; j++) {
514 ch = buf[i + j];
515 if (ch == ':')
516 break;
517 if (isalnum(ch) ||
518 (ch == '-'))
519 continue;
520 return 0;
523 return 1;
526 static int prepare_to_commit(const char *index_file, const char *prefix,
527 struct wt_status *s)
529 struct stat statbuf;
530 int commitable, saved_color_setting;
531 struct strbuf sb = STRBUF_INIT;
532 char *buffer;
533 FILE *fp;
534 const char *hook_arg1 = NULL;
535 const char *hook_arg2 = NULL;
536 int ident_shown = 0;
538 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
539 return 0;
541 if (message.len) {
542 strbuf_addbuf(&sb, &message);
543 hook_arg1 = "message";
544 } else if (logfile && !strcmp(logfile, "-")) {
545 if (isatty(0))
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'",
553 logfile);
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");
565 hook_arg1 = "merge";
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.
580 else if (in_merge)
581 hook_arg1 = "merge";
583 fp = fopen(git_path(commit_editmsg), "w");
584 if (fp == NULL)
585 die_errno("could not open '%s'", git_path(commit_editmsg));
587 if (cleanup_mode != CLEANUP_NONE)
588 stripspace(&sb, 0);
590 if (signoff) {
591 struct strbuf sob = STRBUF_INIT;
592 int i;
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--)
599 ; /* do nothing */
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");
611 strbuf_release(&sb);
613 determine_author_info();
615 /* This checks if committer ident is explicitly given */
616 git_committer_info(0);
617 if (use_editor && include_status) {
618 char *author_ident;
619 const char *committer_ident;
621 if (in_merge)
622 fprintf(fp,
623 "#\n"
624 "# It looks like you may be committing a MERGE.\n"
625 "# If this is not correct, please remove the file\n"
626 "# %s\n"
627 "# and try again.\n"
628 "#\n",
629 git_path("MERGE_HEAD"));
631 fprintf(fp,
632 "\n"
633 "# Please enter the commit message for your changes.");
634 if (cleanup_mode == CLEANUP_ALL)
635 fprintf(fp,
636 " Lines starting\n"
637 "# with '#' will be ignored, and an empty"
638 " message aborts the commit.\n");
639 else /* CLEANUP_SPACE, that is. */
640 fprintf(fp,
641 " Lines starting\n"
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))
652 fprintf(fp,
653 "%s"
654 "# Author: %s\n",
655 ident_shown++ ? "" : "#\n",
656 author_ident);
657 free(author_ident);
659 if (!user_ident_sufficiently_given())
660 fprintf(fp,
661 "%s"
662 "# Committer: %s\n",
663 ident_shown++ ? "" : "#\n",
664 committer_ident);
666 if (ident_shown)
667 fprintf(fp, "#\n");
669 saved_color_setting = s->use_color;
670 s->use_color = 0;
671 commitable = run_status(fp, index_file, prefix, 1, s);
672 s->use_color = saved_color_setting;
673 } else {
674 unsigned char sha1[20];
675 const char *parent = "HEAD";
677 if (!active_nr && read_cache() < 0)
678 die("Cannot read index");
680 if (amend)
681 parent = "HEAD^1";
683 if (get_sha1(parent, sha1))
684 commitable = !!active_nr;
685 else
686 commitable = index_differs_from(parent, 0);
689 fclose(fp);
691 if (!commitable && !in_merge && !allow_empty &&
692 !(amend && is_a_merge(head_sha1))) {
693 run_status(stdout, index_file, prefix, 0, s);
694 return 0;
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.
702 discard_cache();
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");
709 return 0;
712 if (run_hook(index_file, "prepare-commit-msg",
713 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
714 return 0;
716 if (use_editor) {
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)) {
721 fprintf(stderr,
722 "Please supply the message using either -m or -F option.\n");
723 exit(1);
727 if (!no_verify &&
728 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
729 return 0;
732 return 1;
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;
742 const char *nl;
743 int eol, i, start = 0;
745 if (cleanup_mode == CLEANUP_NONE && sb->len)
746 return 0;
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)
753 start += tmpl.len;
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);
760 if (nl)
761 eol = nl - sb->buf;
762 else
763 eol = sb->len;
765 if (strlen(sign_off_header) <= eol - i &&
766 !prefixcmp(sb->buf + i, sign_off_header)) {
767 i = eol;
768 continue;
770 while (i < eol)
771 if (!isspace(sb->buf[i++]))
772 return 0;
775 return 1;
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;
783 const char *av[20];
784 int ac = 0;
786 init_revisions(&revs, NULL);
787 strbuf_addf(&buf, "--author=%s", name);
788 av[++ac] = "--all";
789 av[++ac] = "-i";
790 av[++ac] = buf.buf;
791 av[++ac] = NULL;
792 setup_revisions(ac, av, &revs, NULL);
793 prepare_revision_walk(&revs);
794 commit = get_revision(&revs);
795 if (commit) {
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;
816 else
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[],
822 const char *prefix,
823 struct wt_status *s)
825 int f = 0;
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)
837 use_editor = 0;
838 if (edit_flag)
839 use_editor = 1;
840 if (!use_editor)
841 setenv("GIT_EDITOR", ":", 1);
843 if (get_sha1("HEAD", head_sha1))
844 initial_commit = 1;
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.");
852 if (use_message)
853 f++;
854 if (edit_message)
855 f++;
856 if (logfile)
857 f++;
858 if (f > 1)
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.");
862 if (edit_message)
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.");
868 if (use_message) {
869 unsigned char sha1[20];
870 static char utf8[] = "UTF-8";
871 const char *out_enc;
872 char *enc, *end;
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");
882 if (enc) {
883 end = strchr(enc + 10, '\n');
884 enc = xstrndup(enc + 10, end - (enc + 10));
885 } else {
886 enc = utf8;
888 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
890 if (strcmp(out_enc, enc))
891 use_message_buffer =
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);
902 if (enc != utf8)
903 free(enc);
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;
922 else
923 die("Invalid cleanup mode %s", cleanup_arg);
925 handle_untracked_files_arg(s);
927 if (all && argc > 0)
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)
935 dry_run = 1;
937 return argc;
940 static int dry_run_commit(int argc, const char **argv, const char *prefix,
941 struct wt_status *s)
943 int commitable;
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;
968 return -1;
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")) {
976 int is_bool;
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;
980 return 0;
982 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
983 s->use_color = git_config_colorbool(k, v, -1);
984 return 0;
986 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
987 int slot = parse_status_slot(k, 13);
988 if (slot < 0)
989 return 0;
990 if (!v)
991 return config_error_nonbool(k);
992 color_parse(v, k, s->color_palette[slot]);
993 return 0;
995 if (!strcmp(k, "status.relativepaths")) {
996 s->relative_paths = git_config_bool(k, v);
997 return 0;
999 if (!strcmp(k, "status.showuntrackedfiles")) {
1000 if (!v)
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;
1008 else
1009 return error("Invalid untracked files mode '%s'", v);
1010 return 0;
1012 return git_diff_ui_config(k, v, NULL);
1015 int cmd_status(int argc, const char **argv, const char *prefix)
1017 struct wt_status s;
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,
1029 "mode",
1030 "show untracked files, optional modes: all, normal, no. (Default: all)",
1031 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1032 OPT_END(),
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);
1046 if (*argv)
1047 s.pathspec = get_pathspec(prefix, argv);
1049 read_cache();
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)
1056 s.prefix = prefix;
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);
1065 break;
1066 case STATUS_FORMAT_PORCELAIN:
1067 wt_porcelain_print(&s, null_termination);
1068 break;
1069 case STATUS_FORMAT_LONG:
1070 s.verbose = verbose;
1071 wt_status_print(&s);
1072 break;
1074 return 0;
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);
1089 if (!commit)
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);
1116 rev.abbrev = 0;
1117 rev.diff = 1;
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);
1130 printf("[%s%s ",
1131 !prefixcmp(head, "refs/heads/") ?
1132 head + 11 :
1133 !strcmp(head, "HEAD") ?
1134 "detached HEAD" :
1135 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);
1157 return 0;
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;
1167 char *nl, *p;
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;
1173 struct wt_status s;
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,
1183 prefix, &s);
1184 if (dry_run) {
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();
1195 return 1;
1198 /* Determine parents */
1199 if (initial_commit) {
1200 reflog_msg = "commit (initial)";
1201 } else if (amend) {
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;
1214 FILE *fp;
1216 reflog_msg = "commit (merge)";
1217 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1218 fp = fopen(git_path("MERGE_HEAD"), "r");
1219 if (fp == NULL)
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;
1228 fclose(fp);
1229 strbuf_release(&m);
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);
1238 } else {
1239 reflog_msg = "commit";
1240 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1243 /* Finally, get the commit message */
1244 strbuf_reset(&sb);
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. */
1252 if (verbose) {
1253 p = strstr(sb.buf, "\ndiff --git ");
1254 if (p != NULL)
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");
1263 exit(1);
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');
1278 if (nl)
1279 strbuf_setlen(&sb, nl + 1 - sb.buf);
1280 else
1281 strbuf_addch(&sb, '\n');
1282 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1283 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1285 if (!ref_lock) {
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.");
1304 rerere(0);
1305 run_hook(get_index_file(), "post-commit", NULL);
1306 if (!quiet)
1307 print_summary(prefix, commit_sha1);
1309 return 0;