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 <gitster@pobox.com> Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
44fe83502e
commit
eff80a9fd9
@ -528,6 +528,12 @@ core.editor::
|
|||||||
variable when it is set, and the environment variable
|
variable when it is set, and the environment variable
|
||||||
`GIT_EDITOR` is not set. See linkgit:git-var[1].
|
`GIT_EDITOR` is not set. See linkgit:git-var[1].
|
||||||
|
|
||||||
|
core.commentchar::
|
||||||
|
Commands such as `commit` and `tag` that lets you edit
|
||||||
|
messages consider a line that begins with this character
|
||||||
|
commented, and removes them after the editor returns
|
||||||
|
(default '#').
|
||||||
|
|
||||||
sequence.editor::
|
sequence.editor::
|
||||||
Text editor used by `git rebase -i` for editing the rebase insn file.
|
Text editor used by `git rebase -i` for editing the rebase insn file.
|
||||||
The value is meant to be interpreted by the shell when it is used.
|
The value is meant to be interpreted by the shell when it is used.
|
||||||
|
@ -35,7 +35,13 @@ OPTIONS
|
|||||||
-------
|
-------
|
||||||
-s::
|
-s::
|
||||||
--strip-comments::
|
--strip-comments::
|
||||||
Skip and remove all lines starting with '#'.
|
Skip and remove all lines starting with comment character (default '#').
|
||||||
|
|
||||||
|
-c::
|
||||||
|
--comment-lines::
|
||||||
|
Prepend comment character and blank to each line. Lines will automatically
|
||||||
|
be terminated with a newline. On empty lines, only the comment character
|
||||||
|
will be prepended.
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
--------
|
--------
|
||||||
|
@ -156,6 +156,11 @@ then they will free() it.
|
|||||||
Remove the bytes between `pos..pos+len` and replace it with the given
|
Remove the bytes between `pos..pos+len` and replace it with the given
|
||||||
data.
|
data.
|
||||||
|
|
||||||
|
`strbuf_add_commented_lines`::
|
||||||
|
|
||||||
|
Add a NUL-terminated string to the buffer. Each line will be prepended
|
||||||
|
by a comment character and a blank.
|
||||||
|
|
||||||
`strbuf_add`::
|
`strbuf_add`::
|
||||||
|
|
||||||
Add data of given length to the buffer.
|
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.
|
|||||||
|
|
||||||
Add a formatted string to the buffer.
|
Add a formatted string to the buffer.
|
||||||
|
|
||||||
|
`strbuf_commented_addf`::
|
||||||
|
|
||||||
|
Add a formatted string prepended by a comment character and a
|
||||||
|
blank to the buffer.
|
||||||
|
|
||||||
`strbuf_fread`::
|
`strbuf_fread`::
|
||||||
|
|
||||||
Read a given size of data from a FILE* pointer to the buffer.
|
Read a given size of data from a FILE* pointer to the buffer.
|
||||||
|
@ -706,11 +706,11 @@ static int edit_branch_description(const char *branch_name)
|
|||||||
read_branch_desc(&buf, branch_name);
|
read_branch_desc(&buf, branch_name);
|
||||||
if (!buf.len || buf.buf[buf.len-1] != '\n')
|
if (!buf.len || buf.buf[buf.len-1] != '\n')
|
||||||
strbuf_addch(&buf, '\n');
|
strbuf_addch(&buf, '\n');
|
||||||
strbuf_addf(&buf,
|
strbuf_commented_addf(&buf,
|
||||||
"# Please edit the description for the branch\n"
|
"Please edit the description for the branch\n"
|
||||||
"# %s\n"
|
" %s\n"
|
||||||
"# Lines starting with '#' will be stripped.\n",
|
"Lines starting with '%c' will be stripped.\n",
|
||||||
branch_name);
|
branch_name, comment_line_char);
|
||||||
fp = fopen(git_path(edit_description), "w");
|
fp = fopen(git_path(edit_description), "w");
|
||||||
if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
|
if ((fwrite(buf.buf, 1, buf.len, fp) < buf.len) || fclose(fp)) {
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
@ -733,15 +733,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
|||||||
if (cleanup_mode == CLEANUP_ALL)
|
if (cleanup_mode == CLEANUP_ALL)
|
||||||
status_printf(s, GIT_COLOR_NORMAL,
|
status_printf(s, GIT_COLOR_NORMAL,
|
||||||
_("Please enter the commit message for your changes."
|
_("Please enter the commit message for your changes."
|
||||||
" Lines starting\nwith '#' will be ignored, and an empty"
|
" Lines starting\nwith '%c' will be ignored, and an empty"
|
||||||
" message aborts the commit.\n"));
|
" message aborts the commit.\n"), comment_line_char);
|
||||||
else /* CLEANUP_SPACE, that is. */
|
else /* CLEANUP_SPACE, that is. */
|
||||||
status_printf(s, GIT_COLOR_NORMAL,
|
status_printf(s, GIT_COLOR_NORMAL,
|
||||||
_("Please enter the commit message for your changes."
|
_("Please enter the commit message for your changes."
|
||||||
" Lines starting\n"
|
" Lines starting\n"
|
||||||
"with '#' will be kept; you may remove them"
|
"with '%c' will be kept; you may remove them"
|
||||||
" yourself if you want to.\n"
|
" yourself if you want to.\n"
|
||||||
"An empty message aborts the commit.\n"));
|
"An empty message aborts the commit.\n"), comment_line_char);
|
||||||
if (only_include_assumed)
|
if (only_include_assumed)
|
||||||
status_printf_ln(s, GIT_COLOR_NORMAL,
|
status_printf_ln(s, GIT_COLOR_NORMAL,
|
||||||
"%s", only_include_assumed);
|
"%s", only_include_assumed);
|
||||||
|
@ -464,7 +464,7 @@ static void fmt_tag_signature(struct strbuf *tagbuf,
|
|||||||
strbuf_complete_line(tagbuf);
|
strbuf_complete_line(tagbuf);
|
||||||
if (sig->len) {
|
if (sig->len) {
|
||||||
strbuf_addch(tagbuf, '\n');
|
strbuf_addch(tagbuf, '\n');
|
||||||
strbuf_add_lines(tagbuf, "# ", sig->buf, sig->len);
|
strbuf_add_commented_lines(tagbuf, sig->buf, sig->len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,17 +788,16 @@ static const char merge_editor_comment[] =
|
|||||||
N_("Please enter a commit message to explain why this merge is necessary,\n"
|
N_("Please enter a commit message to explain why this merge is necessary,\n"
|
||||||
"especially if it merges an updated upstream into a topic branch.\n"
|
"especially if it merges an updated upstream into a topic branch.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Lines starting with '#' will be ignored, and an empty message aborts\n"
|
"Lines starting with '%c' will be ignored, and an empty message aborts\n"
|
||||||
"the commit.\n");
|
"the commit.\n");
|
||||||
|
|
||||||
static void prepare_to_commit(struct commit_list *remoteheads)
|
static void prepare_to_commit(struct commit_list *remoteheads)
|
||||||
{
|
{
|
||||||
struct strbuf msg = STRBUF_INIT;
|
struct strbuf msg = STRBUF_INIT;
|
||||||
const char *comment = _(merge_editor_comment);
|
|
||||||
strbuf_addbuf(&msg, &merge_msg);
|
strbuf_addbuf(&msg, &merge_msg);
|
||||||
strbuf_addch(&msg, '\n');
|
strbuf_addch(&msg, '\n');
|
||||||
if (0 < option_edit)
|
if (0 < option_edit)
|
||||||
strbuf_add_lines(&msg, "# ", comment, strlen(comment));
|
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
|
||||||
write_merge_msg(&msg);
|
write_merge_msg(&msg);
|
||||||
if (run_hook(get_index_file(), "prepare-commit-msg",
|
if (run_hook(get_index_file(), "prepare-commit-msg",
|
||||||
git_path("MERGE_MSG"), "merge", NULL, NULL))
|
git_path("MERGE_MSG"), "merge", NULL, NULL))
|
||||||
|
@ -92,10 +92,7 @@ static const char * const git_notes_get_ref_usage[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char note_template[] =
|
static const char note_template[] =
|
||||||
"\n"
|
"\nWrite/edit the notes for the following object:\n";
|
||||||
"#\n"
|
|
||||||
"# Write/edit the notes for the following object:\n"
|
|
||||||
"#\n";
|
|
||||||
|
|
||||||
struct msg_arg {
|
struct msg_arg {
|
||||||
int given;
|
int given;
|
||||||
@ -129,7 +126,7 @@ static void write_commented_object(int fd, const unsigned char *object)
|
|||||||
{"show", "--stat", "--no-notes", sha1_to_hex(object), NULL};
|
{"show", "--stat", "--no-notes", sha1_to_hex(object), NULL};
|
||||||
struct child_process show;
|
struct child_process show;
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
FILE *show_out;
|
struct strbuf cbuf = STRBUF_INIT;
|
||||||
|
|
||||||
/* Invoke "git show --stat --no-notes $object" */
|
/* Invoke "git show --stat --no-notes $object" */
|
||||||
memset(&show, 0, sizeof(show));
|
memset(&show, 0, sizeof(show));
|
||||||
@ -142,21 +139,14 @@ static void write_commented_object(int fd, const unsigned char *object)
|
|||||||
die(_("unable to start 'show' for object '%s'"),
|
die(_("unable to start 'show' for object '%s'"),
|
||||||
sha1_to_hex(object));
|
sha1_to_hex(object));
|
||||||
|
|
||||||
/* Open the output as FILE* so strbuf_getline() can be used. */
|
if (strbuf_read(&buf, show.out, 0) < 0)
|
||||||
show_out = xfdopen(show.out, "r");
|
die_errno(_("could not read 'show' output"));
|
||||||
if (show_out == NULL)
|
strbuf_add_commented_lines(&cbuf, buf.buf, buf.len);
|
||||||
die_errno(_("can't fdopen 'show' output fd"));
|
write_or_die(fd, cbuf.buf, cbuf.len);
|
||||||
|
|
||||||
/* Prepend "# " to each output line and write result to 'fd' */
|
strbuf_release(&cbuf);
|
||||||
while (strbuf_getline(&buf, show_out, '\n') != EOF) {
|
|
||||||
write_or_die(fd, "# ", 2);
|
|
||||||
write_or_die(fd, buf.buf, buf.len);
|
|
||||||
write_or_die(fd, "\n", 1);
|
|
||||||
}
|
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
if (fclose(show_out))
|
|
||||||
die_errno(_("failed to close pipe to 'show' for object '%s'"),
|
|
||||||
sha1_to_hex(object));
|
|
||||||
if (finish_command(&show))
|
if (finish_command(&show))
|
||||||
die(_("failed to finish 'show' for object '%s'"),
|
die(_("failed to finish 'show' for object '%s'"),
|
||||||
sha1_to_hex(object));
|
sha1_to_hex(object));
|
||||||
@ -170,6 +160,7 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
|
|||||||
|
|
||||||
if (msg->use_editor || !msg->given) {
|
if (msg->use_editor || !msg->given) {
|
||||||
int fd;
|
int fd;
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
|
||||||
/* write the template message before editing: */
|
/* write the template message before editing: */
|
||||||
path = git_pathdup("NOTES_EDITMSG");
|
path = git_pathdup("NOTES_EDITMSG");
|
||||||
@ -181,11 +172,16 @@ static void create_note(const unsigned char *object, struct msg_arg *msg,
|
|||||||
write_or_die(fd, msg->buf.buf, msg->buf.len);
|
write_or_die(fd, msg->buf.buf, msg->buf.len);
|
||||||
else if (prev && !append_only)
|
else if (prev && !append_only)
|
||||||
write_note_data(fd, prev);
|
write_note_data(fd, prev);
|
||||||
write_or_die(fd, note_template, strlen(note_template));
|
|
||||||
|
strbuf_addch(&buf, '\n');
|
||||||
|
strbuf_add_commented_lines(&buf, note_template, strlen(note_template));
|
||||||
|
strbuf_addch(&buf, '\n');
|
||||||
|
write_or_die(fd, buf.buf, buf.len);
|
||||||
|
|
||||||
write_commented_object(fd, object);
|
write_commented_object(fd, object);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
strbuf_release(&buf);
|
||||||
strbuf_reset(&(msg->buf));
|
strbuf_reset(&(msg->buf));
|
||||||
|
|
||||||
if (launch_editor(path, &(msg->buf), NULL)) {
|
if (launch_editor(path, &(msg->buf), NULL)) {
|
||||||
|
@ -30,7 +30,8 @@ static size_t cleanup(char *line, size_t len)
|
|||||||
*
|
*
|
||||||
* If last line does not have a newline at the end, one is added.
|
* If last line does not have a newline at the end, one is added.
|
||||||
*
|
*
|
||||||
* Enable skip_comments to skip every line starting with "#".
|
* Enable skip_comments to skip every line starting with comment
|
||||||
|
* character.
|
||||||
*/
|
*/
|
||||||
void stripspace(struct strbuf *sb, int skip_comments)
|
void stripspace(struct strbuf *sb, int skip_comments)
|
||||||
{
|
{
|
||||||
@ -45,7 +46,7 @@ void stripspace(struct strbuf *sb, int skip_comments)
|
|||||||
eol = memchr(sb->buf + i, '\n', sb->len - i);
|
eol = memchr(sb->buf + i, '\n', sb->len - i);
|
||||||
len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
|
len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
|
||||||
|
|
||||||
if (skip_comments && len && sb->buf[i] == '#') {
|
if (skip_comments && len && sb->buf[i] == comment_line_char) {
|
||||||
newlen = 0;
|
newlen = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -66,21 +67,53 @@ void stripspace(struct strbuf *sb, int skip_comments)
|
|||||||
strbuf_setlen(sb, j);
|
strbuf_setlen(sb, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void comment_lines(struct strbuf *buf)
|
||||||
|
{
|
||||||
|
char *msg;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
msg = strbuf_detach(buf, &len);
|
||||||
|
strbuf_add_commented_lines(buf, msg, len);
|
||||||
|
free(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *usage_msg = "\n"
|
||||||
|
" git stripspace [-s | --strip-comments] < input\n"
|
||||||
|
" git stripspace [-c | --comment-lines] < input";
|
||||||
|
|
||||||
int cmd_stripspace(int argc, const char **argv, const char *prefix)
|
int cmd_stripspace(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
int strip_comments = 0;
|
int strip_comments = 0;
|
||||||
|
enum { INVAL = 0, STRIP_SPACE = 1, COMMENT_LINES = 2 } mode = STRIP_SPACE;
|
||||||
|
|
||||||
if (argc == 2 && (!strcmp(argv[1], "-s") ||
|
if (argc == 2) {
|
||||||
!strcmp(argv[1], "--strip-comments")))
|
if (!strcmp(argv[1], "-s") ||
|
||||||
strip_comments = 1;
|
!strcmp(argv[1], "--strip-comments")) {
|
||||||
else if (argc > 1)
|
strip_comments = 1;
|
||||||
usage("git stripspace [-s | --strip-comments] < input");
|
} else if (!strcmp(argv[1], "-c") ||
|
||||||
|
!strcmp(argv[1], "--comment-lines")) {
|
||||||
|
mode = COMMENT_LINES;
|
||||||
|
} else {
|
||||||
|
mode = INVAL;
|
||||||
|
}
|
||||||
|
} else if (argc > 1) {
|
||||||
|
mode = INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == INVAL)
|
||||||
|
usage(usage_msg);
|
||||||
|
|
||||||
|
if (strip_comments || mode == COMMENT_LINES)
|
||||||
|
git_config(git_default_config, NULL);
|
||||||
|
|
||||||
if (strbuf_read(&buf, 0, 1024) < 0)
|
if (strbuf_read(&buf, 0, 1024) < 0)
|
||||||
die_errno("could not read the input");
|
die_errno("could not read the input");
|
||||||
|
|
||||||
stripspace(&buf, strip_comments);
|
if (mode == STRIP_SPACE)
|
||||||
|
stripspace(&buf, strip_comments);
|
||||||
|
else
|
||||||
|
comment_lines(&buf);
|
||||||
|
|
||||||
write_or_die(1, buf.buf, buf.len);
|
write_or_die(1, buf.buf, buf.len);
|
||||||
strbuf_release(&buf);
|
strbuf_release(&buf);
|
||||||
|
@ -246,19 +246,13 @@ static int do_sign(struct strbuf *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char tag_template[] =
|
static const char tag_template[] =
|
||||||
N_("\n"
|
N_("\nWrite a tag message\n"
|
||||||
"#\n"
|
"Lines starting with '%c' will be ignored.\n");
|
||||||
"# Write a tag message\n"
|
|
||||||
"# Lines starting with '#' will be ignored.\n"
|
|
||||||
"#\n");
|
|
||||||
|
|
||||||
static const char tag_template_nocleanup[] =
|
static const char tag_template_nocleanup[] =
|
||||||
N_("\n"
|
N_("\nWrite a tag message\n"
|
||||||
"#\n"
|
"Lines starting with '%c' will be kept; you may remove them"
|
||||||
"# Write a tag message\n"
|
" yourself if you want to.\n");
|
||||||
"# Lines starting with '#' will be kept; you may remove them"
|
|
||||||
" yourself if you want to.\n"
|
|
||||||
"#\n");
|
|
||||||
|
|
||||||
static int git_tag_config(const char *var, const char *value, void *cb)
|
static int git_tag_config(const char *var, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
@ -346,14 +340,18 @@ static void create_tag(const unsigned char *object, const char *tag,
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
die_errno(_("could not create file '%s'"), path);
|
die_errno(_("could not create file '%s'"), path);
|
||||||
|
|
||||||
if (!is_null_sha1(prev))
|
if (!is_null_sha1(prev)) {
|
||||||
write_tag_body(fd, prev);
|
write_tag_body(fd, prev);
|
||||||
else if (opt->cleanup_mode == CLEANUP_ALL)
|
} else {
|
||||||
write_or_die(fd, _(tag_template),
|
struct strbuf buf = STRBUF_INIT;
|
||||||
strlen(_(tag_template)));
|
strbuf_addch(&buf, '\n');
|
||||||
else
|
if (opt->cleanup_mode == CLEANUP_ALL)
|
||||||
write_or_die(fd, _(tag_template_nocleanup),
|
strbuf_commented_addf(&buf, _(tag_template), comment_line_char);
|
||||||
strlen(_(tag_template_nocleanup)));
|
else
|
||||||
|
strbuf_commented_addf(&buf, _(tag_template_nocleanup), comment_line_char);
|
||||||
|
write_or_die(fd, buf.buf, buf.len);
|
||||||
|
strbuf_release(&buf);
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (launch_editor(path, buf, NULL)) {
|
if (launch_editor(path, buf, NULL)) {
|
||||||
|
6
cache.h
6
cache.h
@ -562,6 +562,12 @@ extern int core_preload_index;
|
|||||||
extern int core_apply_sparse_checkout;
|
extern int core_apply_sparse_checkout;
|
||||||
extern int precomposed_unicode;
|
extern int precomposed_unicode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The character that begins a commented line in user-editable file
|
||||||
|
* that is subject to stripspace.
|
||||||
|
*/
|
||||||
|
extern char comment_line_char;
|
||||||
|
|
||||||
enum branch_track {
|
enum branch_track {
|
||||||
BRANCH_TRACK_UNSPECIFIED = -1,
|
BRANCH_TRACK_UNSPECIFIED = -1,
|
||||||
BRANCH_TRACK_NEVER = 0,
|
BRANCH_TRACK_NEVER = 0,
|
||||||
|
8
config.c
8
config.c
@ -717,6 +717,14 @@ static int git_default_core_config(const char *var, const char *value)
|
|||||||
if (!strcmp(var, "core.editor"))
|
if (!strcmp(var, "core.editor"))
|
||||||
return git_config_string(&editor_program, var, value);
|
return git_config_string(&editor_program, var, value);
|
||||||
|
|
||||||
|
if (!strcmp(var, "core.commentchar")) {
|
||||||
|
const char *comment;
|
||||||
|
int ret = git_config_string(&comment, var, value);
|
||||||
|
if (!ret)
|
||||||
|
comment_line_char = comment[0];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(var, "core.askpass"))
|
if (!strcmp(var, "core.askpass"))
|
||||||
return git_config_string(&askpass_program, var, value);
|
return git_config_string(&askpass_program, var, value);
|
||||||
|
|
||||||
|
@ -62,6 +62,12 @@ int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
|
|||||||
struct startup_info *startup_info;
|
struct startup_info *startup_info;
|
||||||
unsigned long pack_size_limit_cfg;
|
unsigned long pack_size_limit_cfg;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The character that begins a commented line in user-editable file
|
||||||
|
* that is subject to stripspace.
|
||||||
|
*/
|
||||||
|
char comment_line_char = '#';
|
||||||
|
|
||||||
/* Parallel index stat data preload? */
|
/* Parallel index stat data preload? */
|
||||||
int core_preload_index = 0;
|
int core_preload_index = 0;
|
||||||
|
|
||||||
|
@ -976,12 +976,12 @@ cmd_summary() {
|
|||||||
done |
|
done |
|
||||||
if test -n "$for_status"; then
|
if test -n "$for_status"; then
|
||||||
if [ -n "$files" ]; then
|
if [ -n "$files" ]; then
|
||||||
gettextln "# Submodules changed but not updated:"
|
gettextln "Submodules changed but not updated:" | git stripspace -c
|
||||||
else
|
else
|
||||||
gettextln "# Submodule changes to be committed:"
|
gettextln "Submodule changes to be committed:" | git stripspace -c
|
||||||
fi
|
fi
|
||||||
echo "#"
|
printf "\n" | git stripspace -c
|
||||||
sed -e 's|^|# |' -e 's|^# $|#|'
|
git stripspace -c
|
||||||
else
|
else
|
||||||
cat
|
cat
|
||||||
fi
|
fi
|
||||||
|
58
strbuf.c
58
strbuf.c
@ -204,6 +204,54 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_lines(struct strbuf *out,
|
||||||
|
const char *prefix1,
|
||||||
|
const char *prefix2,
|
||||||
|
const char *buf, size_t size)
|
||||||
|
{
|
||||||
|
while (size) {
|
||||||
|
const char *prefix;
|
||||||
|
const char *next = memchr(buf, '\n', size);
|
||||||
|
next = next ? (next + 1) : (buf + size);
|
||||||
|
|
||||||
|
prefix = (prefix2 && buf[0] == '\n') ? prefix2 : prefix1;
|
||||||
|
strbuf_addstr(out, prefix);
|
||||||
|
strbuf_add(out, buf, next - buf);
|
||||||
|
size -= next - buf;
|
||||||
|
buf = next;
|
||||||
|
}
|
||||||
|
strbuf_complete_line(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size)
|
||||||
|
{
|
||||||
|
static char prefix1[3];
|
||||||
|
static char prefix2[2];
|
||||||
|
|
||||||
|
if (prefix1[0] != comment_line_char) {
|
||||||
|
sprintf(prefix1, "%c ", comment_line_char);
|
||||||
|
sprintf(prefix2, "%c", comment_line_char);
|
||||||
|
}
|
||||||
|
add_lines(out, prefix1, prefix2, buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list params;
|
||||||
|
struct strbuf buf = STRBUF_INIT;
|
||||||
|
int incomplete_line = sb->len && sb->buf[sb->len - 1] != '\n';
|
||||||
|
|
||||||
|
va_start(params, fmt);
|
||||||
|
strbuf_vaddf(&buf, fmt, params);
|
||||||
|
va_end(params);
|
||||||
|
|
||||||
|
strbuf_add_commented_lines(sb, buf.buf, buf.len);
|
||||||
|
if (incomplete_line)
|
||||||
|
sb->buf[--sb->len] = '\0';
|
||||||
|
|
||||||
|
strbuf_release(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
|
void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -414,15 +462,7 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
|
|||||||
void strbuf_add_lines(struct strbuf *out, const char *prefix,
|
void strbuf_add_lines(struct strbuf *out, const char *prefix,
|
||||||
const char *buf, size_t size)
|
const char *buf, size_t size)
|
||||||
{
|
{
|
||||||
while (size) {
|
add_lines(out, prefix, NULL, buf, size);
|
||||||
const char *next = memchr(buf, '\n', size);
|
|
||||||
next = next ? (next + 1) : (buf + size);
|
|
||||||
strbuf_addstr(out, prefix);
|
|
||||||
strbuf_add(out, buf, next - buf);
|
|
||||||
size -= next - buf;
|
|
||||||
buf = next;
|
|
||||||
}
|
|
||||||
strbuf_complete_line(out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
|
void strbuf_addstr_xml_quoted(struct strbuf *buf, const char *s)
|
||||||
|
4
strbuf.h
4
strbuf.h
@ -110,6 +110,8 @@ extern void strbuf_remove(struct strbuf *, size_t pos, size_t len);
|
|||||||
extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
|
extern void strbuf_splice(struct strbuf *, size_t pos, size_t len,
|
||||||
const void *, size_t);
|
const void *, size_t);
|
||||||
|
|
||||||
|
extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size);
|
||||||
|
|
||||||
extern void strbuf_add(struct strbuf *, const void *, size_t);
|
extern void strbuf_add(struct strbuf *, const void *, size_t);
|
||||||
static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
|
static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
|
||||||
strbuf_add(sb, s, strlen(s));
|
strbuf_add(sb, s, strlen(s));
|
||||||
@ -131,6 +133,8 @@ extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *
|
|||||||
|
|
||||||
__attribute__((format (printf,2,3)))
|
__attribute__((format (printf,2,3)))
|
||||||
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
|
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
|
||||||
|
__attribute__((format (printf, 2, 3)))
|
||||||
|
extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...);
|
||||||
__attribute__((format (printf,2,0)))
|
__attribute__((format (printf,2,0)))
|
||||||
extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
|
extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
|
||||||
|
|
||||||
|
@ -397,4 +397,39 @@ test_expect_success 'strip comments, too' '
|
|||||||
test -z "$(echo "# comment" | git stripspace -s)"
|
test -z "$(echo "# comment" | git stripspace -s)"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'strip comments with changed comment char' '
|
||||||
|
test ! -z "$(echo "; comment" | git -c core.commentchar=";" stripspace)" &&
|
||||||
|
test -z "$(echo "; comment" | git -c core.commentchar=";" stripspace -s)"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '-c with single line' '
|
||||||
|
printf "# foo\n" >expect &&
|
||||||
|
printf "foo" | git stripspace -c >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '-c with single line followed by empty line' '
|
||||||
|
printf "# foo\n#\n" >expect &&
|
||||||
|
printf "foo\n\n" | git stripspace -c >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '-c with newline only' '
|
||||||
|
printf "#\n" >expect &&
|
||||||
|
printf "\n" | git stripspace -c >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--comment-lines with single line' '
|
||||||
|
printf "# foo\n" >expect &&
|
||||||
|
printf "foo" | git stripspace -c >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '-c with changed comment char' '
|
||||||
|
printf "; foo\n" >expect &&
|
||||||
|
printf "foo" | git -c core.commentchar=";" stripspace -c >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -447,4 +447,11 @@ use_template="-t template"
|
|||||||
|
|
||||||
try_commit_status_combo
|
try_commit_status_combo
|
||||||
|
|
||||||
|
test_expect_success 'commit --status with custom comment character' '
|
||||||
|
test_when_finished "git config --unset core.commentchar" &&
|
||||||
|
git config core.commentchar ";" &&
|
||||||
|
try_commit --status &&
|
||||||
|
test_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
@ -1253,6 +1253,56 @@ test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary
|
|||||||
git config -f .gitmodules --remove-section submodule.subname
|
git config -f .gitmodules --remove-section submodule.subname
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat > expect << EOF
|
||||||
|
; On branch master
|
||||||
|
; Changes to be committed:
|
||||||
|
; (use "git reset HEAD <file>..." to unstage)
|
||||||
|
;
|
||||||
|
; modified: sm
|
||||||
|
;
|
||||||
|
; Changes not staged for commit:
|
||||||
|
; (use "git add <file>..." to update what will be committed)
|
||||||
|
; (use "git checkout -- <file>..." to discard changes in working directory)
|
||||||
|
;
|
||||||
|
; modified: dir1/modified
|
||||||
|
; modified: sm (new commits)
|
||||||
|
;
|
||||||
|
; Submodule changes to be committed:
|
||||||
|
;
|
||||||
|
; * sm $head...$new_head (1):
|
||||||
|
; > Add bar
|
||||||
|
;
|
||||||
|
; Submodules changed but not updated:
|
||||||
|
;
|
||||||
|
; * sm $new_head...$head2 (1):
|
||||||
|
; > 2nd commit
|
||||||
|
;
|
||||||
|
; Untracked files:
|
||||||
|
; (use "git add <file>..." to include in what will be committed)
|
||||||
|
;
|
||||||
|
; .gitmodules
|
||||||
|
; dir1/untracked
|
||||||
|
; dir2/modified
|
||||||
|
; dir2/untracked
|
||||||
|
; expect
|
||||||
|
; output
|
||||||
|
; untracked
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success "status (core.commentchar with submodule summary)" '
|
||||||
|
test_when_finished "git config --unset core.commentchar" &&
|
||||||
|
git config core.commentchar ";" &&
|
||||||
|
git status >output &&
|
||||||
|
test_i18ncmp expect output
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success "status (core.commentchar with two chars with submodule summary)" '
|
||||||
|
test_when_finished "git config --unset core.commentchar" &&
|
||||||
|
git config core.commentchar ";;" &&
|
||||||
|
git status >output &&
|
||||||
|
test_i18ncmp expect output
|
||||||
|
'
|
||||||
|
|
||||||
cat > expect << EOF
|
cat > expect << EOF
|
||||||
# On branch master
|
# On branch master
|
||||||
# Changes not staged for commit:
|
# Changes not staged for commit:
|
||||||
|
10
wt-status.c
10
wt-status.c
@ -45,7 +45,7 @@ static void status_vprintf(struct wt_status *s, int at_bol, const char *color,
|
|||||||
|
|
||||||
strbuf_vaddf(&sb, fmt, ap);
|
strbuf_vaddf(&sb, fmt, ap);
|
||||||
if (!sb.len) {
|
if (!sb.len) {
|
||||||
strbuf_addch(&sb, '#');
|
strbuf_addch(&sb, comment_line_char);
|
||||||
if (!trail)
|
if (!trail)
|
||||||
strbuf_addch(&sb, ' ');
|
strbuf_addch(&sb, ' ');
|
||||||
color_print_strbuf(s->fp, color, &sb);
|
color_print_strbuf(s->fp, color, &sb);
|
||||||
@ -59,7 +59,7 @@ static void status_vprintf(struct wt_status *s, int at_bol, const char *color,
|
|||||||
|
|
||||||
strbuf_reset(&linebuf);
|
strbuf_reset(&linebuf);
|
||||||
if (at_bol) {
|
if (at_bol) {
|
||||||
strbuf_addch(&linebuf, '#');
|
strbuf_addch(&linebuf, comment_line_char);
|
||||||
if (*line != '\n' && *line != '\t')
|
if (*line != '\n' && *line != '\t')
|
||||||
strbuf_addch(&linebuf, ' ');
|
strbuf_addch(&linebuf, ' ');
|
||||||
}
|
}
|
||||||
@ -760,8 +760,10 @@ static void wt_status_print_tracking(struct wt_status *s)
|
|||||||
|
|
||||||
for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
|
for (cp = sb.buf; (ep = strchr(cp, '\n')) != NULL; cp = ep + 1)
|
||||||
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
|
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s),
|
||||||
"# %.*s", (int)(ep - cp), cp);
|
"%c %.*s", comment_line_char,
|
||||||
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "#");
|
(int)(ep - cp), cp);
|
||||||
|
color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
|
||||||
|
comment_line_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int has_unmerged(struct wt_status *s)
|
static int has_unmerged(struct wt_status *s)
|
||||||
|
Loading…
Reference in New Issue
Block a user