1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-04-28 19:45:10 +02:00

Merge branch 'jk/core-comment-string' into next

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
This commit is contained in:
Junio C Hamano 2024-03-28 14:20:12 -07:00
commit fbf8eb9331
26 changed files with 182 additions and 136 deletions

View File

@ -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

View File

@ -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 "
@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -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);
@ -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,
@ -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);
@ -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) {
@ -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

View File

@ -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 *);
@ -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);

View File

@ -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);
@ -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);
@ -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);
}
}
@ -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);

View File

@ -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)))

View File

@ -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);
}
@ -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);

View File

@ -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,
@ -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);
}
@ -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?"));

View File

@ -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"

View File

@ -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;

View File

@ -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;
}

View File

@ -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? */

View File

@ -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;
/*

View File

@ -321,7 +321,7 @@ static void credit_people(struct strbuf *out,
skip_prefix(me, them->items->string, &me) &&
starts_with(me, " <")))
return;
strbuf_addf(out, "\n%c %s ", comment_line_char, label);
strbuf_addf(out, "\n%s %s ", comment_line_str, label);
add_people_count(out, them);
}
@ -510,7 +510,7 @@ static void fmt_tag_signature(struct strbuf *tagbuf,
if (sig->len) {
strbuf_addch(tagbuf, '\n');
strbuf_add_commented_lines(tagbuf, sig->buf, sig->len,
comment_line_char);
comment_line_str);
}
}
@ -557,7 +557,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
strbuf_add_commented_lines(&tagline,
origins.items[first_tag].string,
strlen(origins.items[first_tag].string),
comment_line_char);
comment_line_str);
strbuf_insert(&tagbuf, 0, tagline.buf,
tagline.len);
strbuf_release(&tagline);
@ -566,7 +566,7 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
strbuf_add_commented_lines(&tagbuf,
origins.items[i].string,
strlen(origins.items[i].string),
comment_line_char);
comment_line_str);
fmt_tag_signature(&tagbuf, &sig, buf, len);
}
strbuf_release(&payload);

View File

@ -586,8 +586,8 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
}
}
strbuf_stripspace(&ssh_keygen_out, '\0');
strbuf_stripspace(&ssh_keygen_err, '\0');
strbuf_stripspace(&ssh_keygen_out, NULL);
strbuf_stripspace(&ssh_keygen_err, NULL);
/* Add stderr outputs to show the user actual ssh-keygen errors */
strbuf_add(&ssh_keygen_out, ssh_principals_err.buf, ssh_principals_err.len);
strbuf_add(&ssh_keygen_out, ssh_keygen_err.buf, ssh_keygen_err.len);

View File

@ -71,14 +71,14 @@ void append_todo_help(int command_count,
if (!edit_todo) {
strbuf_addch(buf, '\n');
strbuf_commented_addf(buf, comment_line_char,
strbuf_commented_addf(buf, comment_line_str,
Q_("Rebase %s onto %s (%d command)",
"Rebase %s onto %s (%d commands)",
command_count),
shortrevisions, shortonto, command_count);
}
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_char);
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_str);
if (get_missing_commit_check_level() == MISSING_COMMIT_CHECK_ERROR)
msg = _("\nDo not remove any line. Use 'drop' "
@ -87,7 +87,7 @@ void append_todo_help(int command_count,
msg = _("\nIf you remove a line here "
"THAT COMMIT WILL BE LOST.\n");
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_char);
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_str);
if (edit_todo)
msg = _("\nYou are editing the todo file "
@ -98,7 +98,7 @@ void append_todo_help(int command_count,
msg = _("\nHowever, if you remove everything, "
"the rebase will be aborted.\n\n");
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_char);
strbuf_add_commented_lines(buf, msg, strlen(msg), comment_line_str);
}
int edit_todo_list(struct repository *r, struct todo_list *todo_list,
@ -130,7 +130,7 @@ int edit_todo_list(struct repository *r, struct todo_list *todo_list,
if (launch_sequence_editor(todo_file, &new_todo->buf, NULL))
return -2;
strbuf_stripspace(&new_todo->buf, comment_line_char);
strbuf_stripspace(&new_todo->buf, comment_line_str);
if (initial && new_todo->buf.len == 0)
return -3;

View File

@ -678,15 +678,15 @@ void append_conflicts_hint(struct index_state *istate,
if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {
strbuf_addch(msgbuf, '\n');
wt_status_append_cut_line(msgbuf);
strbuf_addch(msgbuf, comment_line_char);
strbuf_addstr(msgbuf, comment_line_str);
}
strbuf_addch(msgbuf, '\n');
strbuf_commented_addf(msgbuf, comment_line_char, "Conflicts:\n");
strbuf_commented_addf(msgbuf, comment_line_str, "Conflicts:\n");
for (i = 0; i < istate->cache_nr;) {
const struct cache_entry *ce = istate->cache[i++];
if (ce_stage(ce)) {
strbuf_commented_addf(msgbuf, comment_line_char,
strbuf_commented_addf(msgbuf, comment_line_str,
"\t%s\n", ce->name);
while (i < istate->cache_nr &&
!strcmp(ce->name, istate->cache[i]->name))
@ -1169,7 +1169,7 @@ void cleanup_message(struct strbuf *msgbuf,
strbuf_setlen(msgbuf, wt_status_locate_end(msgbuf->buf, msgbuf->len));
if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE)
strbuf_stripspace(msgbuf,
cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);
}
/*
@ -1201,7 +1201,7 @@ int template_untouched(const struct strbuf *sb, const char *template_file,
return 0;
strbuf_stripspace(&tmpl,
cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);
if (!skip_prefix(sb->buf, tmpl.buf, &start))
start = sb->buf;
strbuf_release(&tmpl);
@ -1574,7 +1574,7 @@ static int try_to_commit(struct repository *r,
if (cleanup != COMMIT_MSG_CLEANUP_NONE)
strbuf_stripspace(msg,
cleanup == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
cleanup == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);
if ((flags & EDIT_MSG) && message_is_empty(msg, cleanup)) {
res = 1; /* run 'git commit' to display error message */
goto out;
@ -1796,6 +1796,8 @@ static const char *command_to_string(const enum todo_command command)
{
if (command < TODO_COMMENT)
return todo_command_info[command].str;
if (command == TODO_COMMENT)
return comment_line_str;
die(_("unknown command: %d"), command);
}
@ -1803,7 +1805,7 @@ static char command_to_char(const enum todo_command command)
{
if (command < TODO_COMMENT)
return todo_command_info[command].c;
return comment_line_char;
return 0;
}
static int is_noop(const enum todo_command command)
@ -1857,7 +1859,7 @@ static int is_fixup_flag(enum todo_command command, unsigned flag)
static void add_commented_lines(struct strbuf *buf, const void *str, size_t len)
{
const char *s = str;
while (len > 0 && s[0] == comment_line_char) {
while (starts_with_mem(s, len, comment_line_str)) {
size_t count;
const char *n = memchr(s, '\n', len);
if (!n)
@ -1868,7 +1870,7 @@ static void add_commented_lines(struct strbuf *buf, const void *str, size_t len)
s += count;
len -= count;
}
strbuf_add_commented_lines(buf, s, len, comment_line_char);
strbuf_add_commented_lines(buf, s, len, comment_line_str);
}
/* Does the current fixup chain contain a squash command? */
@ -1963,11 +1965,11 @@ static int append_squash_message(struct strbuf *buf, const char *body,
(starts_with(body, "squash!") || starts_with(body, "fixup!"))))
commented_len = commit_subject_length(body);
strbuf_addf(buf, "\n%c ", comment_line_char);
strbuf_addf(buf, "\n%s ", comment_line_str);
strbuf_addf(buf, _(nth_commit_msg_fmt),
++opts->current_fixup_count + 1);
strbuf_addstr(buf, "\n\n");
strbuf_add_commented_lines(buf, body, commented_len, comment_line_char);
strbuf_add_commented_lines(buf, body, commented_len, comment_line_str);
/* buf->buf may be reallocated so store an offset into the buffer */
fixup_off = buf->len;
strbuf_addstr(buf, body + commented_len);
@ -2020,10 +2022,10 @@ static int update_squash_messages(struct repository *r,
return error(_("could not read '%s'"),
rebase_path_squash_msg());
eol = buf.buf[0] != comment_line_char ?
eol = !starts_with(buf.buf, comment_line_str) ?
buf.buf : strchrnul(buf.buf, '\n');
strbuf_addf(&header, "%c ", comment_line_char);
strbuf_addf(&header, "%s ", comment_line_str);
strbuf_addf(&header, _(combined_commit_msg_fmt),
opts->current_fixup_count + 2);
strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);
@ -2049,16 +2051,16 @@ static int update_squash_messages(struct repository *r,
repo_unuse_commit_buffer(r, head_commit, head_message);
return error(_("cannot write '%s'"), rebase_path_fixup_msg());
}
strbuf_addf(&buf, "%c ", comment_line_char);
strbuf_addf(&buf, "%s ", comment_line_str);
strbuf_addf(&buf, _(combined_commit_msg_fmt), 2);
strbuf_addf(&buf, "\n%c ", comment_line_char);
strbuf_addf(&buf, "\n%s ", comment_line_str);
strbuf_addstr(&buf, is_fixup_flag(command, flag) ?
_(skip_first_commit_msg_str) :
_(first_commit_msg_str));
strbuf_addstr(&buf, "\n\n");
if (is_fixup_flag(command, flag))
strbuf_add_commented_lines(&buf, body, strlen(body),
comment_line_char);
comment_line_str);
else
strbuf_addstr(&buf, body);
@ -2073,12 +2075,12 @@ static int update_squash_messages(struct repository *r,
if (command == TODO_SQUASH || is_fixup_flag(command, flag)) {
res = append_squash_message(&buf, body, command, opts, flag);
} else if (command == TODO_FIXUP) {
strbuf_addf(&buf, "\n%c ", comment_line_char);
strbuf_addf(&buf, "\n%s ", comment_line_str);
strbuf_addf(&buf, _(skip_nth_commit_msg_fmt),
++opts->current_fixup_count + 1);
strbuf_addstr(&buf, "\n\n");
strbuf_add_commented_lines(&buf, body, strlen(body),
comment_line_char);
comment_line_str);
} else
return error(_("unknown command: %d"), command);
repo_unuse_commit_buffer(r, commit, message);
@ -2579,7 +2581,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
/* left-trim */
bol += strspn(bol, " \t");
if (bol == eol || *bol == '\r' || *bol == comment_line_char) {
if (bol == eol || *bol == '\r' || starts_with_mem(bol, eol - bol, comment_line_str)) {
item->command = TODO_COMMENT;
item->commit = NULL;
item->arg_offset = bol - buf;
@ -5682,8 +5684,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,
oid_to_hex(&commit->object.oid),
oneline.buf);
if (is_empty)
strbuf_addf(&buf, " %c empty",
comment_line_char);
strbuf_addf(&buf, " %s empty",
comment_line_str);
FLEX_ALLOC_STR(entry, string, buf.buf);
oidcpy(&entry->entry.oid, &commit->object.oid);
@ -5773,7 +5775,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
entry = oidmap_get(&state.commit2label, &commit->object.oid);
if (entry)
strbuf_addf(out, "\n%c Branch %s\n", comment_line_char, entry->string);
strbuf_addf(out, "\n%s Branch %s\n", comment_line_str, entry->string);
else
strbuf_addch(out, '\n');
@ -5910,7 +5912,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
oid_to_hex(&commit->object.oid));
pretty_print_commit(&pp, commit, out);
if (is_empty)
strbuf_addf(out, " %c empty", comment_line_char);
strbuf_addf(out, " %s empty", comment_line_str);
strbuf_addch(out, '\n');
}
if (skipped_commit)

View File

@ -24,6 +24,17 @@ int istarts_with(const char *str, const char *prefix)
return 0;
}
int starts_with_mem(const char *str, size_t len, const char *prefix)
{
const char *end = str + len;
for (; ; str++, prefix++) {
if (!*prefix)
return 1;
else if (str == end || *str != *prefix)
return 0;
}
}
int skip_to_optional_arg_default(const char *str, const char *prefix,
const char **arg, const char *def)
{
@ -340,18 +351,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
}
static void add_lines(struct strbuf *out,
const char *prefix1,
const char *prefix2,
const char *buf, size_t size)
const char *prefix,
const char *buf, size_t size,
int space_after_prefix)
{
while (size) {
const char *prefix;
const char *next = memchr(buf, '\n', size);
next = next ? (next + 1) : (buf + size);
prefix = ((prefix2 && (buf[0] == '\n' || buf[0] == '\t'))
? prefix2 : prefix1);
strbuf_addstr(out, prefix);
if (space_after_prefix && buf[0] != '\n' && buf[0] != '\t')
strbuf_addch(out, ' ');
strbuf_add(out, buf, next - buf);
size -= next - buf;
buf = next;
@ -360,19 +370,12 @@ static void add_lines(struct strbuf *out,
}
void strbuf_add_commented_lines(struct strbuf *out, const char *buf,
size_t size, char comment_line_char)
size_t size, const char *comment_prefix)
{
static char prefix1[3];
static char prefix2[2];
if (prefix1[0] != comment_line_char) {
xsnprintf(prefix1, sizeof(prefix1), "%c ", comment_line_char);
xsnprintf(prefix2, sizeof(prefix2), "%c", comment_line_char);
}
add_lines(out, prefix1, prefix2, buf, size);
add_lines(out, comment_prefix, buf, size, 1);
}
void strbuf_commented_addf(struct strbuf *sb, char comment_line_char,
void strbuf_commented_addf(struct strbuf *sb, const char *comment_prefix,
const char *fmt, ...)
{
va_list params;
@ -383,7 +386,7 @@ void strbuf_commented_addf(struct strbuf *sb, char comment_line_char,
strbuf_vaddf(&buf, fmt, params);
va_end(params);
strbuf_add_commented_lines(sb, buf.buf, buf.len, comment_line_char);
strbuf_add_commented_lines(sb, buf.buf, buf.len, comment_prefix);
if (incomplete_line)
sb->buf[--sb->len] = '\0';
@ -770,7 +773,7 @@ ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
void strbuf_add_lines(struct strbuf *out, const char *prefix,
const char *buf, size_t size)
{
add_lines(out, prefix, NULL, buf, size);
add_lines(out, prefix, buf, size, 0);
}
void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
@ -1025,10 +1028,10 @@ static size_t cleanup(char *line, size_t len)
*
* If last line does not have a newline at the end, one is added.
*
* Pass a non-NUL comment_line_char to skip every line starting
* Pass a non-NULL comment_prefix to skip every line starting
* with it.
*/
void strbuf_stripspace(struct strbuf *sb, char comment_line_char)
void strbuf_stripspace(struct strbuf *sb, const char *comment_prefix)
{
size_t empties = 0;
size_t i, j, len, newlen;
@ -1041,8 +1044,8 @@ void strbuf_stripspace(struct strbuf *sb, char comment_line_char)
eol = memchr(sb->buf + i, '\n', sb->len - i);
len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
if (comment_line_char && len &&
sb->buf[i] == comment_line_char) {
if (comment_prefix && len &&
starts_with(sb->buf + i, comment_prefix)) {
newlen = 0;
continue;
}

View File

@ -288,7 +288,7 @@ void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
*/
void strbuf_add_commented_lines(struct strbuf *out,
const char *buf, size_t size,
char comment_line_char);
const char *comment_prefix);
/**
@ -384,7 +384,7 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
* blank to the buffer.
*/
__attribute__((format (printf, 3, 4)))
void strbuf_commented_addf(struct strbuf *sb, char comment_line_char, const char *fmt, ...);
void strbuf_commented_addf(struct strbuf *sb, const char *comment_prefix, const char *fmt, ...);
__attribute__((format (printf,2,0)))
void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
@ -518,11 +518,11 @@ int strbuf_getcwd(struct strbuf *sb);
int strbuf_normalize_path(struct strbuf *sb);
/**
* Strip whitespace from a buffer. If comment_line_char is non-NUL,
* Strip whitespace from a buffer. If comment_prefix is non-NULL,
* then lines beginning with that character are considered comments,
* thus removed.
*/
void strbuf_stripspace(struct strbuf *buf, char comment_line_char);
void strbuf_stripspace(struct strbuf *buf, const char *comment_prefix);
static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix)
{
@ -678,6 +678,7 @@ char *xstrfmt(const char *fmt, ...);
int starts_with(const char *str, const char *prefix);
int istarts_with(const char *str, const char *prefix);
int starts_with_mem(const char *str, size_t len, const char *prefix);
/*
* If the string "str" is the same as the string in "prefix", then the "arg"

View File

@ -401,6 +401,21 @@ test_expect_success 'strip comments with changed comment char' '
test -z "$(echo "; comment" | git -c core.commentchar=";" stripspace -s)"
'
test_expect_success 'strip comments with changed comment string' '
test ! -z "$(echo "// comment" | git -c core.commentchar=// stripspace)" &&
test -z "$(echo "// comment" | git -c core.commentchar="//" stripspace -s)"
'
test_expect_success 'newline as commentchar is forbidden' '
test_must_fail git -c core.commentChar="$LF" stripspace -s 2>err &&
grep "core.commentchar cannot contain newline" err
'
test_expect_success 'empty commentchar is forbidden' '
test_must_fail git -c core.commentchar= stripspace -s 2>err &&
grep "core.commentchar must have at least one character" err
'
test_expect_success '-c with single line' '
printf "# foo\n" >expect &&
printf "foo" | git stripspace -c >actual &&

View File

@ -101,6 +101,16 @@ test_expect_success 'verbose diff is stripped out with set core.commentChar' '
test_grep "Aborting commit due to empty commit message." err
'
test_expect_success 'verbose diff is stripped with multi-byte comment char' '
(
GIT_EDITOR=cat &&
export GIT_EDITOR &&
test_must_fail git -c core.commentchar="foo>" commit -a -v >out 2>err
) &&
grep "^foo> " out &&
test_grep "Aborting commit due to empty commit message." err
'
test_expect_success 'status does not verbose without --verbose' '
git status >actual &&
! grep "^diff --git" actual

View File

@ -1415,7 +1415,9 @@ 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 ";;" &&
test_must_fail git -c status.displayCommentPrefix=true status
sed "s/^/;/" <expect >expect.double &&
git -c status.displayCommentPrefix=true status >output &&
test_cmp expect.double output
'
test_expect_success "--ignore-submodules=all suppresses submodule summary" '

View File

@ -871,7 +871,7 @@ static size_t find_trailer_block_start(const char *buf, size_t len)
/* The first paragraph is the title and cannot be trailers */
for (s = buf; s < buf + len; s = next_line(s)) {
if (s[0] == comment_line_char)
if (starts_with_mem(s, buf + len - s, comment_line_str))
continue;
if (is_blank_line(s))
break;
@ -891,7 +891,7 @@ static size_t find_trailer_block_start(const char *buf, size_t len)
const char **p;
ssize_t separator_pos;
if (bol[0] == comment_line_char) {
if (starts_with_mem(bol, buf + len - bol, comment_line_str)) {
non_trailer_lines += possible_continuation_lines;
possible_continuation_lines = 0;
continue;
@ -1002,7 +1002,7 @@ void parse_trailers(const struct process_trailer_options *opts,
for (i = 0; i < info->trailer_nr; i++) {
int separator_pos;
char *trailer = info->trailers[i];
if (trailer[0] == comment_line_char)
if (starts_with(trailer, comment_line_str))
continue;
separator_pos = find_separator(trailer, separators);
if (separator_pos >= 1) {

View File

@ -70,7 +70,7 @@ static void status_vprintf(struct wt_status *s, int at_bol, const char *color,
strbuf_vaddf(&sb, fmt, ap);
if (!sb.len) {
if (s->display_comment_prefix) {
strbuf_addch(&sb, comment_line_char);
strbuf_addstr(&sb, comment_line_str);
if (!trail)
strbuf_addch(&sb, ' ');
}
@ -85,7 +85,7 @@ static void status_vprintf(struct wt_status *s, int at_bol, const char *color,
strbuf_reset(&linebuf);
if (at_bol && s->display_comment_prefix) {
strbuf_addch(&linebuf, comment_line_char);
strbuf_addstr(&linebuf, comment_line_str);
if (*line != '\n' && *line != '\t')
strbuf_addch(&linebuf, ' ');
}
@ -1028,7 +1028,7 @@ static void wt_longstatus_print_submodule_summary(struct wt_status *s, int uncom
if (s->display_comment_prefix) {
size_t len;
summary_content = strbuf_detach(&summary, &len);
strbuf_add_commented_lines(&summary, summary_content, len, comment_line_char);
strbuf_add_commented_lines(&summary, summary_content, len, comment_line_str);
free(summary_content);
}
@ -1090,7 +1090,7 @@ size_t wt_status_locate_end(const char *s, size_t len)
const char *p;
struct strbuf pattern = STRBUF_INIT;
strbuf_addf(&pattern, "\n%c %s", comment_line_char, cut_line);
strbuf_addf(&pattern, "\n%s %s", comment_line_str, cut_line);
if (starts_with(s, pattern.buf + 1))
len = 0;
else if ((p = strstr(s, pattern.buf))) {
@ -1106,8 +1106,8 @@ void wt_status_append_cut_line(struct strbuf *buf)
{
const char *explanation = _("Do not modify or remove the line above.\nEverything below it will be ignored.");
strbuf_commented_addf(buf, comment_line_char, "%s", cut_line);
strbuf_add_commented_lines(buf, explanation, strlen(explanation), comment_line_char);
strbuf_commented_addf(buf, comment_line_str, "%s", cut_line);
strbuf_add_commented_lines(buf, explanation, strlen(explanation), comment_line_str);
}
void wt_status_add_cut_line(struct wt_status *s)
@ -1183,8 +1183,6 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
struct strbuf sb = STRBUF_INIT;
const char *cp, *ep, *branch_name;
struct branch *branch;
char comment_line_string[3];
int i;
uint64_t t_begin = 0;
assert(s->branch && !s->is_initial);
@ -1209,20 +1207,15 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
}
}
i = 0;
if (s->display_comment_prefix) {
comment_line_string[i++] = comment_line_char;
comment_line_string[i++] = ' ';
}
comment_line_string[i] = '\0';
for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
"%s%.*s", comment_line_string,
"%s%s%.*s",
s->display_comment_prefix ? comment_line_str : "",
s->display_comment_prefix ? " " : "",
(int)(ep - cp), cp);
if (s->display_comment_prefix)
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
comment_line_char);
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%s",
comment_line_str);
else
fputs("\n", s->fp);
strbuf_release(&sb);
@ -1389,7 +1382,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
git_path("%s", fname));
}
while (!strbuf_getline_lf(&line, f)) {
if (line.len && line.buf[0] == comment_line_char)
if (starts_with(line.buf, comment_line_str))
continue;
strbuf_trim(&line);
if (!line.len)