Skip to content

Commit

Permalink
notes.c: introduce "--[no-]stripspace" option
Browse files Browse the repository at this point in the history
This commit introduces a new option "--[no-]stripspace" to git notes
append, git notes edit, and git notes add. This option allows users to
control whether the note message need to stripped out.

For the consideration of backward compatibility, let's look at the
behavior about "stripspace" in "git notes" command:

1. "Edit Message" case: using the default editor to edit the note
message.

    In "edit" case, the edited message will always be stripped out, the
    implementation which can be found in the "prepare_note_data()". In
    addition, the "-c" option supports to reuse an existing blob as a
    note message, then open the editor to make a further edition on it,
    the edited message will be stripped.

    This commit doesn't change the default behavior of "edit" case by
    using an enum "notes_stripspace", only when "--no-stripspace" option
    is specified, the note message will not be stripped out. If you do
    not specify the option or you specify "--stripspace", clearly, the
    note message will be stripped out.

2. "Assign Message" case: using the "-m"/"-F"/"-C" option to specify the
note message.

    In "assign" case, when specify message by "-m" or "-F", the message
    will be stripped out by default, but when specify message by "-C",
    the message will be copied verbatim, in other word, the message will
    not be stripped out. One more thing need to note is "the order of
    the options matter", that is, if you specify "-C" before "-m" or
    "-F", the reused message by "-C" will be stripped out together,
    because everytime concat "-m" or "-F" message, the concated message
    will be stripped together. Oppositely, if you specify "-m" or "-F"
    before "-C", the reused message by "-C" will not be stripped out.

    This commit doesn't change the default behavior of "assign" case by
    extending the "stripspace" field in "struct note_msg", so we can
    distinguish the different behavior of "-m"/"-F" and "-C" options
    when we need to parse and concat the message.

Signed-off-by: Teng Long <dyroneteng@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
dyrone authored and gitster committed Jun 21, 2023
1 parent b7d87ad commit c4e2aa7
Show file tree
Hide file tree
Showing 3 changed files with 332 additions and 19 deletions.
25 changes: 19 additions & 6 deletions Documentation/git-notes.txt
Expand Up @@ -9,10 +9,10 @@ SYNOPSIS
--------
[verse]
'git notes' [list [<object>]]
'git notes' add [-f] [--allow-empty] [--separator=<paragraph-break>] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' add [-f] [--allow-empty] [--separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' copy [-f] ( --stdin | <from-object> [<to-object>] )
'git notes' append [--allow-empty] [--separator=<paragraph-break>] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' edit [--allow-empty] [<object>]
'git notes' append [--allow-empty] [--separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
'git notes' edit [--allow-empty] [<object>] [--[no-]stripspace]
'git notes' show [<object>]
'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>
'git notes' merge --commit [-v | -q]
Expand Down Expand Up @@ -141,20 +141,26 @@ OPTIONS
If multiple `-m` options are given, their values
are concatenated as separate paragraphs.
Lines starting with `#` and empty lines other than a
single line between paragraphs will be stripped out.
single line between paragraphs will be stripped out,
if you wish to keep them verbatim, use `--no-stripspace`.

-F <file>::
--file=<file>::
Take the note message from the given file. Use '-' to
read the note message from the standard input.
Lines starting with `#` and empty lines other than a
single line between paragraphs will be stripped out.
single line between paragraphs will be stripped out,
if you wish to keep them verbatim, use with
`--no-stripspace` option.

-C <object>::
--reuse-message=<object>::
Take the given blob object (for example, another note) as the
note message. (Use `git notes copy <object>` instead to
copy notes between objects.)
copy notes between objects.). By default, message will be
copied verbatim, but if you wish to strip out the lines
starting with `#` and empty lines other than a single line
between paragraphs, use with`--stripspace` option.

-c <object>::
--reedit-message=<object>::
Expand All @@ -170,6 +176,13 @@ OPTIONS
(a newline is added at the end as needed). Defaults to a
blank line.

--[no-]stripspace::
Strip leading and trailing whitespace from the note message.
Also strip out empty lines other than a single line between
paragraphs. For lines starting with `#` will be stripped out
in non-editor cases like "-m", "-F" and "-C", but not in
editor case like "git notes edit", "-c", etc.

--ref <ref>::
Manipulate the notes tree in <ref>. This overrides
`GIT_NOTES_REF` and the "core.notesRef" configuration. The ref
Expand Down
30 changes: 22 additions & 8 deletions builtin/notes.c
Expand Up @@ -101,14 +101,21 @@ static const char * const git_notes_get_ref_usage[] = {
static const char note_template[] =
N_("Write/edit the notes for the following object:");

enum notes_stripspace {
UNSPECIFIED = -1,
NO_STRIPSPACE = 0,
STRIPSPACE = 1,
};

struct note_msg {
int stripspace;
enum notes_stripspace stripspace;
struct strbuf buf;
};

struct note_data {
int given;
int use_editor;
int stripspace;
char *edit_path;
struct strbuf buf;
struct note_msg **messages;
Expand Down Expand Up @@ -213,7 +220,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
if (launch_editor(d->edit_path, &d->buf, NULL)) {
die(_("please supply the note contents using either -m or -F option"));
}
strbuf_stripspace(&d->buf, 1);
if (d->stripspace)
strbuf_stripspace(&d->buf, 1);
}
}

Expand Down Expand Up @@ -248,7 +256,9 @@ static void concat_messages(struct note_data *d)
append_separator(&d->buf);
strbuf_add(&msg, d->messages[i]->buf.buf, d->messages[i]->buf.len);
strbuf_addbuf(&d->buf, &msg);
if (d->messages[i]->stripspace)
if ((d->stripspace == UNSPECIFIED &&
d->messages[i]->stripspace == STRIPSPACE) ||
d->stripspace == STRIPSPACE)
strbuf_stripspace(&d->buf, 0);
strbuf_reset(&msg);
}
Expand All @@ -266,7 +276,7 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
strbuf_addstr(&msg->buf, arg);
ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc);
d->messages[d->msg_nr - 1] = msg;
msg->stripspace = 1;
msg->stripspace = STRIPSPACE;
return 0;
}

Expand All @@ -286,7 +296,7 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset)

ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc);
d->messages[d->msg_nr - 1] = msg;
msg->stripspace = 1;
msg->stripspace = STRIPSPACE;
return 0;
}

Expand Down Expand Up @@ -319,7 +329,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
msg->buf.len = len;
ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc);
d->messages[d->msg_nr - 1] = msg;
msg->stripspace = 0;
msg->stripspace = NO_STRIPSPACE;
return 0;
}

Expand Down Expand Up @@ -453,7 +463,7 @@ static int add(int argc, const char **argv, const char *prefix)
struct notes_tree *t;
struct object_id object, new_note;
const struct object_id *note;
struct note_data d = { .buf = STRBUF_INIT };
struct note_data d = { .buf = STRBUF_INIT, .stripspace = UNSPECIFIED };

struct option options[] = {
OPT_CALLBACK_F('m', "message", &d, N_("message"),
Expand All @@ -473,6 +483,8 @@ static int add(int argc, const char **argv, const char *prefix)
OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
OPT_STRING(0, "separator", &separator, N_("separator"),
N_("insert <paragraph-break> between paragraphs")),
OPT_BOOL(0, "stripspace", &d.stripspace,
N_("remove unnecessary whitespace")),
OPT_END()
};

Expand Down Expand Up @@ -626,7 +638,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
const struct object_id *note;
char *logmsg;
const char * const *usage;
struct note_data d = { .buf = STRBUF_INIT };
struct note_data d = { .buf = STRBUF_INIT, .stripspace = UNSPECIFIED };
struct option options[] = {
OPT_CALLBACK_F('m', "message", &d, N_("message"),
N_("note contents as a string"), PARSE_OPT_NONEG,
Expand All @@ -644,6 +656,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)
N_("allow storing empty note")),
OPT_STRING(0, "separator", &separator, N_("separator"),
N_("insert <paragraph-break> between paragraphs")),
OPT_BOOL(0, "stripspace", &d.stripspace,
N_("remove unnecessary whitespace")),
OPT_END()
};
int edit = !strcmp(argv[0], "edit");
Expand Down

0 comments on commit c4e2aa7

Please sign in to comment.