Skip to content

Commit

Permalink
Merge branch 'jk/core-comment-string'
Browse files Browse the repository at this point in the history
core.commentChar used to be limited to a single byte, but has been
updated to allow an arbitrary multi-byte sequence.

* jk/core-comment-string:
  config: add core.commentString
  config: allow multi-byte core.commentChar
  environment: drop comment_line_char compatibility macro
  wt-status: drop custom comment-char stringification
  sequencer: handle multi-byte comment characters when writing todo list
  find multi-byte comment chars in unterminated buffers
  find multi-byte comment chars in NUL-terminated strings
  prefer comment_line_str to comment_line_char for printing
  strbuf: accept a comment string for strbuf_add_commented_lines()
  strbuf: accept a comment string for strbuf_commented_addf()
  strbuf: accept a comment string for strbuf_stripspace()
  environment: store comment_line_char as a string
  strbuf: avoid shadowing global comment_line_char name
  commit: refactor base-case of adjust_comment_line_char()
  strbuf: avoid static variables in strbuf_add_commented_lines()
  strbuf: simplify comment-handling in add_lines() helper
  config: forbid newline as core.commentChar
  • Loading branch information
gitster committed Apr 5, 2024
2 parents 3256584 + 9ccf3e9 commit dce1e0b
Show file tree
Hide file tree
Showing 26 changed files with 182 additions and 136 deletions.
17 changes: 16 additions & 1 deletion Documentation/config/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -520,13 +520,28 @@ core.editor::
`GIT_EDITOR` is not set. See linkgit:git-var[1].

core.commentChar::
core.commentString::
Commands such as `commit` and `tag` that let you edit
messages consider a line that begins with this ASCII character
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.
+
Note that these two variables are aliases of each other, and in modern
versions of Git you are free to use a string (e.g., `//` or `⁑⁕⁑`) with
`commentChar`. Versions of Git prior to v2.45.0 will ignore
`commentString` but will reject a value of `commentChar` that consists
of more than a single ASCII byte. If you plan to use your config with
older and newer versions of Git, you may want to specify both:
+
[core]
# single character for older versions
commentChar = "#"
# string for newer versions (which will override commentChar
# because it comes later in the file)
commentString = "//"

core.filesRefLockTimeout::
The length of time, in milliseconds, to retry when trying to
Expand Down
14 changes: 7 additions & 7 deletions add-patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,26 +1105,26 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
size_t i;

strbuf_reset(&s->buf);
strbuf_commented_addf(&s->buf, comment_line_char,
strbuf_commented_addf(&s->buf, comment_line_str,
_("Manual hunk edit mode -- see bottom for "
"a quick guide.\n"));
render_hunk(s, hunk, 0, 0, &s->buf);
strbuf_commented_addf(&s->buf, comment_line_char,
strbuf_commented_addf(&s->buf, comment_line_str,
_("---\n"
"To remove '%c' lines, make them ' ' lines "
"(context).\n"
"To remove '%c' lines, delete them.\n"
"Lines starting with %c will be removed.\n"),
"Lines starting with %s will be removed.\n"),
s->mode->is_reverse ? '+' : '-',
s->mode->is_reverse ? '-' : '+',
comment_line_char);
strbuf_commented_addf(&s->buf, comment_line_char, "%s",
comment_line_str);
strbuf_commented_addf(&s->buf, comment_line_str, "%s",
_(s->mode->edit_hunk_hint));
/*
* TRANSLATORS: 'it' refers to the patch mentioned in the previous
* messages.
*/
strbuf_commented_addf(&s->buf, comment_line_char,
strbuf_commented_addf(&s->buf, comment_line_str,
_("If it does not apply cleanly, you will be "
"given an opportunity to\n"
"edit again. If all lines of the hunk are "
Expand All @@ -1139,7 +1139,7 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
for (i = 0; i < s->buf.len; ) {
size_t next = find_next_line(&s->buf, i);

if (s->buf.buf[i] != comment_line_char)
if (!starts_with(s->buf.buf + i, comment_line_str))
strbuf_add(&s->plain, s->buf.buf + i, next - i);
i = next;
}
Expand Down
2 changes: 1 addition & 1 deletion builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,7 @@ static int parse_mail(struct am_state *state, const char *mail)

strbuf_addstr(&msg, "\n\n");
strbuf_addbuf(&msg, &mi.log_message);
strbuf_stripspace(&msg, '\0');
strbuf_stripspace(&msg, NULL);

assert(!state->author_name);
state->author_name = strbuf_detach(&author_name, NULL);
Expand Down
8 changes: 4 additions & 4 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,18 +677,18 @@ static int edit_branch_description(const char *branch_name)
exists = !read_branch_desc(&buf, branch_name);
if (!buf.len || buf.buf[buf.len-1] != '\n')
strbuf_addch(&buf, '\n');
strbuf_commented_addf(&buf, comment_line_char,
strbuf_commented_addf(&buf, comment_line_str,
_("Please edit the description for the branch\n"
" %s\n"
"Lines starting with '%c' will be stripped.\n"),
branch_name, comment_line_char);
"Lines starting with '%s' will be stripped.\n"),
branch_name, comment_line_str);
write_file_buf(edit_description(), buf.buf, buf.len);
strbuf_reset(&buf);
if (launch_editor(edit_description(), &buf, NULL)) {
strbuf_release(&buf);
return -1;
}
strbuf_stripspace(&buf, comment_line_char);
strbuf_stripspace(&buf, comment_line_str);

strbuf_addf(&name, "branch.%s.description", branch_name);
if (buf.len || exists)
Expand Down
21 changes: 11 additions & 10 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,10 @@ static void adjust_comment_line_char(const struct strbuf *sb)
char *candidate;
const char *p;

comment_line_char = candidates[0];
if (!memchr(sb->buf, comment_line_char, sb->len))
if (!memchr(sb->buf, candidates[0], sb->len)) {
comment_line_str = xstrfmt("%c", candidates[0]);
return;
}

p = sb->buf;
candidate = strchr(candidates, *p);
Expand All @@ -706,7 +707,7 @@ static void adjust_comment_line_char(const struct strbuf *sb)
if (!*p)
die(_("unable to select a comment character that is not used\n"
"in the current commit message"));
comment_line_char = *p;
comment_line_str = xstrfmt("%c", *p);
}

static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,
Expand Down Expand Up @@ -889,7 +890,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
s->hints = 0;

if (clean_message_contents)
strbuf_stripspace(&sb, '\0');
strbuf_stripspace(&sb, NULL);

if (signoff)
append_signoff(&sb, ignored_log_message_bytes(sb.buf, sb.len), 0);
Expand All @@ -909,18 +910,18 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
struct ident_split ci, ai;
const char *hint_cleanup_all = allow_empty_message ?
_("Please enter the commit message for your changes."
" Lines starting\nwith '%c' will be ignored.\n") :
" Lines starting\nwith '%s' will be ignored.\n") :
_("Please enter the commit message for your changes."
" Lines starting\nwith '%c' will be ignored, and an empty"
" Lines starting\nwith '%s' will be ignored, and an empty"
" message aborts the commit.\n");
const char *hint_cleanup_space = allow_empty_message ?
_("Please enter the commit message for your changes."
" Lines starting\n"
"with '%c' will be kept; you may remove them"
"with '%s' will be kept; you may remove them"
" yourself if you want to.\n") :
_("Please enter the commit message for your changes."
" Lines starting\n"
"with '%c' will be kept; you may remove them"
"with '%s' will be kept; you may remove them"
" yourself if you want to.\n"
"An empty message aborts the commit.\n");
if (whence != FROM_COMMIT) {
Expand All @@ -943,12 +944,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,

fprintf(s->fp, "\n");
if (cleanup_mode == COMMIT_MSG_CLEANUP_ALL)
status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_char);
status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_all, comment_line_str);
else if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
if (whence == FROM_COMMIT)
wt_status_add_cut_line(s);
} else /* COMMIT_MSG_CLEANUP_SPACE, that is. */
status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_char);
status_printf(s, GIT_COLOR_NORMAL, hint_cleanup_space, comment_line_str);

/*
* These should never fail because they come from our own
Expand Down
12 changes: 6 additions & 6 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ static const char scissors_editor_comment[] =
N_("An empty message aborts the commit.\n");

static const char no_scissors_editor_comment[] =
N_("Lines starting with '%c' will be ignored, and an empty message aborts\n"
N_("Lines starting with '%s' will be ignored, and an empty message aborts\n"
"the commit.\n");

static void write_merge_heads(struct commit_list *);
Expand Down Expand Up @@ -853,16 +853,16 @@ static void prepare_to_commit(struct commit_list *remoteheads)
strbuf_addch(&msg, '\n');
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
wt_status_append_cut_line(&msg);
strbuf_commented_addf(&msg, comment_line_char, "\n");
strbuf_commented_addf(&msg, comment_line_str, "\n");
}
strbuf_commented_addf(&msg, comment_line_char,
strbuf_commented_addf(&msg, comment_line_str,
_(merge_editor_comment));
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
strbuf_commented_addf(&msg, comment_line_char,
strbuf_commented_addf(&msg, comment_line_str,
_(scissors_editor_comment));
else
strbuf_commented_addf(&msg, comment_line_char,
_(no_scissors_editor_comment), comment_line_char);
strbuf_commented_addf(&msg, comment_line_str,
_(no_scissors_editor_comment), comment_line_str);
}
if (signoff)
append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0);
Expand Down
12 changes: 6 additions & 6 deletions builtin/notes.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static void write_commented_object(int fd, const struct object_id *object)

if (strbuf_read(&buf, show.out, 0) < 0)
die_errno(_("could not read 'show' output"));
strbuf_add_commented_lines(&cbuf, buf.buf, buf.len, comment_line_char);
strbuf_add_commented_lines(&cbuf, buf.buf, buf.len, comment_line_str);
write_or_die(fd, cbuf.buf, cbuf.len);

strbuf_release(&cbuf);
Expand Down Expand Up @@ -207,10 +207,10 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
copy_obj_to_fd(fd, old_note);

strbuf_addch(&buf, '\n');
strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_char);
strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_str);
strbuf_add_commented_lines(&buf, _(note_template), strlen(_(note_template)),
comment_line_char);
strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_char);
comment_line_str);
strbuf_add_commented_lines(&buf, "\n", strlen("\n"), comment_line_str);
write_or_die(fd, buf.buf, buf.len);

write_commented_object(fd, object);
Expand All @@ -223,7 +223,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
die(_("please supply the note contents using either -m or -F option"));
}
if (d->stripspace)
strbuf_stripspace(&d->buf, comment_line_char);
strbuf_stripspace(&d->buf, comment_line_str);
}
}

Expand Down Expand Up @@ -264,7 +264,7 @@ static void concat_messages(struct note_data *d)
if ((d->stripspace == UNSPECIFIED &&
d->messages[i]->stripspace == STRIPSPACE) ||
d->stripspace == STRIPSPACE)
strbuf_stripspace(&d->buf, 0);
strbuf_stripspace(&d->buf, NULL);
strbuf_reset(&msg);
}
strbuf_release(&msg);
Expand Down
2 changes: 1 addition & 1 deletion builtin/rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ static int edit_todo_file(unsigned flags)
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
return error_errno(_("could not read '%s'."), todo_file);

strbuf_stripspace(&todo_list.buf, comment_line_char);
strbuf_stripspace(&todo_list.buf, comment_line_str);
res = edit_todo_list(the_repository, &todo_list, &new_todo, NULL, NULL, flags);
if (!res && todo_list_write_to_file(the_repository, &new_todo, todo_file,
NULL, NULL, -1, flags & ~(TODO_LIST_SHORTEN_IDS)))
Expand Down
4 changes: 2 additions & 2 deletions builtin/stripspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ static void comment_lines(struct strbuf *buf)
size_t len;

msg = strbuf_detach(buf, &len);
strbuf_add_commented_lines(buf, msg, len, comment_line_char);
strbuf_add_commented_lines(buf, msg, len, comment_line_str);
free(msg);
}

Expand Down Expand Up @@ -59,7 +59,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)

if (mode == STRIP_DEFAULT || mode == STRIP_COMMENTS)
strbuf_stripspace(&buf,
mode == STRIP_COMMENTS ? comment_line_char : '\0');
mode == STRIP_COMMENTS ? comment_line_str : NULL);
else
comment_lines(&buf);

Expand Down
14 changes: 7 additions & 7 deletions builtin/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,

static const char tag_template[] =
N_("\nWrite a message for tag:\n %s\n"
"Lines starting with '%c' will be ignored.\n");
"Lines starting with '%s' will be ignored.\n");

static const char tag_template_nocleanup[] =
N_("\nWrite a message for tag:\n %s\n"
"Lines starting with '%c' will be kept; you may remove them"
"Lines starting with '%s' will be kept; you may remove them"
" yourself if you want to.\n");

static int git_tag_config(const char *var, const char *value,
Expand Down Expand Up @@ -328,11 +328,11 @@ static void create_tag(const struct object_id *object, const char *object_ref,
struct strbuf buf = STRBUF_INIT;
strbuf_addch(&buf, '\n');
if (opt->cleanup_mode == CLEANUP_ALL)
strbuf_commented_addf(&buf, comment_line_char,
_(tag_template), tag, comment_line_char);
strbuf_commented_addf(&buf, comment_line_str,
_(tag_template), tag, comment_line_str);
else
strbuf_commented_addf(&buf, comment_line_char,
_(tag_template_nocleanup), tag, comment_line_char);
strbuf_commented_addf(&buf, comment_line_str,
_(tag_template_nocleanup), tag, comment_line_str);
write_or_die(fd, buf.buf, buf.len);
strbuf_release(&buf);
}
Expand All @@ -347,7 +347,7 @@ static void create_tag(const struct object_id *object, const char *object_ref,

if (opt->cleanup_mode != CLEANUP_NONE)
strbuf_stripspace(buf,
opt->cleanup_mode == CLEANUP_ALL ? comment_line_char : '\0');
opt->cleanup_mode == CLEANUP_ALL ? comment_line_str : NULL);

if (!opt->message_given && !buf->len)
die(_("no tag message?"));
Expand Down
2 changes: 1 addition & 1 deletion builtin/worktree.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ static int can_use_local_refs(const struct add_opts *opts)
strbuf_add_real_path(&path, get_worktree_git_dir(NULL));
strbuf_addstr(&path, "/HEAD");
strbuf_read_file(&contents, path.buf, 64);
strbuf_stripspace(&contents, 0);
strbuf_stripspace(&contents, NULL);
strbuf_strip_suffix(&contents, "\n");

warning(_("HEAD points to an invalid (or orphaned) reference.\n"
Expand Down
3 changes: 2 additions & 1 deletion commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,8 @@ size_t ignored_log_message_bytes(const char *buf, size_t len)
else
next_line++;

if (buf[bol] == comment_line_char || buf[bol] == '\n') {
if (starts_with_mem(buf + bol, cutoff - bol, comment_line_str) ||
buf[bol] == '\n') {
/* is this the first of the run of comments? */
if (!boc)
boc = bol;
Expand Down
11 changes: 7 additions & 4 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,16 +1565,19 @@ static int git_default_core_config(const char *var, const char *value,
if (!strcmp(var, "core.editor"))
return git_config_string(&editor_program, var, value);

if (!strcmp(var, "core.commentchar")) {
if (!strcmp(var, "core.commentchar") ||
!strcmp(var, "core.commentstring")) {
if (!value)
return config_error_nonbool(var);
else if (!strcasecmp(value, "auto"))
auto_comment_line_char = 1;
else if (value[0] && !value[1]) {
comment_line_char = value[0];
else if (value[0]) {
if (strchr(value, '\n'))
return error(_("%s cannot contain newline"), var);
comment_line_str = xstrdup(value);
auto_comment_line_char = 0;
} else
return error(_("core.commentChar should only be one ASCII character"));
return error(_("%s must have at least one character"), var);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ int protect_ntfs = PROTECT_NTFS_DEFAULT;
* The character that begins a commented line in user-editable file
* that is subject to stripspace.
*/
char comment_line_char = '#';
const char *comment_line_str = "#";
int auto_comment_line_char;

/* Parallel index stat data preload? */
Expand Down
2 changes: 1 addition & 1 deletion environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct strvec;
* The character that begins a commented line in user-editable file
* that is subject to stripspace.
*/
extern char comment_line_char;
extern const char *comment_line_str;
extern int auto_comment_line_char;

/*
Expand Down
Loading

0 comments on commit dce1e0b

Please sign in to comment.