1 /*
2 * Builtin "git commit"
3 *
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
32 };
34 static const char * const builtin_status_usage[] = {
35 "git status [options] [--] <filepattern>...",
36 NULL
37 };
39 static const char implicit_ident_advice[] =
40 "Your name and email address were configured automatically based\n"
41 "on your username and hostname. Please check that they are accurate.\n"
42 "You can suppress this message by setting them explicitly:\n"
43 "\n"
44 " git config --global user.name \"Your Name\"\n"
45 " git config --global user.email you@example.com\n"
46 "\n"
47 "If the identity used for this commit is wrong, you can fix it with:\n"
48 "\n"
49 " git commit --amend --author='Your Name <you@example.com>'\n";
51 static unsigned char head_sha1[20];
53 static char *use_message_buffer;
54 static const char commit_editmsg[] = "COMMIT_EDITMSG";
55 static struct lock_file index_lock; /* real index */
56 static struct lock_file false_lock; /* used only for partial commits */
57 static enum {
58 COMMIT_AS_IS = 1,
59 COMMIT_NORMAL,
60 COMMIT_PARTIAL
61 } commit_style;
63 static const char *logfile, *force_author;
64 static const char *template_file;
65 static char *edit_message, *use_message;
66 static char *author_name, *author_email, *author_date;
67 static int all, edit_flag, also, interactive, only, amend, signoff;
68 static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
69 static int no_post_rewrite;
70 static char *untracked_files_arg, *force_date;
71 /*
72 * The default commit message cleanup mode will remove the lines
73 * beginning with # (shell comments) and leading and trailing
74 * whitespaces (empty lines or containing only whitespaces)
75 * if editor is used, and only the whitespaces if the message
76 * is specified explicitly.
77 */
78 static enum {
79 CLEANUP_SPACE,
80 CLEANUP_NONE,
81 CLEANUP_ALL
82 } cleanup_mode;
83 static char *cleanup_arg;
85 static int use_editor = 1, initial_commit, in_merge, include_status = 1;
86 static const char *only_include_assumed;
87 static struct strbuf message;
89 static int null_termination;
90 static enum {
91 STATUS_FORMAT_LONG,
92 STATUS_FORMAT_SHORT,
93 STATUS_FORMAT_PORCELAIN
94 } status_format = STATUS_FORMAT_LONG;
96 static int opt_parse_m(const struct option *opt, const char *arg, int unset)
97 {
98 struct strbuf *buf = opt->value;
99 if (unset)
100 strbuf_setlen(buf, 0);
101 else {
102 strbuf_addstr(buf, arg);
103 strbuf_addstr(buf, "\n\n");
104 }
105 return 0;
106 }
108 static struct option builtin_commit_options[] = {
109 OPT__QUIET(&quiet),
110 OPT__VERBOSE(&verbose),
112 OPT_GROUP("Commit message options"),
113 OPT_FILENAME('F', "file", &logfile, "read log from file"),
114 OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"),
115 OPT_STRING(0, "date", &force_date, "DATE", "override date for commit"),
116 OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m),
117 OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit"),
118 OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
119 OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
120 OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
121 OPT_FILENAME('t', "template", &template_file, "use specified template file"),
122 OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
123 OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
124 OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
125 /* end commit message options */
127 OPT_GROUP("Commit contents options"),
128 OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
129 OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
130 OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
131 OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
132 OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
133 OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
134 OPT_SET_INT(0, "short", &status_format, "show status concisely",
135 STATUS_FORMAT_SHORT),
136 OPT_SET_INT(0, "porcelain", &status_format,
137 "show porcelain output format", STATUS_FORMAT_PORCELAIN),
138 OPT_BOOLEAN('z', "null", &null_termination,
139 "terminate entries with NUL"),
140 OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
141 OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
142 { 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" },
143 OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
144 /* end commit contents options */
146 OPT_END()
147 };
149 static void rollback_index_files(void)
150 {
151 switch (commit_style) {
152 case COMMIT_AS_IS:
153 break; /* nothing to do */
154 case COMMIT_NORMAL:
155 rollback_lock_file(&index_lock);
156 break;
157 case COMMIT_PARTIAL:
158 rollback_lock_file(&index_lock);
159 rollback_lock_file(&false_lock);
160 break;
161 }
162 }
164 static int commit_index_files(void)
165 {
166 int err = 0;
168 switch (commit_style) {
169 case COMMIT_AS_IS:
170 break; /* nothing to do */
171 case COMMIT_NORMAL:
172 err = commit_lock_file(&index_lock);
173 break;
174 case COMMIT_PARTIAL:
175 err = commit_lock_file(&index_lock);
176 rollback_lock_file(&false_lock);
177 break;
178 }
180 return err;
181 }
183 /*
184 * Take a union of paths in the index and the named tree (typically, "HEAD"),
185 * and return the paths that match the given pattern in list.
186 */
187 static int list_paths(struct string_list *list, const char *with_tree,
188 const char *prefix, const char **pattern)
189 {
190 int i;
191 char *m;
193 for (i = 0; pattern[i]; i++)
194 ;
195 m = xcalloc(1, i);
197 if (with_tree)
198 overlay_tree_on_cache(with_tree, prefix);
200 for (i = 0; i < active_nr; i++) {
201 struct cache_entry *ce = active_cache[i];
202 struct string_list_item *item;
204 if (ce->ce_flags & CE_UPDATE)
205 continue;
206 if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
207 continue;
208 item = string_list_insert(ce->name, list);
209 if (ce_skip_worktree(ce))
210 item->util = item; /* better a valid pointer than a fake one */
211 }
213 return report_path_error(m, pattern, prefix ? strlen(prefix) : 0);
214 }
216 static void add_remove_files(struct string_list *list)
217 {
218 int i;
219 for (i = 0; i < list->nr; i++) {
220 struct stat st;
221 struct string_list_item *p = &(list->items[i]);
223 /* p->util is skip-worktree */
224 if (p->util)
225 continue;
227 if (!lstat(p->string, &st)) {
228 if (add_to_cache(p->string, &st, 0))
229 die("updating files failed");
230 } else
231 remove_file_from_cache(p->string);
232 }
233 }
235 static void create_base_index(void)
236 {
237 struct tree *tree;
238 struct unpack_trees_options opts;
239 struct tree_desc t;
241 if (initial_commit) {
242 discard_cache();
243 return;
244 }
246 memset(&opts, 0, sizeof(opts));
247 opts.head_idx = 1;
248 opts.index_only = 1;
249 opts.merge = 1;
250 opts.src_index = &the_index;
251 opts.dst_index = &the_index;
253 opts.fn = oneway_merge;
254 tree = parse_tree_indirect(head_sha1);
255 if (!tree)
256 die("failed to unpack HEAD tree object");
257 parse_tree(tree);
258 init_tree_desc(&t, tree->buffer, tree->size);
259 if (unpack_trees(1, &t, &opts))
260 exit(128); /* We've already reported the error, finish dying */
261 }
263 static void refresh_cache_or_die(int refresh_flags)
264 {
265 /*
266 * refresh_flags contains REFRESH_QUIET, so the only errors
267 * are for unmerged entries.
268 */
269 if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN))
270 die_resolve_conflict("commit");
271 }
273 static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
274 {
275 int fd;
276 struct string_list partial;
277 const char **pathspec = NULL;
278 int refresh_flags = REFRESH_QUIET;
280 if (is_status)
281 refresh_flags |= REFRESH_UNMERGED;
282 if (interactive) {
283 if (interactive_add(argc, argv, prefix) != 0)
284 die("interactive add failed");
285 if (read_cache_preload(NULL) < 0)
286 die("index file corrupt");
287 commit_style = COMMIT_AS_IS;
288 return get_index_file();
289 }
291 if (*argv)
292 pathspec = get_pathspec(prefix, argv);
294 if (read_cache_preload(pathspec) < 0)
295 die("index file corrupt");
297 /*
298 * Non partial, non as-is commit.
299 *
300 * (1) get the real index;
301 * (2) update the_index as necessary;
302 * (3) write the_index out to the real index (still locked);
303 * (4) return the name of the locked index file.
304 *
305 * The caller should run hooks on the locked real index, and
306 * (A) if all goes well, commit the real index;
307 * (B) on failure, rollback the real index.
308 */
309 if (all || (also && pathspec && *pathspec)) {
310 fd = hold_locked_index(&index_lock, 1);
311 add_files_to_cache(also ? prefix : NULL, pathspec, 0);
312 refresh_cache_or_die(refresh_flags);
313 if (write_cache(fd, active_cache, active_nr) ||
314 close_lock_file(&index_lock))
315 die("unable to write new_index file");
316 commit_style = COMMIT_NORMAL;
317 return index_lock.filename;
318 }
320 /*
321 * As-is commit.
322 *
323 * (1) return the name of the real index file.
324 *
325 * The caller should run hooks on the real index,
326 * and create commit from the_index.
327 * We still need to refresh the index here.
328 */
329 if (!pathspec || !*pathspec) {
330 fd = hold_locked_index(&index_lock, 1);
331 refresh_cache_or_die(refresh_flags);
332 if (write_cache(fd, active_cache, active_nr) ||
333 commit_locked_index(&index_lock))
334 die("unable to write new_index file");
335 commit_style = COMMIT_AS_IS;
336 return get_index_file();
337 }
339 /*
340 * A partial commit.
341 *
342 * (0) find the set of affected paths;
343 * (1) get lock on the real index file;
344 * (2) update the_index with the given paths;
345 * (3) write the_index out to the real index (still locked);
346 * (4) get lock on the false index file;
347 * (5) reset the_index from HEAD;
348 * (6) update the_index the same way as (2);
349 * (7) write the_index out to the false index file;
350 * (8) return the name of the false index file (still locked);
351 *
352 * The caller should run hooks on the locked false index, and
353 * create commit from it. Then
354 * (A) if all goes well, commit the real index;
355 * (B) on failure, rollback the real index;
356 * In either case, rollback the false index.
357 */
358 commit_style = COMMIT_PARTIAL;
360 if (in_merge)
361 die("cannot do a partial commit during a merge.");
363 memset(&partial, 0, sizeof(partial));
364 partial.strdup_strings = 1;
365 if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec))
366 exit(1);
368 discard_cache();
369 if (read_cache() < 0)
370 die("cannot read the index");
372 fd = hold_locked_index(&index_lock, 1);
373 add_remove_files(&partial);
374 refresh_cache(REFRESH_QUIET);
375 if (write_cache(fd, active_cache, active_nr) ||
376 close_lock_file(&index_lock))
377 die("unable to write new_index file");
379 fd = hold_lock_file_for_update(&false_lock,
380 git_path("next-index-%"PRIuMAX,
381 (uintmax_t) getpid()),
382 LOCK_DIE_ON_ERROR);
384 create_base_index();
385 add_remove_files(&partial);
386 refresh_cache(REFRESH_QUIET);
388 if (write_cache(fd, active_cache, active_nr) ||
389 close_lock_file(&false_lock))
390 die("unable to write temporary index file");
392 discard_cache();
393 read_cache_from(false_lock.filename);
395 return false_lock.filename;
396 }
398 static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
399 struct wt_status *s)
400 {
401 unsigned char sha1[20];
403 if (s->relative_paths)
404 s->prefix = prefix;
406 if (amend) {
407 s->amend = 1;
408 s->reference = "HEAD^1";
409 }
410 s->verbose = verbose;
411 s->index_file = index_file;
412 s->fp = fp;
413 s->nowarn = nowarn;
414 s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
416 wt_status_collect(s);
418 switch (status_format) {
419 case STATUS_FORMAT_SHORT:
420 wt_shortstatus_print(s, null_termination);
421 break;
422 case STATUS_FORMAT_PORCELAIN:
423 wt_porcelain_print(s, null_termination);
424 break;
425 case STATUS_FORMAT_LONG:
426 wt_status_print(s);
427 break;
428 }
430 return s->commitable;
431 }
433 static int is_a_merge(const unsigned char *sha1)
434 {
435 struct commit *commit = lookup_commit(sha1);
436 if (!commit || parse_commit(commit))
437 die("could not parse HEAD commit");
438 return !!(commit->parents && commit->parents->next);
439 }
441 static const char sign_off_header[] = "Signed-off-by: ";
443 static void determine_author_info(void)
444 {
445 char *name, *email, *date;
447 name = getenv("GIT_AUTHOR_NAME");
448 email = getenv("GIT_AUTHOR_EMAIL");
449 date = getenv("GIT_AUTHOR_DATE");
451 if (use_message && !renew_authorship) {
452 const char *a, *lb, *rb, *eol;
454 a = strstr(use_message_buffer, "\nauthor ");
455 if (!a)
456 die("invalid commit: %s", use_message);
458 lb = strstr(a + 8, " <");
459 rb = strstr(a + 8, "> ");
460 eol = strchr(a + 8, '\n');
461 if (!lb || !rb || !eol)
462 die("invalid commit: %s", use_message);
464 name = xstrndup(a + 8, lb - (a + 8));
465 email = xstrndup(lb + 2, rb - (lb + 2));
466 date = xstrndup(rb + 2, eol - (rb + 2));
467 }
469 if (force_author) {
470 const char *lb = strstr(force_author, " <");
471 const char *rb = strchr(force_author, '>');
473 if (!lb || !rb)
474 die("malformed --author parameter");
475 name = xstrndup(force_author, lb - force_author);
476 email = xstrndup(lb + 2, rb - (lb + 2));
477 }
479 if (force_date)
480 date = force_date;
482 author_name = name;
483 author_email = email;
484 author_date = date;
485 }
487 static int ends_rfc2822_footer(struct strbuf *sb)
488 {
489 int ch;
490 int hit = 0;
491 int i, j, k;
492 int len = sb->len;
493 int first = 1;
494 const char *buf = sb->buf;
496 for (i = len - 1; i > 0; i--) {
497 if (hit && buf[i] == '\n')
498 break;
499 hit = (buf[i] == '\n');
500 }
502 while (i < len - 1 && buf[i] == '\n')
503 i++;
505 for (; i < len; i = k) {
506 for (k = i; k < len && buf[k] != '\n'; k++)
507 ; /* do nothing */
508 k++;
510 if ((buf[k] == ' ' || buf[k] == '\t') && !first)
511 continue;
513 first = 0;
515 for (j = 0; i + j < len; j++) {
516 ch = buf[i + j];
517 if (ch == ':')
518 break;
519 if (isalnum(ch) ||
520 (ch == '-'))
521 continue;
522 return 0;
523 }
524 }
525 return 1;
526 }
528 static int prepare_to_commit(const char *index_file, const char *prefix,
529 struct wt_status *s)
530 {
531 struct stat statbuf;
532 int commitable, saved_color_setting;
533 struct strbuf sb = STRBUF_INIT;
534 char *buffer;
535 FILE *fp;
536 const char *hook_arg1 = NULL;
537 const char *hook_arg2 = NULL;
538 int ident_shown = 0;
540 if (!no_verify && run_hook(index_file, "pre-commit", NULL))
541 return 0;
543 if (message.len) {
544 strbuf_addbuf(&sb, &message);
545 hook_arg1 = "message";
546 } else if (logfile && !strcmp(logfile, "-")) {
547 if (isatty(0))
548 fprintf(stderr, "(reading log message from standard input)\n");
549 if (strbuf_read(&sb, 0, 0) < 0)
550 die_errno("could not read log from standard input");
551 hook_arg1 = "message";
552 } else if (logfile) {
553 if (strbuf_read_file(&sb, logfile, 0) < 0)
554 die_errno("could not read log file '%s'",
555 logfile);
556 hook_arg1 = "message";
557 } else if (use_message) {
558 buffer = strstr(use_message_buffer, "\n\n");
559 if (!buffer || buffer[2] == '\0')
560 die("commit has empty message");
561 strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
562 hook_arg1 = "commit";
563 hook_arg2 = use_message;
564 } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
565 if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
566 die_errno("could not read MERGE_MSG");
567 hook_arg1 = "merge";
568 } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
569 if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
570 die_errno("could not read SQUASH_MSG");
571 hook_arg1 = "squash";
572 } else if (template_file && !stat(template_file, &statbuf)) {
573 if (strbuf_read_file(&sb, template_file, 0) < 0)
574 die_errno("could not read '%s'", template_file);
575 hook_arg1 = "template";
576 }
578 /*
579 * This final case does not modify the template message,
580 * it just sets the argument to the prepare-commit-msg hook.
581 */
582 else if (in_merge)
583 hook_arg1 = "merge";
585 fp = fopen(git_path(commit_editmsg), "w");
586 if (fp == NULL)
587 die_errno("could not open '%s'", git_path(commit_editmsg));
589 if (cleanup_mode != CLEANUP_NONE)
590 stripspace(&sb, 0);
592 if (signoff) {
593 struct strbuf sob = STRBUF_INIT;
594 int i;
596 strbuf_addstr(&sob, sign_off_header);
597 strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
598 getenv("GIT_COMMITTER_EMAIL")));
599 strbuf_addch(&sob, '\n');
600 for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--)
601 ; /* do nothing */
602 if (prefixcmp(sb.buf + i, sob.buf)) {
603 if (!i || !ends_rfc2822_footer(&sb))
604 strbuf_addch(&sb, '\n');
605 strbuf_addbuf(&sb, &sob);
606 }
607 strbuf_release(&sob);
608 }
610 if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
611 die_errno("could not write commit template");
613 strbuf_release(&sb);
615 determine_author_info();
617 /* This checks if committer ident is explicitly given */
618 git_committer_info(0);
619 if (use_editor && include_status) {
620 char *author_ident;
621 const char *committer_ident;
623 if (in_merge)
624 fprintf(fp,
625 "#\n"
626 "# It looks like you may be committing a MERGE.\n"
627 "# If this is not correct, please remove the file\n"
628 "# %s\n"
629 "# and try again.\n"
630 "#\n",
631 git_path("MERGE_HEAD"));
633 fprintf(fp,
634 "\n"
635 "# Please enter the commit message for your changes.");
636 if (cleanup_mode == CLEANUP_ALL)
637 fprintf(fp,
638 " Lines starting\n"
639 "# with '#' will be ignored, and an empty"
640 " message aborts the commit.\n");
641 else /* CLEANUP_SPACE, that is. */
642 fprintf(fp,
643 " Lines starting\n"
644 "# with '#' will be kept; you may remove them"
645 " yourself if you want to.\n"
646 "# An empty message aborts the commit.\n");
647 if (only_include_assumed)
648 fprintf(fp, "# %s\n", only_include_assumed);
650 author_ident = xstrdup(fmt_name(author_name, author_email));
651 committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
652 getenv("GIT_COMMITTER_EMAIL"));
653 if (strcmp(author_ident, committer_ident))
654 fprintf(fp,
655 "%s"
656 "# Author: %s\n",
657 ident_shown++ ? "" : "#\n",
658 author_ident);
659 free(author_ident);
661 if (!user_ident_sufficiently_given())
662 fprintf(fp,
663 "%s"
664 "# Committer: %s\n",
665 ident_shown++ ? "" : "#\n",
666 committer_ident);
668 if (ident_shown)
669 fprintf(fp, "#\n");
671 saved_color_setting = s->use_color;
672 s->use_color = 0;
673 commitable = run_status(fp, index_file, prefix, 1, s);
674 s->use_color = saved_color_setting;
675 } else {
676 unsigned char sha1[20];
677 const char *parent = "HEAD";
679 if (!active_nr && read_cache() < 0)
680 die("Cannot read index");
682 if (amend)
683 parent = "HEAD^1";
685 if (get_sha1(parent, sha1))
686 commitable = !!active_nr;
687 else
688 commitable = index_differs_from(parent, 0);
689 }
691 fclose(fp);
693 if (!commitable && !in_merge && !allow_empty &&
694 !(amend && is_a_merge(head_sha1))) {
695 run_status(stdout, index_file, prefix, 0, s);
696 return 0;
697 }
699 /*
700 * Re-read the index as pre-commit hook could have updated it,
701 * and write it out as a tree. We must do this before we invoke
702 * the editor and after we invoke run_status above.
703 */
704 discard_cache();
705 read_cache_from(index_file);
706 if (!active_cache_tree)
707 active_cache_tree = cache_tree();
708 if (cache_tree_update(active_cache_tree,
709 active_cache, active_nr, 0, 0) < 0) {
710 error("Error building trees");
711 return 0;
712 }
714 if (run_hook(index_file, "prepare-commit-msg",
715 git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
716 return 0;
718 if (use_editor) {
719 char index[PATH_MAX];
720 const char *env[2] = { NULL };
721 env[0] = index;
722 snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
723 if (launch_editor(git_path(commit_editmsg), NULL, env)) {
724 fprintf(stderr,
725 "Please supply the message using either -m or -F option.\n");
726 exit(1);
727 }
728 }
730 if (!no_verify &&
731 run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
732 return 0;
733 }
735 return 1;
736 }
738 /*
739 * Find out if the message in the strbuf contains only whitespace and
740 * Signed-off-by lines.
741 */
742 static int message_is_empty(struct strbuf *sb)
743 {
744 struct strbuf tmpl = STRBUF_INIT;
745 const char *nl;
746 int eol, i, start = 0;
748 if (cleanup_mode == CLEANUP_NONE && sb->len)
749 return 0;
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)
756 start += tmpl.len;
757 }
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);
763 if (nl)
764 eol = nl - sb->buf;
765 else
766 eol = sb->len;
768 if (strlen(sign_off_header) <= eol - i &&
769 !prefixcmp(sb->buf + i, sign_off_header)) {
770 i = eol;
771 continue;
772 }
773 while (i < eol)
774 if (!isspace(sb->buf[i++]))
775 return 0;
776 }
778 return 1;
779 }
781 static const char *find_author_by_nickname(const char *name)
782 {
783 struct rev_info revs;
784 struct commit *commit;
785 struct strbuf buf = STRBUF_INIT;
786 const char *av[20];
787 int ac = 0;
789 init_revisions(&revs, NULL);
790 strbuf_addf(&buf, "--author=%s", name);
791 av[++ac] = "--all";
792 av[++ac] = "-i";
793 av[++ac] = buf.buf;
794 av[++ac] = NULL;
795 setup_revisions(ac, av, &revs, NULL);
796 prepare_revision_walk(&revs);
797 commit = get_revision(&revs);
798 if (commit) {
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);
804 }
805 die("No existing author found with '%s'", name);
806 }
809 static void handle_untracked_files_arg(struct wt_status *s)
810 {
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;
819 else
820 die("Invalid untracked files mode '%s'", untracked_files_arg);
821 }
823 static int parse_and_validate_options(int argc, const char *argv[],
824 const char * const usage[],
825 const char *prefix,
826 struct wt_status *s)
827 {
828 int f = 0;
830 argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
831 0);
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)
840 use_editor = 0;
841 if (edit_flag)
842 use_editor = 1;
843 if (!use_editor)
844 setenv("GIT_EDITOR", ":", 1);
846 if (get_sha1("HEAD", head_sha1))
847 initial_commit = 1;
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.");
855 if (use_message)
856 f++;
857 if (edit_message)
858 f++;
859 if (logfile)
860 f++;
861 if (f > 1)
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.");
865 if (edit_message)
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.");
871 if (use_message) {
872 unsigned char sha1[20];
873 static char utf8[] = "UTF-8";
874 const char *out_enc;
875 char *enc, *end;
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");
885 if (enc) {
886 end = strchr(enc + 10, '\n');
887 enc = xstrndup(enc + 10, end - (enc + 10));
888 } else {
889 enc = utf8;
890 }
891 out_enc = git_commit_encoding ? git_commit_encoding : utf8;
893 if (strcmp(out_enc, enc))
894 use_message_buffer =
895 reencode_string(commit->buffer, out_enc, enc);
897 /*
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.
902 */
903 if (use_message_buffer == NULL)
904 use_message_buffer = xstrdup(commit->buffer);
905 if (enc != utf8)
906 free(enc);
907 }
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;
925 else
926 die("Invalid cleanup mode %s", cleanup_arg);
928 handle_untracked_files_arg(s);
930 if (all && argc > 0)
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)
938 dry_run = 1;
940 return argc;
941 }
943 static int dry_run_commit(int argc, const char **argv, const char *prefix,
944 struct wt_status *s)
945 {
946 int commitable;
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;
954 }
956 static int parse_status_slot(const char *var, int offset)
957 {
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;
971 return -1;
972 }
974 static int git_status_config(const char *k, const char *v, void *cb)
975 {
976 struct wt_status *s = cb;
978 if (!strcmp(k, "status.submodulesummary")) {
979 int is_bool;
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;
983 return 0;
984 }
985 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
986 s->use_color = git_config_colorbool(k, v, -1);
987 return 0;
988 }
989 if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
990 int slot = parse_status_slot(k, 13);
991 if (slot < 0)
992 return 0;
993 if (!v)
994 return config_error_nonbool(k);
995 color_parse(v, k, s->color_palette[slot]);
996 return 0;
997 }
998 if (!strcmp(k, "status.relativepaths")) {
999 s->relative_paths = git_config_bool(k, v);
1000 return 0;
1001 }
1002 if (!strcmp(k, "status.showuntrackedfiles")) {
1003 if (!v)
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;
1011 else
1012 return error("Invalid untracked files mode '%s'", v);
1013 return 0;
1014 }
1015 return git_diff_ui_config(k, v, NULL);
1016 }
1018 int cmd_status(int argc, const char **argv, const char *prefix)
1019 {
1020 struct wt_status s;
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,
1032 "mode",
1033 "show untracked files, optional modes: all, normal, no. (Default: all)",
1034 PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1035 OPT_END(),
1036 };
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);
1049 if (*argv)
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)
1059 s.prefix = prefix;
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);
1068 break;
1069 case STATUS_FORMAT_PORCELAIN:
1070 wt_porcelain_print(&s, null_termination);
1071 break;
1072 case STATUS_FORMAT_LONG:
1073 s.verbose = verbose;
1074 wt_status_print(&s);
1075 break;
1076 }
1077 return 0;
1078 }
1080 static void print_summary(const char *prefix, const unsigned char *sha1)
1081 {
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);
1092 if (!commit)
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);
1104 }
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);
1111 }
1112 }
1113 strbuf_release(&author_ident);
1114 strbuf_release(&committer_ident);
1116 init_revisions(&rev, prefix);
1117 setup_revisions(0, NULL, &rev, NULL);
1119 rev.abbrev = 0;
1120 rev.diff = 1;
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);
1133 printf("[%s%s ",
1134 !prefixcmp(head, "refs/heads/") ?
1135 head + 11 :
1136 !strcmp(head, "HEAD") ?
1137 "detached HEAD" :
1138 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);
1148 }
1149 strbuf_release(&format);
1150 }
1152 static int git_commit_config(const char *k, const char *v, void *cb)
1153 {
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);
1160 return 0;
1161 }
1163 return git_status_config(k, v, s);
1164 }
1166 static const char post_rewrite_hook[] = "hooks/post-rewrite";
1168 static int run_rewrite_hook(const unsigned char *oldsha1,
1169 const unsigned char *newsha1)
1170 {
1171 /* oldsha1 SP newsha1 LF NUL */
1172 static char buf[2*40 + 3];
1173 struct child_process proc;
1174 const char *argv[3];
1175 int code;
1176 size_t n;
1178 if (access(git_path(post_rewrite_hook), X_OK) < 0)
1179 return 0;
1181 argv[0] = git_path(post_rewrite_hook);
1182 argv[1] = "amend";
1183 argv[2] = NULL;
1185 memset(&proc, 0, sizeof(proc));
1186 proc.argv = argv;
1187 proc.in = -1;
1188 proc.stdout_to_stderr = 1;
1190 code = start_command(&proc);
1191 if (code)
1192 return code;
1193 n = snprintf(buf, sizeof(buf), "%s %s\n",
1194 sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
1195 write_in_full(proc.in, buf, n);
1196 close(proc.in);
1197 return finish_command(&proc);
1198 }
1200 int cmd_commit(int argc, const char **argv, const char *prefix)
1201 {
1202 struct strbuf sb = STRBUF_INIT;
1203 const char *index_file, *reflog_msg;
1204 char *nl, *p;
1205 unsigned char commit_sha1[20];
1206 struct ref_lock *ref_lock;
1207 struct commit_list *parents = NULL, **pptr = &parents;
1208 struct stat statbuf;
1209 int allow_fast_forward = 1;
1210 struct wt_status s;
1212 wt_status_prepare(&s);
1213 git_config(git_commit_config, &s);
1214 in_merge = file_exists(git_path("MERGE_HEAD"));
1215 s.in_merge = in_merge;
1217 if (s.use_color == -1)
1218 s.use_color = git_use_color_default;
1219 argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1220 prefix, &s);
1221 if (dry_run) {
1222 if (diff_use_color_default == -1)
1223 diff_use_color_default = git_use_color_default;
1224 return dry_run_commit(argc, argv, prefix, &s);
1225 }
1226 index_file = prepare_index(argc, argv, prefix, 0);
1228 /* Set up everything for writing the commit object. This includes
1229 running hooks, writing the trees, and interacting with the user. */
1230 if (!prepare_to_commit(index_file, prefix, &s)) {
1231 rollback_index_files();
1232 return 1;
1233 }
1235 /* Determine parents */
1236 if (initial_commit) {
1237 reflog_msg = "commit (initial)";
1238 } else if (amend) {
1239 struct commit_list *c;
1240 struct commit *commit;
1242 reflog_msg = "commit (amend)";
1243 commit = lookup_commit(head_sha1);
1244 if (!commit || parse_commit(commit))
1245 die("could not parse HEAD commit");
1247 for (c = commit->parents; c; c = c->next)
1248 pptr = &commit_list_insert(c->item, pptr)->next;
1249 } else if (in_merge) {
1250 struct strbuf m = STRBUF_INIT;
1251 FILE *fp;
1253 reflog_msg = "commit (merge)";
1254 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1255 fp = fopen(git_path("MERGE_HEAD"), "r");
1256 if (fp == NULL)
1257 die_errno("could not open '%s' for reading",
1258 git_path("MERGE_HEAD"));
1259 while (strbuf_getline(&m, fp, '\n') != EOF) {
1260 unsigned char sha1[20];
1261 if (get_sha1_hex(m.buf, sha1) < 0)
1262 die("Corrupt MERGE_HEAD file (%s)", m.buf);
1263 pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1264 }
1265 fclose(fp);
1266 strbuf_release(&m);
1267 if (!stat(git_path("MERGE_MODE"), &statbuf)) {
1268 if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
1269 die_errno("could not read MERGE_MODE");
1270 if (!strcmp(sb.buf, "no-ff"))
1271 allow_fast_forward = 0;
1272 }
1273 if (allow_fast_forward)
1274 parents = reduce_heads(parents);
1275 } else {
1276 reflog_msg = "commit";
1277 pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
1278 }
1280 /* Finally, get the commit message */
1281 strbuf_reset(&sb);
1282 if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
1283 int saved_errno = errno;
1284 rollback_index_files();
1285 die("could not read commit message: %s", strerror(saved_errno));
1286 }
1288 /* Truncate the message just before the diff, if any. */
1289 if (verbose) {
1290 p = strstr(sb.buf, "\ndiff --git ");
1291 if (p != NULL)
1292 strbuf_setlen(&sb, p - sb.buf + 1);
1293 }
1295 if (cleanup_mode != CLEANUP_NONE)
1296 stripspace(&sb, cleanup_mode == CLEANUP_ALL);
1297 if (message_is_empty(&sb)) {
1298 rollback_index_files();
1299 fprintf(stderr, "Aborting commit due to empty commit message.\n");
1300 exit(1);
1301 }
1303 if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
1304 fmt_ident(author_name, author_email, author_date,
1305 IDENT_ERROR_ON_NO_NAME))) {
1306 rollback_index_files();
1307 die("failed to write commit object");
1308 }
1310 ref_lock = lock_any_ref_for_update("HEAD",
1311 initial_commit ? NULL : head_sha1,
1312 0);
1314 nl = strchr(sb.buf, '\n');
1315 if (nl)
1316 strbuf_setlen(&sb, nl + 1 - sb.buf);
1317 else
1318 strbuf_addch(&sb, '\n');
1319 strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg));
1320 strbuf_insert(&sb, strlen(reflog_msg), ": ", 2);
1322 if (!ref_lock) {
1323 rollback_index_files();
1324 die("cannot lock HEAD ref");
1325 }
1326 if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
1327 rollback_index_files();
1328 die("cannot update HEAD ref");
1329 }
1331 unlink(git_path("MERGE_HEAD"));
1332 unlink(git_path("MERGE_MSG"));
1333 unlink(git_path("MERGE_MODE"));
1334 unlink(git_path("SQUASH_MSG"));
1336 if (commit_index_files())
1337 die ("Repository has been updated, but unable to write\n"
1338 "new_index file. Check that disk is not full or quota is\n"
1339 "not exceeded, and then \"git reset HEAD\" to recover.");
1341 rerere(0);
1342 run_hook(get_index_file(), "post-commit", NULL);
1343 if (amend && !no_post_rewrite) {
1344 struct notes_rewrite_cfg *cfg;
1345 cfg = init_copy_notes_for_rewrite("amend");
1346 if (cfg) {
1347 copy_note_for_rewrite(cfg, head_sha1, commit_sha1);
1348 finish_copy_notes_for_rewrite(cfg);
1349 }
1350 run_rewrite_hook(head_sha1, commit_sha1);
1351 }
1352 if (!quiet)
1353 print_summary(prefix, commit_sha1);
1355 return 0;
1356 }