Merge branch 'jk/commit-C-pick-empty' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:46:54 +0000 (11:46 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 25 Jun 2014 18:46:54 +0000 (11:46 -0700)
"git commit --allow-empty-message -C $commit" did not work when the
commit did not have any log message.

* jk/commit-C-pick-empty:
commit: do not complain of empty messages from -C

1  2 
builtin/commit.c
diff --combined builtin/commit.c
index 9cfef6c6cca61973a4982763e4b834bf1b45cb75,aa04507174765a230ff56626cffb5d0a7e66c4a7..65c069d2cbdd7f34b9ebf7add06e65de17df8efa
@@@ -113,7 -113,6 +113,7 @@@ static char *sign_commit
  static enum {
        CLEANUP_SPACE,
        CLEANUP_NONE,
 +      CLEANUP_SCISSORS,
        CLEANUP_ALL
  } cleanup_mode;
  static const char *cleanup_arg;
@@@ -235,7 -234,7 +235,7 @@@ static int list_paths(struct string_lis
  
                if (ce->ce_flags & CE_UPDATE)
                        continue;
 -              if (!match_pathspec_depth(pattern, ce->name, ce_namelen(ce), 0, m))
 +              if (!ce_path_match(ce, pattern, m))
                        continue;
                item = string_list_insert(list, ce->name);
                if (ce_skip_worktree(ce))
@@@ -308,6 -307,7 +308,6 @@@ static char *prepare_index(int argc, co
        int fd;
        struct string_list partial;
        struct pathspec pathspec;
 -      char *old_index_env = NULL;
        int refresh_flags = REFRESH_QUIET;
  
        if (is_status)
                die(_("index file corrupt"));
  
        if (interactive) {
 +              char *old_index_env = NULL;
                fd = hold_locked_index(&index_lock, 1);
  
                refresh_cache_or_die(refresh_flags);
@@@ -601,17 -600,19 +601,17 @@@ static int prepare_to_commit(const cha
  {
        struct stat statbuf;
        struct strbuf committer_ident = STRBUF_INIT;
 -      int commitable, saved_color_setting;
 +      int commitable;
        struct strbuf sb = STRBUF_INIT;
 -      char *buffer;
        const char *hook_arg1 = NULL;
        const char *hook_arg2 = NULL;
 -      int ident_shown = 0;
        int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
        int old_display_comment_prefix;
  
        /* This checks and barfs if author is badly specified */
        determine_author_info(author_ident);
  
 -      if (!no_verify && run_hook(index_file, "pre-commit", NULL))
 +      if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", NULL))
                return 0;
  
        if (squash_message) {
                                  logfile);
                hook_arg1 = "message";
        } else if (use_message) {
 +              char *buffer;
                buffer = strstr(use_message_buffer, "\n\n");
-               if (!use_editor && (!buffer || buffer[2] == '\0'))
-                       die(_("commit has empty message"));
-               strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
+               if (buffer)
+                       strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
                hook_arg1 = "commit";
                hook_arg2 = use_message;
        } else if (fixup_message) {
                                eol = nl - sb.buf;
                        else
                                eol = sb.len;
 -                      if (!prefixcmp(sb.buf + previous, "\nConflicts:\n")) {
 +                      if (starts_with(sb.buf + previous, "\nConflicts:\n")) {
                                ignore_footer = sb.len - previous;
                                break;
                        }
        /* This checks if committer ident is explicitly given */
        strbuf_addstr(&committer_ident, git_committer_info(IDENT_STRICT));
        if (use_editor && include_status) {
 +              int ident_shown = 0;
 +              int saved_color_setting;
                char *ai_tmp, *ci_tmp;
 -              if (whence != FROM_COMMIT)
 +              if (whence != FROM_COMMIT) {
 +                      if (cleanup_mode == CLEANUP_SCISSORS)
 +                              wt_status_add_cut_line(s->fp);
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                            whence == FROM_MERGE
                                ? _("\n"
                                git_path(whence == FROM_MERGE
                                         ? "MERGE_HEAD"
                                         : "CHERRY_PICK_HEAD"));
 +              }
  
                fprintf(s->fp, "\n");
                if (cleanup_mode == CLEANUP_ALL)
                                _("Please enter the commit message for your changes."
                                  " Lines starting\nwith '%c' will be ignored, and an empty"
                                  " message aborts the commit.\n"), comment_line_char);
 +              else if (cleanup_mode == CLEANUP_SCISSORS && whence == FROM_COMMIT)
 +                      wt_status_add_cut_line(s->fp);
                else /* CLEANUP_SPACE, that is. */
                        status_printf(s, GIT_COLOR_NORMAL,
                                _("Please enter the commit message for your changes."
                return 0;
        }
  
 -      if (run_hook(index_file, "prepare-commit-msg",
 -                   git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
 +      if (run_commit_hook(use_editor, index_file, "prepare-commit-msg",
 +                          git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
                return 0;
  
        if (use_editor) {
        }
  
        if (!no_verify &&
 -          run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
 +          run_commit_hook(use_editor, index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
                return 0;
        }
  
@@@ -911,7 -903,7 +910,7 @@@ static int rest_is_empty(struct strbuf 
                        eol = sb->len;
  
                if (strlen(sign_off_header) <= eol - i &&
 -                  !prefixcmp(sb->buf + i, sign_off_header)) {
 +                  starts_with(sb->buf + i, sign_off_header)) {
                        i = eol;
                        continue;
                }
@@@ -1074,6 -1066,8 +1073,6 @@@ static int parse_and_validate_options(i
                use_editor = 0;
        if (0 <= edit_flag)
                use_editor = edit_flag;
 -      if (!use_editor)
 -              setenv("GIT_EDITOR", ":", 1);
  
        /* Sanity check options */
        if (amend && !current_head)
        if (argc == 0 && only && amend)
                only_include_assumed = _("Clever... amending the last one with dirty index.");
        if (argc > 0 && !also && !only)
 -              only_include_assumed = _("Explicit paths specified without -i nor -o; assuming --only paths...");
 +              only_include_assumed = _("Explicit paths specified without -i or -o; assuming --only paths...");
        if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
                cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
        else if (!strcmp(cleanup_arg, "verbatim"))
                cleanup_mode = CLEANUP_SPACE;
        else if (!strcmp(cleanup_arg, "strip"))
                cleanup_mode = CLEANUP_ALL;
 +      else if (!strcmp(cleanup_arg, "scissors"))
 +              cleanup_mode = use_editor ? CLEANUP_SCISSORS : CLEANUP_SPACE;
        else
                die(_("Invalid cleanup mode %s"), cleanup_arg);
  
@@@ -1190,7 -1182,7 +1189,7 @@@ static int git_status_config(const cha
  {
        struct wt_status *s = cb;
  
 -      if (!prefixcmp(k, "column."))
 +      if (starts_with(k, "column."))
                return git_column_config(k, v, "status", &s->colopts);
        if (!strcmp(k, "status.submodulesummary")) {
                int is_bool;
                s->display_comment_prefix = git_config_bool(k, v);
                return 0;
        }
 -      if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
 +      if (starts_with(k, "status.color.") || starts_with(k, "color.status.")) {
                int slot = parse_status_slot(k, 13);
                if (slot < 0)
                        return 0;
@@@ -1345,7 -1337,7 +1344,7 @@@ static void print_summary(const char *p
        commit = lookup_commit(sha1);
        if (!commit)
                die(_("couldn't look up newly created commit"));
 -      if (!commit || parse_commit(commit))
 +      if (parse_commit(commit))
                die(_("could not parse newly created commit"));
  
        strbuf_addstr(&format, "format:%h] %s");
  
        head = resolve_ref_unsafe("HEAD", junk_sha1, 0, NULL);
        printf("[%s%s ",
 -              !prefixcmp(head, "refs/heads/") ?
 +              starts_with(head, "refs/heads/") ?
                        head + 11 :
                        !strcmp(head, "HEAD") ?
                                _("detached HEAD") :
@@@ -1413,10 -1405,6 +1412,10 @@@ static int git_commit_config(const cha
        }
        if (!strcmp(k, "commit.cleanup"))
                return git_config_string(&cleanup_arg, k, v);
 +      if (!strcmp(k, "commit.gpgsign")) {
 +              sign_commit = git_config_bool(k, v) ? "" : NULL;
 +              return 0;
 +      }
  
        status = git_gpg_config(k, v, NULL);
        if (status)
@@@ -1456,29 -1444,6 +1455,29 @@@ static int run_rewrite_hook(const unsig
        return finish_command(&proc);
  }
  
 +int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)
 +{
 +      const char *hook_env[3] =  { NULL };
 +      char index[PATH_MAX];
 +      va_list args;
 +      int ret;
 +
 +      snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
 +      hook_env[0] = index;
 +
 +      /*
 +       * Let the hook know that no editor will be launched.
 +       */
 +      if (!editor_is_used)
 +              hook_env[1] = "GIT_EDITOR=:";
 +
 +      va_start(args, name);
 +      ret = run_hook_ve(hook_env, name, args);
 +      va_end(args);
 +
 +      return ret;
 +}
 +
  int cmd_commit(int argc, const char **argv, const char *prefix)
  {
        static struct wt_status s;
                OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
                OPT_STRING(0, "cleanup", &cleanup_arg, N_("default"), N_("how to strip spaces and #comments from message")),
                OPT_BOOL(0, "status", &include_status, N_("include status in commit message template")),
 -              { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
 +              { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
                  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
                /* end commit message options */
  
        struct ref_lock *ref_lock;
        struct commit_list *parents = NULL, **pptr = &parents;
        struct stat statbuf;
 -      int allow_fast_forward = 1;
        struct commit *current_head = NULL;
        struct commit_extra_header *extra = NULL;
  
                current_head = NULL;
        else {
                current_head = lookup_commit_or_die(sha1, "HEAD");
 -              if (!current_head || parse_commit(current_head))
 +              if (parse_commit(current_head))
                        die(_("could not parse HEAD commit"));
        }
        argc = parse_and_validate_options(argc, argv, builtin_commit_options,
        } else if (whence == FROM_MERGE) {
                struct strbuf m = STRBUF_INIT;
                FILE *fp;
 +              int allow_fast_forward = 1;
  
                if (!reflog_msg)
                        reflog_msg = "commit (merge)";
                die(_("could not read commit message: %s"), strerror(saved_errno));
        }
  
 -      /* Truncate the message just before the diff, if any. */
 -      if (verbose)
 +      if (verbose || /* Truncate the message just before the diff, if any. */
 +          cleanup_mode == CLEANUP_SCISSORS)
                wt_status_truncate_message_at_cut_line(&sb);
  
        if (cleanup_mode != CLEANUP_NONE)
                     "not exceeded, and then \"git reset HEAD\" to recover."));
  
        rerere(0);
 -      run_hook(get_index_file(), "post-commit", NULL);
 +      run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
        if (amend && !no_post_rewrite) {
                struct notes_rewrite_cfg *cfg;
                cfg = init_copy_notes_for_rewrite("amend");