Merge branch 'jl/commit-v-strip-marker' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 5 Feb 2014 22:01:09 +0000 (14:01 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Feb 2014 22:01:09 +0000 (14:01 -0800)
"git commit -v" appends the patch to the log message before
editing, and then removes the patch when the editor returned
control. However, the patch was not stripped correctly when the
first modified path was a submodule.

* jl/commit-v-strip-marker:
commit -v: strip diffs and submodule shortlogs from the commit message

builtin/commit.c
t/t7507-commit-verbose.sh
wt-status.c
wt-status.h
index 6ab4605cf5c2e6ef5efb37518c9c215bf8895f97..fedb45af8c65d28c3b43b3b74362e589d81a95ee 100644 (file)
@@ -1505,7 +1505,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        struct strbuf sb = STRBUF_INIT;
        struct strbuf author_ident = STRBUF_INIT;
        const char *index_file, *reflog_msg;
-       char *nl, *p;
+       char *nl;
        unsigned char sha1[20];
        struct ref_lock *ref_lock;
        struct commit_list *parents = NULL, **pptr = &parents;
@@ -1601,11 +1601,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
        }
 
        /* Truncate the message just before the diff, if any. */
-       if (verbose) {
-               p = strstr(sb.buf, "\ndiff --git ");
-               if (p != NULL)
-                       strbuf_setlen(&sb, p - sb.buf + 1);
-       }
+       if (verbose)
+               wt_status_truncate_message_at_cut_line(&sb);
 
        if (cleanup_mode != CLEANUP_NONE)
                stripspace(&sb, cleanup_mode == CLEANUP_ALL);
index da5bd3b5a585667dad97481df27049f0aa7415eb..2ddf28c984de99cb17884f76d68a708076f57e12 100755 (executable)
@@ -65,9 +65,35 @@ test_expect_success 'diff in message is retained without -v' '
        check_message diff
 '
 
-test_expect_failure 'diff in message is retained with -v' '
+test_expect_success 'diff in message is retained with -v' '
        git commit --amend -F diff -v &&
        check_message diff
 '
 
+test_expect_success 'submodule log is stripped out too with -v' '
+       git config diff.submodule log &&
+       git submodule add ./. sub &&
+       git commit -m "sub added" &&
+       (
+               cd sub &&
+               echo "more" >>file &&
+               git commit -a -m "submodule commit"
+       ) &&
+       (
+               GIT_EDITOR=cat &&
+               export GIT_EDITOR &&
+               test_must_fail git commit -a -v 2>err
+       ) &&
+       test_i18ngrep "Aborting commit due to empty commit message." err
+'
+
+test_expect_success 'verbose diff is stripped out with set core.commentChar' '
+       (
+               GIT_EDITOR=cat &&
+               export GIT_EDITOR &&
+               test_must_fail git -c core.commentchar=";" commit -a -v 2>err
+       ) &&
+       test_i18ngrep "Aborting commit due to empty commit message." err
+'
+
 test_done
index b4e44baa2917dfcf33824c3d6fc08756886b9ae1..85390b813f12e2392b73dd6dffe8d1b41e838614 100644 (file)
@@ -16,6 +16,9 @@
 #include "column.h"
 #include "strbuf.h"
 
+static char cut_line[] =
+"------------------------ >8 ------------------------\n";
+
 static char default_wt_status_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
        GIT_COLOR_GREEN,  /* WT_STATUS_UPDATED */
@@ -767,6 +770,18 @@ static void wt_status_print_other(struct wt_status *s,
        status_printf_ln(s, GIT_COLOR_NORMAL, "");
 }
 
+void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
+{
+       const char *p;
+       struct strbuf pattern = STRBUF_INIT;
+
+       strbuf_addf(&pattern, "%c %s", comment_line_char, cut_line);
+       p = strstr(buf->buf, pattern.buf);
+       if (p && (p == buf->buf || p[-1] == '\n'))
+               strbuf_setlen(buf, p - buf->buf);
+       strbuf_release(&pattern);
+}
+
 static void wt_status_print_verbose(struct wt_status *s)
 {
        struct rev_info rev;
@@ -787,10 +802,20 @@ static void wt_status_print_verbose(struct wt_status *s)
         * If we're not going to stdout, then we definitely don't
         * want color, since we are going to the commit message
         * file (and even the "auto" setting won't work, since it
-        * will have checked isatty on stdout).
+        * will have checked isatty on stdout). But we then do want
+        * to insert the scissor line here to reliably remove the
+        * diff before committing.
         */
-       if (s->fp != stdout)
+       if (s->fp != stdout) {
+               const char *explanation = _("Do not touch the line above.\nEverything below will be removed.");
+               struct strbuf buf = STRBUF_INIT;
+
                rev.diffopt.use_color = 0;
+               fprintf(s->fp, "%c %s", comment_line_char, cut_line);
+               strbuf_add_commented_lines(&buf, explanation, strlen(explanation));
+               fputs(buf.buf, s->fp);
+               strbuf_release(&buf);
+       }
        run_diff_index(&rev, 1);
 }
 
index 6c29e6f5e57f84eb7acdc3cf1ee621cc717fd5a9..30a481258366733ad5d6a65e3a9c3ae1ee74e833 100644 (file)
@@ -91,6 +91,7 @@ struct wt_status_state {
        unsigned char cherry_pick_head_sha1[20];
 };
 
+void wt_status_truncate_message_at_cut_line(struct strbuf *);
 void wt_status_prepare(struct wt_status *s);
 void wt_status_print(struct wt_status *s);
 void wt_status_collect(struct wt_status *s);