From 50b54fd72a8776d628365c7760bc922902d29d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sat, 17 May 2014 08:52:22 +0700 Subject: [PATCH 1/2] config: be strict on core.commentChar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't support comment _strings_ (at least not yet). And multi-byte character encoding could also be misinterpreted. The test with two commas is updated because it violates this. It's added with the patch that introduces core.commentChar in eff80a9 (Allow custom "comment char" - 2013-01-16). It's not clear to me _why_ that behavior is wanted. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- config.c | 8 ++++++-- t/t7508-status.sh | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config.c b/config.c index a30cb5c07db18a..491a9050aebdef 100644 --- a/config.c +++ b/config.c @@ -826,9 +826,13 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.commentchar")) { const char *comment; int ret = git_config_string(&comment, var, value); - if (!ret) + if (ret) + return ret; + else if (comment[0] && !comment[1]) { comment_line_char = comment[0]; - return ret; + } else + return error("core.commentChar should only be one character"); + return 0; } if (!strcmp(var, "core.askpass")) diff --git a/t/t7508-status.sh b/t/t7508-status.sh index c987b5ed652b97..148ab9ebc2fe24 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -1350,8 +1350,7 @@ test_expect_success "status (core.commentchar with submodule summary)" ' test_expect_success "status (core.commentchar with two chars with submodule summary)" ' test_config core.commentchar ";;" && - git -c status.displayCommentPrefix=true status >output && - test_i18ncmp expect output + test_must_fail git -c status.displayCommentPrefix=true status ' test_expect_success "--ignore-submodules=all suppresses submodule summary" ' From 84c9dc2c5a2d34351a06554af32501d4f99990e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Sat, 17 May 2014 08:52:23 +0700 Subject: [PATCH 2/2] commit: allow core.commentChar=auto for character auto selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When core.commentChar is "auto", the comment char starts with '#' as in default but if it's already in the prepared message, find another char in a small subset. This should stop surprises because git strips some lines unexpectedly. Note that git is not smart enough to recognize '#' as the comment char in custom templates and convert it if the final comment char is different. It thinks '#' lines in custom templates as part of the commit message. So don't use this with custom templates. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- Documentation/config.txt | 3 +++ builtin/commit.c | 32 ++++++++++++++++++++++++++++++++ cache.h | 1 + config.c | 3 +++ environment.c | 1 + t/t7502-commit.sh | 26 ++++++++++++++++++++++++++ 6 files changed, 66 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 1932e9b9a2be54..9f3ce06c8734d2 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 in 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 9cfef6c6cca619..515c4c4c0553c0 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -594,6 +594,36 @@ 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; + + comment_line_char = candidates[0]; + if (!memchr(sb->buf, comment_line_char, sb->len)) + return; + + 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 = ' '; + } + } + + for (p = candidates; *p == ' '; p++) + ; + if (!*p) + die(_("unable to select a comment character that is not used\n" + "in the current commit message")); + 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 +778,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 107ac61b68f15b..646fb810bb38f5 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 491a9050aebdef..d29c7334198292 100644 --- a/config.c +++ b/config.c @@ -828,8 +828,11 @@ static int git_default_core_config(const char *var, const char *value) int ret = git_config_string(&comment, var, value); if (ret) return ret; + else if (!strcasecmp(comment, "auto")) + auto_comment_line_char = 1; else if (comment[0] && !comment[1]) { comment_line_char = comment[0]; + auto_comment_line_char = 0; } else return error("core.commentChar should only be one character"); return 0; diff --git a/environment.c b/environment.c index 5c4815dbe132fc..f2de1ee9ada0c1 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 9a3f3a1b4151eb..30e46884f29722 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -563,4 +563,30 @@ 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 +EOF + git commit --amend -F text && + ( + test_set_editor .git/FAKE_EDITOR && + test_must_fail git -c core.commentChar=auto commit --amend + ) +' + test_done