Merge branch 'jc/commit-unedited-template' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 26 Apr 2012 17:35:15 +0000 (10:35 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 26 Apr 2012 17:35:15 +0000 (10:35 -0700)
When "git commit --template F" errors out because the user did not
touch the message, it claimed that it aborts due to "empty message",
which was utterly wrong.

By Junio C Hamano (4) and Adam Monsen (1)
* jc/commit-unedited-template:
Documentation/git-commit: rephrase the "initial-ness" of templates
git-commit.txt: clarify -t requires editing message
commit: rephrase the error when user did not touch templated log message
commit: do not trigger bogus "has templated message edited" check
t7501: test the right kind of breakage

Documentation/git-commit.txt
builtin/commit.c
t/t7501-commit.sh
index 5cc84a139133dca2fdcb594007c8b0d6464d5ca8..68abfcacca8f3b0dc7c2daec54e539547ff6b5f9 100644 (file)
@@ -132,11 +132,14 @@ OPTIONS
 
 -t <file>::
 --template=<file>::
-       Use the contents of the given file as the initial version
-       of the commit message. The editor is invoked and you can
-       make subsequent changes. If a message is specified using
-       the `-m` or `-F` options, this option has no effect. This
-       overrides the `commit.template` configuration variable.
+       When editing the commit message, start the editor with the
+       contents in the given file.  The `commit.template` configuration
+       variable is often used to give this option implicitly to the
+       command.  This mechanism can be used by projects that want to
+       guide participants with some hints on what to write in the message
+       in what order.  If the user exits the editor without editing the
+       message, the commit is aborted.  This has no effect when a message
+       is given by other means, e.g. with the `-m` or `-F` options.
 
 -s::
 --signoff::
index 7808be30e181e9cc4f031cdfea3b155f32970da8..b257ae87740fb0887d285e88476a6ba423e6c25c 100644 (file)
@@ -921,27 +921,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        return 1;
 }
 
-/*
- * Find out if the message in the strbuf contains only whitespace and
- * Signed-off-by lines.
- */
-static int message_is_empty(struct strbuf *sb)
+static int rest_is_empty(struct strbuf *sb, int start)
 {
-       struct strbuf tmpl = STRBUF_INIT;
+       int i, eol;
        const char *nl;
-       int eol, i, start = 0;
-
-       if (cleanup_mode == CLEANUP_NONE && sb->len)
-               return 0;
-
-       /* See if the template is just a prefix of the message. */
-       if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
-               stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
-               if (start + tmpl.len <= sb->len &&
-                   memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
-                       start += tmpl.len;
-       }
-       strbuf_release(&tmpl);
 
        /* Check if the rest is just whitespace and Signed-of-by's. */
        for (i = start; i < sb->len; i++) {
@@ -964,6 +947,40 @@ static int message_is_empty(struct strbuf *sb)
        return 1;
 }
 
+/*
+ * Find out if the message in the strbuf contains only whitespace and
+ * Signed-off-by lines.
+ */
+static int message_is_empty(struct strbuf *sb)
+{
+       if (cleanup_mode == CLEANUP_NONE && sb->len)
+               return 0;
+       return rest_is_empty(sb, 0);
+}
+
+/*
+ * See if the user edited the message in the editor or left what
+ * was in the template intact
+ */
+static int template_untouched(struct strbuf *sb)
+{
+       struct strbuf tmpl = STRBUF_INIT;
+       char *start;
+
+       if (cleanup_mode == CLEANUP_NONE && sb->len)
+               return 0;
+
+       if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
+               return 0;
+
+       stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
+       start = (char *)skip_prefix(sb->buf, tmpl.buf);
+       if (!start)
+               start = sb->buf;
+       strbuf_release(&tmpl);
+       return rest_is_empty(sb, start - sb->buf);
+}
+
 static const char *find_author_by_nickname(const char *name)
 {
        struct rev_info revs;
@@ -1071,6 +1088,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
                die(_("Only one of -c/-C/-F/--fixup can be used."));
        if (message.len && f > 0)
                die((_("Option -m cannot be combined with -c/-C/-F/--fixup.")));
+       if (f || message.len)
+               template_file = NULL;
        if (edit_message)
                use_message = edit_message;
        if (amend && !use_message && !fixup_message)
@@ -1510,6 +1529,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
        if (cleanup_mode != CLEANUP_NONE)
                stripspace(&sb, cleanup_mode == CLEANUP_ALL);
+       if (template_untouched(&sb) && !allow_empty_message) {
+               rollback_index_files();
+               fprintf(stderr, _("Aborting commit; you did not edit the message.\n"));
+               exit(1);
+       }
        if (message_is_empty(&sb) && !allow_empty_message) {
                rollback_index_files();
                fprintf(stderr, _("Aborting commit due to empty commit message.\n"));
index 8bb38337a9796142bc091c2b108f7f9e79b0f377..b20ca0eace9dd8f9a11227ebfb932e0446278ea1 100755 (executable)
@@ -30,10 +30,12 @@ test_expect_success 'setup: initial commit' '
 '
 
 test_expect_success '-m and -F do not mix' '
+       git checkout HEAD file && echo >>file && git add file &&
        test_must_fail git commit -m foo -m bar -F file
 '
 
 test_expect_success '-m and -C do not mix' '
+       git checkout HEAD file && echo >>file && git add file &&
        test_must_fail git commit -C HEAD -m illegal
 '
 
@@ -79,7 +81,19 @@ test_expect_success 'empty commit message' '
        test_must_fail git commit -F msg -a
 '
 
+test_expect_success 'template "emptyness" check does not kick in with -F' '
+       git checkout HEAD file && echo >>file && git add file &&
+       git commit -t file -F file
+'
+
+test_expect_success 'template "emptyness" check' '
+       git checkout HEAD file && echo >>file && git add file &&
+       test_must_fail git commit -t file 2>err &&
+       test_i18ngrep "did not edit" err
+'
+
 test_expect_success 'setup: commit message from file' '
+       git checkout HEAD file && echo >>file && git add file &&
        echo this is the commit message, coming from a file >msg &&
        git commit -F msg -a
 '