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