notes: introduce "--no-separator" option

Sometimes, the user may want to add or append multiple notes without any separator to be added between them. Disscussion: https://public-inbox.org/git/3f86a553-246a-4626-b1bd-bacd8148318a@app.fastmail.com/ Signed-off-by: Teng Long <dyroneteng@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Teng Long committed May 27, 2023 at 15:57 UTC 3d6a31646491bf4f8b1166d7182c6d92e2414cf8
3 files changed +79 -18
Documentation/git-notes.txt
+6 -5
@@ -9,9 +9,9 @@ SYNOPSIS
9 --------
10 [verse]
11 'git notes' [list [<object>]]
12 -'git notes' add [-f] [--allow-empty] [--separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
12 +'git notes' add [-f] [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
13 'git notes' copy [-f] ( --stdin | <from-object> [<to-object>] )
14 -'git notes' append [--allow-empty] [--separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
14 +'git notes' append [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
15 'git notes' edit [--allow-empty] [<object>] [--[no-]stripspace]
16 'git notes' show [<object>]
17 'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>
@@ -171,10 +171,11 @@ OPTIONS
171 Allow an empty note object to be stored. The default behavior is
172 to automatically remove empty notes.
173
174 ---separator <paragraph-break>::
174 +--[no-]separator, --separator=<paragraph-break>::
175 Specify a string used as a custom inter-paragraph separator
176 - (a newline is added at the end as needed). Defaults to a
177 - blank line.
176 + (a newline is added at the end as needed). If `--no-separator`, no
177 + separators will be added between paragraphs. Defaults to a blank
178 + line.
179
180 --[no-]stripspace::
181 Strip leading and trailing whitespace from the note message.
builtin/notes.c
+27 -10
@@ -28,12 +28,12 @@
28 #include "worktree.h"
29 #include "write-or-die.h"
30
31 -static char *separator = "\n";
31 +static const char *separator = "\n";
32 static const char * const git_notes_usage[] = {
33 N_("git notes [--ref <notes-ref>] [list [<object>]]"),
34 - N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--separator=<paragraph-break>] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
34 + 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>]"),
35 N_("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"),
36 - N_("git notes [--ref <notes-ref>] append [--allow-empty] [--separator=<paragraph-break>] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
36 + N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
37 N_("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"),
38 N_("git notes [--ref <notes-ref>] show [<object>]"),
39 N_("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"),
@@ -239,8 +239,11 @@ static void write_note_data(struct note_data *d, struct object_id *oid)
239
240 static void append_separator(struct strbuf *message)
241 {
242 - size_t sep_len = strlen(separator);
243 - if (sep_len && separator[sep_len - 1] == '\n')
242 + size_t sep_len = 0;
243 +
244 + if (!separator)
245 + return;
246 + else if ((sep_len = strlen(separator)) && separator[sep_len - 1] == '\n')
247 strbuf_addstr(message, separator);
248 else
249 strbuf_addf(message, "%s%s", separator, "\n");
@@ -249,8 +252,8 @@ static void append_separator(struct strbuf *message)
252 static void concat_messages(struct note_data *d)
253 {
254 struct strbuf msg = STRBUF_INIT;
252 -
255 size_t i;
256 +
257 for (i = 0; i < d->msg_nr ; i++) {
258 if (d->buf.len)
259 append_separator(&d->buf);
@@ -341,6 +344,16 @@ static int parse_reedit_arg(const struct option *opt, const char *arg, int unset
344 return parse_reuse_arg(opt, arg, unset);
345 }
346
347 +static int parse_separator_arg(const struct option *opt, const char *arg,
348 + int unset)
349 +{
350 + if (unset)
351 + *(const char **)opt->value = NULL;
352 + else
353 + *(const char **)opt->value = arg ? arg : "\n";
354 + return 0;
355 +}
356 +
357 static int notes_copy_from_stdin(int force, const char *rewrite_cmd)
358 {
359 struct strbuf buf = STRBUF_INIT;
@@ -481,8 +494,10 @@ static int add(int argc, const char **argv, const char *prefix)
494 OPT_BOOL(0, "allow-empty", &allow_empty,
495 N_("allow storing empty note")),
496 OPT__FORCE(&force, N_("replace existing notes"), PARSE_OPT_NOCOMPLETE),
484 - OPT_STRING(0, "separator", &separator, N_("separator"),
485 - N_("insert <paragraph-break> between paragraphs")),
497 + OPT_CALLBACK_F(0, "separator", &separator,
498 + N_("<paragraph-break>"),
499 + N_("insert <paragraph-break> between paragraphs"),
500 + PARSE_OPT_OPTARG, parse_separator_arg),
501 OPT_BOOL(0, "stripspace", &d.stripspace,
502 N_("remove unnecessary whitespace")),
503 OPT_END()
@@ -654,8 +669,10 @@ static int append_edit(int argc, const char **argv, const char *prefix)
669 parse_reuse_arg),
670 OPT_BOOL(0, "allow-empty", &allow_empty,
671 N_("allow storing empty note")),
657 - OPT_STRING(0, "separator", &separator, N_("separator"),
658 - N_("insert <paragraph-break> between paragraphs")),
672 + OPT_CALLBACK_F(0, "separator", &separator,
673 + N_("<paragraph-break>"),
674 + N_("insert <paragraph-break> between paragraphs"),
675 + PARSE_OPT_OPTARG, parse_separator_arg),
676 OPT_BOOL(0, "stripspace", &d.stripspace,
677 N_("remove unnecessary whitespace")),
678 OPT_END()
t/t3301-notes.sh
+46 -3
@@ -382,6 +382,7 @@ test_expect_success 'create note with combination of -m and -F' '
382 '
383
384 test_expect_success 'create note with combination of -m and -F and --separator' '
385 + test_when_finished git notes remove HEAD &&
386 cat >expect-combine_m_and_F <<-\EOF &&
387 foo
388 -------
@@ -395,7 +396,22 @@ test_expect_success 'create note with combination of -m and -F and --separator'
396 EOF
397 echo "xyzzy" >note_a &&
398 echo "zyxxy" >note_b &&
398 - git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --separator "-------" &&
399 + git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --separator="-------" &&
400 + git notes show >actual &&
401 + test_cmp expect-combine_m_and_F actual
402 +'
403 +
404 +test_expect_success 'create note with combination of -m and -F and --no-separator' '
405 + cat >expect-combine_m_and_F <<-\EOF &&
406 + foo
407 + xyzzy
408 + bar
409 + zyxxy
410 + baz
411 + EOF
412 + echo "xyzzy" >note_a &&
413 + echo "zyxxy" >note_b &&
414 + git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --no-separator &&
415 git notes show >actual &&
416 test_cmp expect-combine_m_and_F actual
417 '
@@ -541,7 +557,7 @@ test_expect_success 'listing non-existing notes fails' '
557 test_must_be_empty actual
558 '
559
544 -test_expect_success 'append: specify an empty separator' '
560 +test_expect_success 'append: specify a separator with an empty arg' '
561 test_when_finished git notes remove HEAD &&
562 cat >expect <<-\EOF &&
563 notes-1
@@ -555,6 +571,33 @@ test_expect_success 'append: specify an empty separator' '
571 test_cmp expect actual
572 '
573
574 +test_expect_success 'append: specify a separator without arg' '
575 + test_when_finished git notes remove HEAD &&
576 + cat >expect <<-\EOF &&
577 + notes-1
578 +
579 + notes-2
580 + EOF
581 +
582 + git notes add -m "notes-1" &&
583 + git notes append --separator -m "notes-2" &&
584 + git notes show >actual &&
585 + test_cmp expect actual
586 +'
587 +
588 +test_expect_success 'append: specify as --no-separator' '
589 + test_when_finished git notes remove HEAD &&
590 + cat >expect <<-\EOF &&
591 + notes-1
592 + notes-2
593 + EOF
594 +
595 + git notes add -m "notes-1" &&
596 + git notes append --no-separator -m "notes-2" &&
597 + git notes show >actual &&
598 + test_cmp expect actual
599 +'
600 +
601 test_expect_success 'append: specify separator with line break' '
602 test_when_finished git notes remove HEAD &&
603 cat >expect <<-\EOF &&
@@ -615,7 +658,7 @@ test_expect_success 'append note with combination of -m and -F and --separator'
658
659 echo "f-notes-1" >note_a &&
660 echo "f-notes-2" >note_b &&
618 - git notes append -m "m-notes-1" -F note_a -m "m-notes-2" -F note_b -m "m-notes-3" --separator "-------" &&
661 + git notes append -m "m-notes-1" -F note_a -m "m-notes-2" -F note_b -m "m-notes-3" --separator="-------" &&
662 git notes show >actual &&
663 test_cmp expect-combine_m_and_F actual
664 '