Merge branch 'tl/notes-separator'
'git notes append' was taught '--separator' to specify string to insert between paragraphs. * tl/notes-separator: notes: introduce "--no-separator" option notes.c: introduce "--[no-]stripspace" option notes.c: append separator instead of insert by pos notes.c: introduce '--separator=<paragraph-break>' option t3321: add test cases about the notes stripspace behavior notes.c: use designated initializers for clarity notes.c: cleanup 'strbuf_grow' call in 'append_edit'maint
commit
a9cc3b8fc7
|
@ -9,10 +9,10 @@ SYNOPSIS
|
|||
--------
|
||||
[verse]
|
||||
'git notes' [list [<object>]]
|
||||
'git notes' add [-f] [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
|
||||
'git notes' add [-f] [--allow-empty] [--[no-]separator | --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] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
|
||||
'git notes' edit [--allow-empty] [<object>]
|
||||
'git notes' append [--allow-empty] [--[no-]separator | --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]
|
||||
|
@ -65,7 +65,9 @@ add::
|
|||
However, if you're using `add` interactively (using an editor
|
||||
to supply the notes contents), then - instead of aborting -
|
||||
the existing notes will be opened in the editor (like the `edit`
|
||||
subcommand).
|
||||
subcommand). If you specify multiple `-m` and `-F`, a blank
|
||||
line will be inserted between the messages. Use the `--separator`
|
||||
option to insert other delimiters.
|
||||
|
||||
copy::
|
||||
Copy the notes for the first object onto the second object (defaults to
|
||||
|
@ -85,8 +87,12 @@ corresponding <to-object>. (The optional `<rest>` is ignored so that
|
|||
the command can read the input given to the `post-rewrite` hook.)
|
||||
|
||||
append::
|
||||
Append to the notes of an existing object (defaults to HEAD).
|
||||
Creates a new notes object if needed.
|
||||
Append new message(s) given by `-m` or `-F` options to an
|
||||
existing note, or add them as a new note if one does not
|
||||
exist, for the object (defaults to HEAD). When appending to
|
||||
an existing note, a blank line is added before each new
|
||||
message as an inter-paragraph separator. The separator can
|
||||
be customized with the `--separator` option.
|
||||
|
||||
edit::
|
||||
Edit the notes for a given object (defaults to HEAD).
|
||||
|
@ -135,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>::
|
||||
|
@ -159,6 +171,19 @@ OPTIONS
|
|||
Allow an empty note object to be stored. The default behavior is
|
||||
to automatically remove empty notes.
|
||||
|
||||
--[no-]separator, --separator=<paragraph-break>::
|
||||
Specify a string used as a custom inter-paragraph separator
|
||||
(a newline is added at the end as needed). If `--no-separator`, no
|
||||
separators will be added between paragraphs. 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
|
||||
|
|
159
builtin/notes.c
159
builtin/notes.c
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "builtin.h"
|
||||
#include "config.h"
|
||||
#include "alloc.h"
|
||||
#include "editor.h"
|
||||
#include "environment.h"
|
||||
#include "gettext.h"
|
||||
|
@ -30,11 +31,12 @@
|
|||
#include "worktree.h"
|
||||
#include "write-or-die.h"
|
||||
|
||||
static const char *separator = "\n";
|
||||
static const char * const git_notes_usage[] = {
|
||||
N_("git notes [--ref <notes-ref>] [list [<object>]]"),
|
||||
N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"),
|
||||
N_("git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] show [<object>]"),
|
||||
N_("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"),
|
||||
|
@ -102,11 +104,26 @@ 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 {
|
||||
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;
|
||||
size_t msg_nr;
|
||||
size_t msg_alloc;
|
||||
};
|
||||
|
||||
static void free_note_data(struct note_data *d)
|
||||
|
@ -116,6 +133,12 @@ static void free_note_data(struct note_data *d)
|
|||
free(d->edit_path);
|
||||
}
|
||||
strbuf_release(&d->buf);
|
||||
|
||||
while (d->msg_nr--) {
|
||||
strbuf_release(&d->messages[d->msg_nr]->buf);
|
||||
free(d->messages[d->msg_nr]);
|
||||
}
|
||||
free(d->messages);
|
||||
}
|
||||
|
||||
static int list_each_note(const struct object_id *object_oid,
|
||||
|
@ -201,7 +224,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, comment_line_char);
|
||||
if (d->stripspace)
|
||||
strbuf_stripspace(&d->buf, comment_line_char);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,66 +241,102 @@ static void write_note_data(struct note_data *d, struct object_id *oid)
|
|||
}
|
||||
}
|
||||
|
||||
static void append_separator(struct strbuf *message)
|
||||
{
|
||||
size_t sep_len = 0;
|
||||
|
||||
if (!separator)
|
||||
return;
|
||||
else if ((sep_len = strlen(separator)) && separator[sep_len - 1] == '\n')
|
||||
strbuf_addstr(message, separator);
|
||||
else
|
||||
strbuf_addf(message, "%s%s", separator, "\n");
|
||||
}
|
||||
|
||||
static void concat_messages(struct note_data *d)
|
||||
{
|
||||
struct strbuf msg = STRBUF_INIT;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < d->msg_nr ; i++) {
|
||||
if (d->buf.len)
|
||||
append_separator(&d->buf);
|
||||
strbuf_add(&msg, d->messages[i]->buf.buf, d->messages[i]->buf.len);
|
||||
strbuf_addbuf(&d->buf, &msg);
|
||||
if ((d->stripspace == UNSPECIFIED &&
|
||||
d->messages[i]->stripspace == STRIPSPACE) ||
|
||||
d->stripspace == STRIPSPACE)
|
||||
strbuf_stripspace(&d->buf, 0);
|
||||
strbuf_reset(&msg);
|
||||
}
|
||||
strbuf_release(&msg);
|
||||
}
|
||||
|
||||
static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct note_data *d = opt->value;
|
||||
struct note_msg *msg = xmalloc(sizeof(*msg));
|
||||
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
|
||||
strbuf_grow(&d->buf, strlen(arg) + 2);
|
||||
if (d->buf.len)
|
||||
strbuf_addch(&d->buf, '\n');
|
||||
strbuf_addstr(&d->buf, arg);
|
||||
strbuf_stripspace(&d->buf, '\0');
|
||||
|
||||
d->given = 1;
|
||||
strbuf_init(&msg->buf, strlen(arg));
|
||||
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 = STRIPSPACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_file_arg(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct note_data *d = opt->value;
|
||||
struct note_msg *msg = xmalloc(sizeof(*msg));
|
||||
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
|
||||
if (d->buf.len)
|
||||
strbuf_addch(&d->buf, '\n');
|
||||
strbuf_init(&msg->buf , 0);
|
||||
if (!strcmp(arg, "-")) {
|
||||
if (strbuf_read(&d->buf, 0, 1024) < 0)
|
||||
if (strbuf_read(&msg->buf, 0, 1024) < 0)
|
||||
die_errno(_("cannot read '%s'"), arg);
|
||||
} else if (strbuf_read_file(&d->buf, arg, 1024) < 0)
|
||||
} else if (strbuf_read_file(&msg->buf, arg, 1024) < 0)
|
||||
die_errno(_("could not open or read '%s'"), arg);
|
||||
strbuf_stripspace(&d->buf, '\0');
|
||||
|
||||
d->given = 1;
|
||||
ALLOC_GROW_BY(d->messages, d->msg_nr, 1, d->msg_alloc);
|
||||
d->messages[d->msg_nr - 1] = msg;
|
||||
msg->stripspace = STRIPSPACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct note_data *d = opt->value;
|
||||
char *buf;
|
||||
struct note_msg *msg = xmalloc(sizeof(*msg));
|
||||
char *value;
|
||||
struct object_id object;
|
||||
enum object_type type;
|
||||
unsigned long len;
|
||||
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
|
||||
if (d->buf.len)
|
||||
strbuf_addch(&d->buf, '\n');
|
||||
|
||||
strbuf_init(&msg->buf, 0);
|
||||
if (repo_get_oid(the_repository, arg, &object))
|
||||
die(_("failed to resolve '%s' as a valid ref."), arg);
|
||||
if (!(buf = repo_read_object_file(the_repository, &object, &type, &len)))
|
||||
if (!(value = repo_read_object_file(the_repository, &object, &type, &len)))
|
||||
die(_("failed to read object '%s'."), arg);
|
||||
if (type != OBJ_BLOB) {
|
||||
free(buf);
|
||||
strbuf_release(&msg->buf);
|
||||
free(value);
|
||||
free(msg);
|
||||
die(_("cannot read note data from non-blob object '%s'."), arg);
|
||||
}
|
||||
strbuf_add(&d->buf, buf, len);
|
||||
free(buf);
|
||||
|
||||
d->given = 1;
|
||||
strbuf_add(&msg->buf, value, len);
|
||||
free(value);
|
||||
|
||||
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 = NO_STRIPSPACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -288,6 +348,16 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset
|
|||
return parse_reuse_arg(opt, arg, unset);
|
||||
}
|
||||
|
||||
static int parse_separator_arg(const struct option *opt, const char *arg,
|
||||
int unset)
|
||||
{
|
||||
if (unset)
|
||||
*(const char **)opt->value = NULL;
|
||||
else
|
||||
*(const char **)opt->value = arg ? arg : "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int notes_copy_from_stdin(int force, const char *rewrite_cmd)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
@ -410,7 +480,8 @@ 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 = { 0, 0, NULL, 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,
|
||||
|
@ -427,6 +498,12 @@ static int add(int argc, const char **argv, const char *prefix)
|
|||
OPT_BOOL(0, "allow-empty", &allow_empty,
|
||||
N_("allow storing empty note")),
|
||||
OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
|
||||
OPT_CALLBACK_F(0, "separator", &separator,
|
||||
N_("<paragraph-break>"),
|
||||
N_("insert <paragraph-break> between paragraphs"),
|
||||
PARSE_OPT_OPTARG, parse_separator_arg),
|
||||
OPT_BOOL(0, "stripspace", &d.stripspace,
|
||||
N_("remove unnecessary whitespace")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
@ -438,6 +515,10 @@ static int add(int argc, const char **argv, const char *prefix)
|
|||
usage_with_options(git_notes_add_usage, options);
|
||||
}
|
||||
|
||||
if (d.msg_nr)
|
||||
concat_messages(&d);
|
||||
d.given = !!d.buf.len;
|
||||
|
||||
object_ref = argc > 1 ? argv[1] : "HEAD";
|
||||
|
||||
if (repo_get_oid(the_repository, object_ref, &object))
|
||||
|
@ -576,7 +657,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 = { 0, 0, NULL, 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,
|
||||
|
@ -592,6 +673,12 @@ static int append_edit(int argc, const char **argv, const char *prefix)
|
|||
parse_reuse_arg),
|
||||
OPT_BOOL(0, "allow-empty", &allow_empty,
|
||||
N_("allow storing empty note")),
|
||||
OPT_CALLBACK_F(0, "separator", &separator,
|
||||
N_("<paragraph-break>"),
|
||||
N_("insert <paragraph-break> between paragraphs"),
|
||||
PARSE_OPT_OPTARG, parse_separator_arg),
|
||||
OPT_BOOL(0, "stripspace", &d.stripspace,
|
||||
N_("remove unnecessary whitespace")),
|
||||
OPT_END()
|
||||
};
|
||||
int edit = !strcmp(argv[0], "edit");
|
||||
|
@ -605,6 +692,10 @@ static int append_edit(int argc, const char **argv, const char *prefix)
|
|||
usage_with_options(usage, options);
|
||||
}
|
||||
|
||||
if (d.msg_nr)
|
||||
concat_messages(&d);
|
||||
d.given = !!d.buf.len;
|
||||
|
||||
if (d.given && edit)
|
||||
fprintf(stderr, _("The -m/-F/-c/-C options have been deprecated "
|
||||
"for the 'edit' subcommand.\n"
|
||||
|
@ -624,15 +715,17 @@ static int append_edit(int argc, const char **argv, const char *prefix)
|
|||
/* Append buf to previous note contents */
|
||||
unsigned long size;
|
||||
enum object_type type;
|
||||
char *prev_buf = repo_read_object_file(the_repository, note,
|
||||
&type, &size);
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
char *prev_buf = repo_read_object_file(the_repository, note, &type, &size);
|
||||
|
||||
strbuf_grow(&d.buf, size + 1);
|
||||
if (d.buf.len && prev_buf && size)
|
||||
strbuf_insertstr(&d.buf, 0, "\n");
|
||||
if (prev_buf && size)
|
||||
strbuf_insert(&d.buf, 0, prev_buf, size);
|
||||
strbuf_add(&buf, prev_buf, size);
|
||||
if (d.buf.len && prev_buf && size)
|
||||
append_separator(&buf);
|
||||
strbuf_insert(&d.buf, 0, buf.buf, buf.len);
|
||||
|
||||
free(prev_buf);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
if (d.buf.len || allow_empty) {
|
||||
|
|
169
t/t3301-notes.sh
169
t/t3301-notes.sh
|
@ -362,6 +362,7 @@ test_expect_success 'do not create empty note with -m ""' '
|
|||
'
|
||||
|
||||
test_expect_success 'create note with combination of -m and -F' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect-combine_m_and_F <<-EOF &&
|
||||
foo
|
||||
|
||||
|
@ -380,6 +381,41 @@ test_expect_success 'create note with combination of -m and -F' '
|
|||
test_cmp expect-combine_m_and_F actual
|
||||
'
|
||||
|
||||
test_expect_success 'create note with combination of -m and -F and --separator' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect-combine_m_and_F <<-\EOF &&
|
||||
foo
|
||||
-------
|
||||
xyzzy
|
||||
-------
|
||||
bar
|
||||
-------
|
||||
zyxxy
|
||||
-------
|
||||
baz
|
||||
EOF
|
||||
echo "xyzzy" >note_a &&
|
||||
echo "zyxxy" >note_b &&
|
||||
git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --separator="-------" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect-combine_m_and_F actual
|
||||
'
|
||||
|
||||
test_expect_success 'create note with combination of -m and -F and --no-separator' '
|
||||
cat >expect-combine_m_and_F <<-\EOF &&
|
||||
foo
|
||||
xyzzy
|
||||
bar
|
||||
zyxxy
|
||||
baz
|
||||
EOF
|
||||
echo "xyzzy" >note_a &&
|
||||
echo "zyxxy" >note_b &&
|
||||
git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --no-separator &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect-combine_m_and_F actual
|
||||
'
|
||||
|
||||
test_expect_success 'remove note with "git notes remove"' '
|
||||
git notes remove HEAD^ &&
|
||||
git notes remove &&
|
||||
|
@ -521,6 +557,112 @@ test_expect_success 'listing non-existing notes fails' '
|
|||
test_must_be_empty actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify a separator with an empty arg' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
|
||||
notes-2
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --separator="" -m "notes-2" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify a separator without arg' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
|
||||
notes-2
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --separator -m "notes-2" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify as --no-separator' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
notes-2
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --no-separator -m "notes-2" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify separator with line break' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
-------
|
||||
notes-2
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --separator="-------$LF" -m "notes-2" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify separator without line break' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
-------
|
||||
notes-2
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --separator="-------" -m "notes-2" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append: specify separator with multiple messages' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect <<-\EOF &&
|
||||
notes-1
|
||||
-------
|
||||
notes-2
|
||||
-------
|
||||
notes-3
|
||||
EOF
|
||||
|
||||
git notes add -m "notes-1" &&
|
||||
git notes append --separator="-------" -m "notes-2" -m "notes-3" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note with combination of -m and -F and --separator' '
|
||||
test_when_finished git notes remove HEAD &&
|
||||
cat >expect-combine_m_and_F <<-\EOF &&
|
||||
m-notes-1
|
||||
-------
|
||||
f-notes-1
|
||||
-------
|
||||
m-notes-2
|
||||
-------
|
||||
f-notes-2
|
||||
-------
|
||||
m-notes-3
|
||||
EOF
|
||||
|
||||
echo "f-notes-1" >note_a &&
|
||||
echo "f-notes-2" >note_b &&
|
||||
git notes append -m "m-notes-1" -F note_a -m "m-notes-2" -F note_b -m "m-notes-3" --separator="-------" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect-combine_m_and_F actual
|
||||
'
|
||||
|
||||
test_expect_success 'append to existing note with "git notes append"' '
|
||||
cat >expect <<-EOF &&
|
||||
Initial set of notes
|
||||
|
@ -818,6 +960,33 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i
|
|||
test_cmp blob actual
|
||||
'
|
||||
|
||||
test_expect_success 'create note from blob with "-C", also specify "-m", "-F" and "--separator"' '
|
||||
# 8th will be reuseed in following tests, so rollback when the test is done
|
||||
test_when_finished "git notes remove && git notes add -C $(cat blob)" &&
|
||||
commit=$(git rev-parse HEAD) &&
|
||||
cat >expect <<-EOF &&
|
||||
commit $commit
|
||||
Author: A U Thor <author@example.com>
|
||||
Date: Thu Apr 7 15:20:13 2005 -0700
|
||||
|
||||
${indent}8th
|
||||
|
||||
Notes:
|
||||
${indent}This is a blob object
|
||||
${indent}-------
|
||||
${indent}This is created by -m
|
||||
${indent}-------
|
||||
${indent}This is created by -F
|
||||
EOF
|
||||
|
||||
git notes remove &&
|
||||
echo "This is a blob object" | git hash-object -w --stdin >blob &&
|
||||
echo "This is created by -F" >note_a &&
|
||||
git notes add -C $(cat blob) -m "This is created by -m" -F note_a --separator="-------" &&
|
||||
git log -1 >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'create note from other note with "git notes add -c"' '
|
||||
test_commit 9th &&
|
||||
commit=$(git rev-parse HEAD) &&
|
||||
|
|
|
@ -0,0 +1,577 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2023 Teng Long
|
||||
#
|
||||
|
||||
test_description='Test commit notes with stripspace behavior'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
MULTI_LF="$LF$LF$LF"
|
||||
write_script fake_editor <<\EOF
|
||||
echo "$MSG" >"$1"
|
||||
echo "$MSG" >&2
|
||||
EOF
|
||||
GIT_EDITOR=./fake_editor
|
||||
export GIT_EDITOR
|
||||
|
||||
test_expect_success 'setup the commit' '
|
||||
test_commit 1st
|
||||
'
|
||||
|
||||
test_expect_success 'add note by editor' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying single "-m", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
git notes add -m "${LF}first-line${MULTI_LF}second-line${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
git notes add --stripspace -m "${LF}first-line${MULTI_LF}second-line${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying single "-m" and "--no-stripspace" ' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}first-line${MULTI_LF}second-line
|
||||
EOF
|
||||
|
||||
git notes add --no-stripspace \
|
||||
-m "${LF}first-line${MULTI_LF}second-line${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying multiple "-m", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
git notes add -m "${LF}" \
|
||||
-m "first-line" \
|
||||
-m "${MULTI_LF}" \
|
||||
-m "second-line" \
|
||||
-m "${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
git notes add --stripspace -m "${LF}" \
|
||||
-m "first-line" \
|
||||
-m "${MULTI_LF}" \
|
||||
-m "second-line" \
|
||||
-m "${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add notes by specifying multiple "-m" and "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line${LF}
|
||||
EOF
|
||||
|
||||
git notes add --no-stripspace \
|
||||
-m "${LF}" \
|
||||
-m "first-line" \
|
||||
-m "${MULTI_LF}" \
|
||||
-m "second-line" \
|
||||
-m "${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying single "-F", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat >note-file <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -F note-file &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
git notes add --stripspace -F note-file &&
|
||||
git notes show >actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying single "-F" and "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add --no-stripspace -F note-file &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying multiple "-F", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
file-1-first-line
|
||||
|
||||
file-1-second-line
|
||||
|
||||
file-2-first-line
|
||||
|
||||
file-2-second-line
|
||||
EOF
|
||||
|
||||
cat >note-file-1 <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-2 <<-EOF &&
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
git notes add --stripspace -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying multiple "-F" with "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-1 <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-2 <<-EOF &&
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add --no-stripspace -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note by editor' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
git notes add -m "first-line" &&
|
||||
MSG="${MULTI_LF}second-line${LF}" git notes append &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note by specifying single "-m"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
git notes add -m "${LF}first-line" &&
|
||||
git notes append -m "${MULTI_LF}second-line${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note by specifying multiple "-m"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
git notes add -m "${LF}first-line" &&
|
||||
git notes append -m "${MULTI_LF}" \
|
||||
-m "second-line" \
|
||||
-m "${LF}" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying single "-F"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat >note-file <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -F note-file &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add notes by specifying multiple "-F"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
file-1-first-line
|
||||
|
||||
file-1-second-line
|
||||
|
||||
file-2-first-line
|
||||
|
||||
file-2-second-line
|
||||
EOF
|
||||
|
||||
cat >note-file-1 <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-2 <<-EOF &&
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note by specifying single "-F"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
initial-line
|
||||
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat >note-file <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -m "initial-line" &&
|
||||
git notes append -F note-file &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append notes by specifying multiple "-F"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
initial-line
|
||||
|
||||
file-1-first-line
|
||||
|
||||
file-1-second-line
|
||||
|
||||
file-2-first-line
|
||||
|
||||
file-2-second-line
|
||||
EOF
|
||||
|
||||
cat >note-file-1 <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-2 <<-EOF &&
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -m "initial-line" &&
|
||||
git notes append -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'append note by specifying multiple "-F" with "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
initial-line
|
||||
${LF}${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-1 <<-EOF &&
|
||||
${LF}
|
||||
file-1-first-line
|
||||
${MULTI_LF}
|
||||
file-1-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >note-file-2 <<-EOF &&
|
||||
${LF}
|
||||
file-2-first-line
|
||||
${MULTI_LF}
|
||||
file-2-second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
git notes add -m "initial-line" &&
|
||||
git notes append --no-stripspace -F note-file-1 -F note-file-2 &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add notes with empty messages' '
|
||||
rev=$(git rev-parse HEAD) &&
|
||||
git notes add -m "${LF}" \
|
||||
-m "${MULTI_LF}" \
|
||||
-m "${LF}" >actual 2>&1 &&
|
||||
test_i18ngrep "Removing note for object" actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying "-C", "--no-stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat expect | git hash-object -w --stdin >blob &&
|
||||
git notes add -C $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
git notes add --no-stripspace -C $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'reuse note by specifying "-C" and "--stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >data <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat data | git hash-object -w --stdin >blob &&
|
||||
git notes add --stripspace -C $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'reuse with "-C" and add note with "-m", "-m" will stripspace all together' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >data <<-EOF &&
|
||||
${LF}
|
||||
first-line
|
||||
${MULTI_LF}
|
||||
second-line
|
||||
${LF}
|
||||
EOF
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
|
||||
third-line
|
||||
EOF
|
||||
|
||||
cat data | git hash-object -w --stdin >blob &&
|
||||
git notes add -C $(cat blob) -m "third-line" &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note with "-m" and reuse note with "-C", "-C" will not stripspace all together' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >data <<-EOF &&
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
${LF}
|
||||
second-line
|
||||
EOF
|
||||
|
||||
cat data | git hash-object -w --stdin >blob &&
|
||||
git notes add -m "first-line" -C $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying "-c", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
echo "initial-line" | git hash-object -w --stdin >blob &&
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add -c $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --stripspace -c $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'add note by specifying "-c" with "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}first-line${MULTI_LF}second-line${LF}
|
||||
EOF
|
||||
|
||||
echo "initial-line" | git hash-object -w --stdin >blob &&
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace -c $(cat blob) &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'edit note by specifying "-c", "--stripspace" is the default behavior' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
first-line
|
||||
|
||||
second-line
|
||||
EOF
|
||||
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual &&
|
||||
git notes remove &&
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit --stripspace &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'edit note by specifying "-c" with "--no-stripspace"' '
|
||||
test_when_finished "git notes remove" &&
|
||||
cat >expect <<-EOF &&
|
||||
${LF}first-line${MULTI_LF}second-line${LF}
|
||||
EOF
|
||||
|
||||
MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace &&
|
||||
git notes show >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
Loading…
Reference in New Issue