core.commentChar starts with '#' as in default but if it's already in the prepared message, find another one among a small subset. This should stop surprises because git strips some lines unexpectedly. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/config.txt | 3 +++ builtin/commit.c | 36 ++++++++++++++++++++++++++++++++++++ cache.h | 1 + config.c | 2 ++ environment.c | 1 + t/t7502-commit.sh | 25 +++++++++++++++++++++++++ 6 files changed, 68 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 1932e9b..d5bf4d0 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -544,6 +544,9 @@ core.commentchar:: messages consider a line that begins with this character commented, and removes them after the editor returns (default '#'). ++ +If set to "auto", `git-commit` would select a character that is not +the beginning character of any line of existing commit messages. sequence.editor:: Text editor used by `git rebase -i` for editing the rebase instruction file. diff --git a/builtin/commit.c b/builtin/commit.c index 9cfef6c..039b426 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -594,6 +594,40 @@ static char *cut_ident_timestamp_part(char *string) return ket; } +static void adjust_comment_line_char(const struct strbuf *sb) +{ + char candidates[] = " @!#$%^&|:;~"; + char *candidate; + const char *p; + + if (!sb->len) + return; + + if (!strchr(candidates, comment_line_char)) + candidates[0] = comment_line_char; + p = sb->buf; + candidate = strchr(candidates, *p); + if (candidate) + *candidate = ' '; + for (p = sb->buf; *p; p++) { + if ((p[0] == '\n' || p[0] == '\r') && p[1]) { + candidate = strchr(candidates, p[1]); + if (candidate) + *candidate = ' '; + } + } + + if (candidates[0] == comment_line_char) + return; + for (p = candidates; *p == ' '; p++) + ; + if (!*p) + die(_("the comment character '%c' exists in the commit message\n" + "Please choose another character for core.commentChar"), + comment_line_char); + comment_line_char = *p; +} + static int prepare_to_commit(const char *index_file, const char *prefix, struct commit *current_head, struct wt_status *s, @@ -748,6 +782,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) die_errno(_("could not write commit template")); + if (auto_comment_line_char) + adjust_comment_line_char(&sb); strbuf_release(&sb); /* This checks if committer ident is explicitly given */ diff --git a/cache.h b/cache.h index 107ac61..646fb81 100644 --- a/cache.h +++ b/cache.h @@ -602,6 +602,7 @@ extern int precomposed_unicode; * that is subject to stripspace. */ extern char comment_line_char; +extern int auto_comment_line_char; enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, diff --git a/config.c b/config.c index 05d909b..5ec3520 100644 --- a/config.c +++ b/config.c @@ -829,6 +829,8 @@ static int git_default_core_config(const char *var, const char *value) if (!ret) { if (comment[0] && !comment[1]) comment_line_char = comment[0]; + else if (!strcasecmp(comment, "auto")) + auto_comment_line_char = 1; else return error("core.commentChar should only be one character"); } diff --git a/environment.c b/environment.c index 5c4815d..f2de1ee 100644 --- a/environment.c +++ b/environment.c @@ -69,6 +69,7 @@ unsigned long pack_size_limit_cfg; * that is subject to stripspace. */ char comment_line_char = '#'; +int auto_comment_line_char; /* Parallel index stat data preload? */ int core_preload_index = 0; diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 9a3f3a1..5cff300 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -563,4 +563,29 @@ test_expect_success 'commit --status with custom comment character' ' test_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG ' +test_expect_success 'switch core.commentchar' ' + test_commit "#foo" foo && + GIT_EDITOR=.git/FAKE_EDITOR git -c core.commentChar=auto commit --amend && + test_i18ngrep "^@ Changes to be committed:" .git/COMMIT_EDITMSG +' + +test_expect_success 'switch core.commentchar but out of options' ' + cat >text <<\EOF && +# 1 +@ 2 +! 3 +$ 4 +% 5 +^ 6 +& 7 +| 8 +: 9 +; 10 +~ 11 +EOF + git commit --amend -F text && + GIT_EDITOR=.git/FAKE_EDITOR test_must_fail \ + git -c core.commentChar=auto commit --amend +' + test_done -- 1.9.1.346.ga2b5940 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html