Skip to content

Commit eff80a9

Browse files
committed
Allow custom "comment char"
Some users do want to write a line that begin with a pound sign, #, in their commit log message. Many tracking system recognise a token of #<bugid> form, for example. The support we offer these use cases is not very friendly to the end users. They have a choice between - Don't do it. Avoid such a line by rewrapping or indenting; and - Use --cleanup=whitespace but remove all the hint lines we add. Give them a way to set a custom comment char, e.g. $ git -c core.commentchar="%" commit so that they do not have to do either of the two workarounds. [jc: although I started the topic, all the tests and documentation updates, many of the call sites of the new strbuf_add_commented_*() functions, and the change to git-submodule.sh scripted Porcelain are from Ralf.] Signed-off-by: Junio C Hamano <[email protected]> Signed-off-by: Ralf Thielow <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 44fe835 commit eff80a9

20 files changed

+284
-78
lines changed

Documentation/config.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,12 @@ core.editor::
528528
variable when it is set, and the environment variable
529529
`GIT_EDITOR` is not set. See linkgit:git-var[1].
530530

531+
core.commentchar::
532+
Commands such as `commit` and `tag` that lets you edit
533+
messages consider a line that begins with this character
534+
commented, and removes them after the editor returns
535+
(default '#').
536+
531537
sequence.editor::
532538
Text editor used by `git rebase -i` for editing the rebase insn file.
533539
The value is meant to be interpreted by the shell when it is used.

Documentation/git-stripspace.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ OPTIONS
3535
-------
3636
-s::
3737
--strip-comments::
38-
Skip and remove all lines starting with '#'.
38+
Skip and remove all lines starting with comment character (default '#').
39+
40+
-c::
41+
--comment-lines::
42+
Prepend comment character and blank to each line. Lines will automatically
43+
be terminated with a newline. On empty lines, only the comment character
44+
will be prepended.
3945

4046
EXAMPLES
4147
--------

Documentation/technical/api-strbuf.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ then they will free() it.
156156
Remove the bytes between `pos..pos+len` and replace it with the given
157157
data.
158158

159+
`strbuf_add_commented_lines`::
160+
161+
Add a NUL-terminated string to the buffer. Each line will be prepended
162+
by a comment character and a blank.
163+
159164
`strbuf_add`::
160165

161166
Add data of given length to the buffer.
@@ -229,6 +234,11 @@ which can be used by the programmer of the callback as she sees fit.
229234

230235
Add a formatted string to the buffer.
231236

237+
`strbuf_commented_addf`::
238+
239+
Add a formatted string prepended by a comment character and a
240+
blank to the buffer.
241+
232242
`strbuf_fread`::
233243

234244
Read a given size of data from a FILE* pointer to the buffer.

builtin/branch.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,11 @@ static int edit_branch_description(const char *branch_name)
706706
read_branch_desc(&buf, branch_name);
707707
if (!buf.len || buf.buf[buf.len-1] != '\n')
708708
strbuf_addch(&buf, '\n');
709-
strbuf_addf(&buf,
710-
"# Please edit the description for the branch\n"
711-
"# %s\n"
712-
"# Lines starting with '#' will be stripped.\n",
713-
branch_name);
709+
strbuf_commented_addf(&buf,
710+
"Please edit the description for the branch\n"
711+
" %s\n"
712+
"Lines starting with '%c' will be stripped.\n",
713+
branch_name, comment_line_char);
714714
fp = fopen(git_path(edit_description), "w");
715715
if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
716716
strbuf_release(&buf);

builtin/commit.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -733,15 +733,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
733733
if (cleanup_mode == CLEANUP_ALL)
734734
status_printf(s, GIT_COLOR_NORMAL,
735735
_("Please enter the commit message for your changes."
736-
" Lines starting\nwith '#' will be ignored, and an empty"
737-
" message aborts the commit.\n"));
736+
" Lines starting\nwith '%c' will be ignored, and an empty"
737+
" message aborts the commit.\n"), comment_line_char);
738738
else /* CLEANUP_SPACE, that is. */
739739
status_printf(s, GIT_COLOR_NORMAL,
740740
_("Please enter the commit message for your changes."
741-
" Lines starting\n"
742-
"with '#' will be kept; you may remove them"
743-
" yourself if you want to.\n"
744-
"An empty message aborts the commit.\n"));
741+
" Lines starting\n"
742+
"with '%c' will be kept; you may remove them"
743+
" yourself if you want to.\n"
744+
"An empty message aborts the commit.\n"), comment_line_char);
745745
if (only_include_assumed)
746746
status_printf_ln(s, GIT_COLOR_NORMAL,
747747
"%s", only_include_assumed);

builtin/fmt-merge-msg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ static void fmt_tag_signature(struct strbuf *tagbuf,
464464
strbuf_complete_line(tagbuf);
465465
if (sig->len) {
466466
strbuf_addch(tagbuf, '\n');
467-
strbuf_add_lines(tagbuf, "# ", sig->buf, sig->len);
467+
strbuf_add_commented_lines(tagbuf, sig->buf, sig->len);
468468
}
469469
}
470470

builtin/merge.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,17 +788,16 @@ static const char merge_editor_comment[] =
788788
N_("Please enter a commit message to explain why this merge is necessary,\n"
789789
"especially if it merges an updated upstream into a topic branch.\n"
790790
"\n"
791-
"Lines starting with '#' will be ignored, and an empty message aborts\n"
791+
"Lines starting with '%c' will be ignored, and an empty message aborts\n"
792792
"the commit.\n");
793793

794794
static void prepare_to_commit(struct commit_list *remoteheads)
795795
{
796796
struct strbuf msg = STRBUF_INIT;
797-
const char *comment = _(merge_editor_comment);
798797
strbuf_addbuf(&msg, &merge_msg);
799798
strbuf_addch(&msg, '\n');
800799
if (0 < option_edit)
801-
strbuf_add_lines(&msg, "# ", comment, strlen(comment));
800+
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
802801
write_merge_msg(&msg);
803802
if (run_hook(get_index_file(), "prepare-commit-msg",
804803
git_path("MERGE_MSG"), "merge", NULL, NULL))

builtin/notes.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,7 @@ static const char * const git_notes_get_ref_usage[] = {
9292
};
9393

9494
static const char note_template[] =
95-
"\n"
96-
"#\n"
97-
"# Write/edit the notes for the following object:\n"
98-
"#\n";
95+
"\nWrite/edit the notes for the following object:\n";
9996

10097
struct msg_arg {
10198
int given;
@@ -129,7 +126,7 @@ static void write_commented_object(int fd, const unsigned char *object)
129126
{"show", "--stat", "--no-notes", sha1_to_hex(object), NULL};
130127
struct child_process show;
131128
struct strbuf buf = STRBUF_INIT;
132-
FILE *show_out;
129+
struct strbuf cbuf = STRBUF_INIT;
133130

134131
/* Invoke "git show --stat --no-notes $object" */
135132
memset(&show, 0, sizeof(show));
@@ -142,21 +139,14 @@ static void write_commented_object(int fd, const unsigned char *object)
142139
die(_("unable to start 'show' for object '%s'"),
143140
sha1_to_hex(object));
144141

145-
/* Open the output as FILE* so strbuf_getline() can be used. */
146-
show_out = xfdopen(show.out, "r");
147-
if (show_out == NULL)
148-
die_errno(_("can't fdopen 'show' output fd"));
142+
if (strbuf_read(&buf, show.out, 0) < 0)
143+
die_errno(_("could not read 'show' output"));
144+
strbuf_add_commented_lines(&cbuf, buf.buf, buf.len);
145+
write_or_die(fd, cbuf.buf, cbuf.len);
149146

150-
/* Prepend "# " to each output line and write result to 'fd' */
151-
while (strbuf_getline(&buf, show_out, '\n') != EOF) {
152-
write_or_die(fd, "# ", 2);
153-
write_or_die(fd, buf.buf, buf.len);
154-
write_or_die(fd, "\n", 1);
155-
}
147+
strbuf_release(&cbuf);
156148
strbuf_release(&buf);
157-
if (fclose(show_out))
158-
die_errno(_("failed to close pipe to 'show' for object '%s'"),
159-
sha1_to_hex(object));
149+
160150
if (finish_command(&show))
161151
die(_("failed to finish 'show' for object '%s'"),
162152
sha1_to_hex(object));
@@ -170,6 +160,7 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
170160

171161
if (msg->use_editor || !msg->given) {
172162
int fd;
163+
struct strbuf buf = STRBUF_INIT;
173164

174165
/* write the template message before editing: */
175166
path = git_pathdup("NOTES_EDITMSG");
@@ -181,11 +172,16 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
181172
write_or_die(fd, msg->buf.buf, msg->buf.len);
182173
else if (prev && !append_only)
183174
write_note_data(fd, prev);
184-
write_or_die(fd, note_template, strlen(note_template));
175+
176+
strbuf_addch(&buf, '\n');
177+
strbuf_add_commented_lines(&buf, note_template, strlen(note_template));
178+
strbuf_addch(&buf, '\n');
179+
write_or_die(fd, buf.buf, buf.len);
185180

186181
write_commented_object(fd, object);
187182

188183
close(fd);
184+
strbuf_release(&buf);
189185
strbuf_reset(&(msg->buf));
190186

191187
if (launch_editor(path, &(msg->buf), NULL)) {

builtin/stripspace.c

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ static size_t cleanup(char *line, size_t len)
3030
*
3131
* If last line does not have a newline at the end, one is added.
3232
*
33-
* Enable skip_comments to skip every line starting with "#".
33+
* Enable skip_comments to skip every line starting with comment
34+
* character.
3435
*/
3536
void stripspace(struct strbuf *sb, int skip_comments)
3637
{
@@ -45,7 +46,7 @@ void stripspace(struct strbuf *sb, int skip_comments)
4546
eol = memchr(sb->buf + i, '\n', sb->len - i);
4647
len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
4748

48-
if (skip_comments && len && sb->buf[i] == '#') {
49+
if (skip_comments && len && sb->buf[i] == comment_line_char) {
4950
newlen = 0;
5051
continue;
5152
}
@@ -66,21 +67,53 @@ void stripspace(struct strbuf *sb, int skip_comments)
6667
strbuf_setlen(sb, j);
6768
}
6869

70+
static void comment_lines(struct strbuf *buf)
71+
{
72+
char *msg;
73+
size_t len;
74+
75+
msg = strbuf_detach(buf, &len);
76+
strbuf_add_commented_lines(buf, msg, len);
77+
free(msg);
78+
}
79+
80+
static const char *usage_msg = "\n"
81+
" git stripspace [-s | --strip-comments] < input\n"
82+
" git stripspace [-c | --comment-lines] < input";
83+
6984
int cmd_stripspace(int argc, const char **argv, const char *prefix)
7085
{
7186
struct strbuf buf = STRBUF_INIT;
7287
int strip_comments = 0;
88+
enum { INVAL = 0, STRIP_SPACE = 1, COMMENT_LINES = 2 } mode = STRIP_SPACE;
89+
90+
if (argc == 2) {
91+
if (!strcmp(argv[1], "-s") ||
92+
!strcmp(argv[1], "--strip-comments")) {
93+
strip_comments = 1;
94+
} else if (!strcmp(argv[1], "-c") ||
95+
!strcmp(argv[1], "--comment-lines")) {
96+
mode = COMMENT_LINES;
97+
} else {
98+
mode = INVAL;
99+
}
100+
} else if (argc > 1) {
101+
mode = INVAL;
102+
}
103+
104+
if (mode == INVAL)
105+
usage(usage_msg);
73106

74-
if (argc == 2 && (!strcmp(argv[1], "-s") ||
75-
!strcmp(argv[1], "--strip-comments")))
76-
strip_comments = 1;
77-
else if (argc > 1)
78-
usage("git stripspace [-s | --strip-comments] < input");
107+
if (strip_comments || mode == COMMENT_LINES)
108+
git_config(git_default_config, NULL);
79109

80110
if (strbuf_read(&buf, 0, 1024) < 0)
81111
die_errno("could not read the input");
82112

83-
stripspace(&buf, strip_comments);
113+
if (mode == STRIP_SPACE)
114+
stripspace(&buf, strip_comments);
115+
else
116+
comment_lines(&buf);
84117

85118
write_or_die(1, buf.buf, buf.len);
86119
strbuf_release(&buf);

builtin/tag.c

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -246,19 +246,13 @@ static int do_sign(struct strbuf *buffer)
246246
}
247247

248248
static const char tag_template[] =
249-
N_("\n"
250-
"#\n"
251-
"# Write a tag message\n"
252-
"# Lines starting with '#' will be ignored.\n"
253-
"#\n");
249+
N_("\nWrite a tag message\n"
250+
"Lines starting with '%c' will be ignored.\n");
254251

255252
static const char tag_template_nocleanup[] =
256-
N_("\n"
257-
"#\n"
258-
"# Write a tag message\n"
259-
"# Lines starting with '#' will be kept; you may remove them"
260-
" yourself if you want to.\n"
261-
"#\n");
253+
N_("\nWrite a tag message\n"
254+
"Lines starting with '%c' will be kept; you may remove them"
255+
" yourself if you want to.\n");
262256

263257
static int git_tag_config(const char *var, const char *value, void *cb)
264258
{
@@ -346,14 +340,18 @@ static void create_tag(const unsigned char *object, const char *tag,
346340
if (fd < 0)
347341
die_errno(_("could not create file '%s'"), path);
348342

349-
if (!is_null_sha1(prev))
343+
if (!is_null_sha1(prev)) {
350344
write_tag_body(fd, prev);
351-
else if (opt->cleanup_mode == CLEANUP_ALL)
352-
write_or_die(fd, _(tag_template),
353-
strlen(_(tag_template)));
354-
else
355-
write_or_die(fd, _(tag_template_nocleanup),
356-
strlen(_(tag_template_nocleanup)));
345+
} else {
346+
struct strbuf buf = STRBUF_INIT;
347+
strbuf_addch(&buf, '\n');
348+
if (opt->cleanup_mode == CLEANUP_ALL)
349+
strbuf_commented_addf(&buf, _(tag_template), comment_line_char);
350+
else
351+
strbuf_commented_addf(&buf, _(tag_template_nocleanup), comment_line_char);
352+
write_or_die(fd, buf.buf, buf.len);
353+
strbuf_release(&buf);
354+
}
357355
close(fd);
358356

359357
if (launch_editor(path, buf, NULL)) {

cache.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,12 @@ extern int core_preload_index;
562562
extern int core_apply_sparse_checkout;
563563
extern int precomposed_unicode;
564564

565+
/*
566+
* The character that begins a commented line in user-editable file
567+
* that is subject to stripspace.
568+
*/
569+
extern char comment_line_char;
570+
565571
enum branch_track {
566572
BRANCH_TRACK_UNSPECIFIED = -1,
567573
BRANCH_TRACK_NEVER = 0,

config.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,14 @@ static int git_default_core_config(const char *var, const char *value)
717717
if (!strcmp(var, "core.editor"))
718718
return git_config_string(&editor_program, var, value);
719719

720+
if (!strcmp(var, "core.commentchar")) {
721+
const char *comment;
722+
int ret = git_config_string(&comment, var, value);
723+
if (!ret)
724+
comment_line_char = comment[0];
725+
return ret;
726+
}
727+
720728
if (!strcmp(var, "core.askpass"))
721729
return git_config_string(&askpass_program, var, value);
722730

environment.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
6262
struct startup_info *startup_info;
6363
unsigned long pack_size_limit_cfg;
6464

65+
/*
66+
* The character that begins a commented line in user-editable file
67+
* that is subject to stripspace.
68+
*/
69+
char comment_line_char = '#';
70+
6571
/* Parallel index stat data preload? */
6672
int core_preload_index = 0;
6773

git-submodule.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -976,12 +976,12 @@ cmd_summary() {
976976
done |
977977
if test -n "$for_status"; then
978978
if [ -n "$files" ]; then
979-
gettextln "# Submodules changed but not updated:"
979+
gettextln "Submodules changed but not updated:" | git stripspace -c
980980
else
981-
gettextln "# Submodule changes to be committed:"
981+
gettextln "Submodule changes to be committed:" | git stripspace -c
982982
fi
983-
echo "#"
984-
sed -e 's|^|# |' -e 's|^# $|#|'
983+
printf "\n" | git stripspace -c
984+
git stripspace -c
985985
else
986986
cat
987987
fi

0 commit comments

Comments
 (0)