git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 5/5] notes.c: introduce "--separator" option

From
Teng Long <dyroneteng@gmail.com>
Date
Jan 12, 2023, 02:48 UTC
Message-ID
<f7edbd0e508243ab55c13721a21b78bf50278a21.1673490953.git.dyroneteng@gmail.com>
In-Reply-To
<cover.1673490953.git.dyroneteng@gmail.com>
From: Teng Long <dyroneteng@gmail.com>

When appending to a given notes object and the appended note is not empty too, we will insert a blank line at first which separates the existing note and the appended one, which as the separator.

Sometimes, we want to use a specified <text> as the separator. For example, if we specify as:

    * --separator='------': we will insert "------\n" as the separator,
    because user do not provide the line break char at last, we will add
    the trailing '\n' compatibly.
    * --separator='------\n': we will insert as-is because it contains
    the line break at last.
    * --separator='': we specify an empty separator which means will
    append the message directly without inserting any separator at
    first.
    * not specified --separator option: will use '\n' as the separator
    when do appending and this is the default behavour.
Signed-off-by: Teng Long <dyroneteng@gmail.com>
---
 Documentation/git-notes.txt | 18 +++++++++--
 builtin/notes.c             | 49 +++++++++++++++++++++++++++---
 t/t3301-notes.sh            | 59 +++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt
index efbc10f0f5..227fa88317 100644
--- a/Documentation/git-notes.txt
+++ b/Documentation/git-notes.txt
@@ -11,7 +11,7 @@ SYNOPSIS
 'git notes' [list [<object>]]
 'git notes' add [-f] [--allow-empty] [-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' append [--allow-empty] [--separator] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>]
 'git notes' edit [--allow-empty] [<object>]
 'git notes' show [<object>]
 'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref>
@@ -86,7 +86,11 @@ 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.
+	Creates a new notes object if needed. If the note of the given
+	object and the note to be appended are not empty, a blank line
+	will be inserted between them as the separator ("blank line" is
+	the default behavior, `--separator` option supports to specify
+	a customized one).
 
 edit::
 	Edit the notes for a given object (defaults to HEAD).
@@ -159,6 +163,16 @@ OPTIONS
 	Allow an empty note object to be stored. The default behavior is
 	to automatically remove empty notes.
 
+--separator <text>::
+	Specify the <text> to be inserted between existing note and appended
+	message, the <text> acts as a separator.
+	If <text> is empty (`--separator=''`), will append the message to
+	existing note directly without insert any separator.
+	If <text> is nonempty, will use as-is. One thing to notice is if
+	the <text> lacks newline charactor, will add the newline automatically.
+	If not specify this option, a blank line will be inserted as the
+	separator.
+
 --ref <ref>::
 	Manipulate the notes tree in <ref>.  This overrides
 	`GIT_NOTES_REF` and the "core.notesRef" configuration.  The ref
diff --git a/builtin/notes.c b/builtin/notes.c
index f2efb3736c..6746ad3232 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -24,6 +24,8 @@
 #include "notes-utils.h"
 #include "worktree.h"
 
+static 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>]"),
@@ -209,7 +211,7 @@ static void write_note_data(struct note_data *d, struct object_id *oid)
 	}
 }
 
-static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
+static int parse_msg_arg_add(const struct option *opt, const char *arg, int unset)
 {
 	struct note_data *d = opt->value;
 
@@ -225,6 +227,43 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+static void insert_separator(struct strbuf *message)
+{
+	const char *insert;
+
+	if (!separator)
+		separator = "\n";
+	if (*separator == '\0')
+		/* separator is empty; use as-is (no blank line) */
+		return;
+	else if (separator[strlen(separator) - 1] == '\n')
+		/* user supplied newline; use as-is */
+		insert = separator;
+	else
+		/* separator lacks newline; add it ourselves */
+		insert = xstrfmt("%s%s", separator,"\n");
+	strbuf_insertstr(message, 0, insert);
+}
+
+static int parse_msg_arg_append(const struct option *opt, const char *arg, int unset)
+{
+	struct note_data *d = opt->value;
+	struct strbuf append = STRBUF_INIT;
+
+	BUG_ON_OPT_NEG(unset);
+
+	strbuf_addstr(&append, arg);
+	if (d->buf.len){
+		insert_separator(&append);
+	}
+	strbuf_addbuf(&d->buf, &append);
+	strbuf_stripspace(&d->buf, 0);
+
+	d->given = 1;
+	strbuf_release(&append);
+	return 0;
+}
+
 static int parse_file_arg(const struct option *opt, const char *arg, int unset)
 {
 	struct note_data *d = opt->value;
@@ -406,7 +445,7 @@ static int add(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT_CALLBACK_F('m', "message", &d, N_("message"),
 			N_("note contents as a string"), PARSE_OPT_NONEG,
-			parse_msg_arg),
+			parse_msg_arg_add),
 		OPT_CALLBACK_F('F', "file", &d, N_("file"),
 			N_("note contents in a file"), PARSE_OPT_NONEG,
 			parse_file_arg),
@@ -572,7 +611,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT_CALLBACK_F('m', "message", &d, N_("message"),
 			N_("note contents as a string"), PARSE_OPT_NONEG,
-			parse_msg_arg),
+			parse_msg_arg_append),
 		OPT_CALLBACK_F('F', "file", &d, N_("file"),
 			N_("note contents in a file"), PARSE_OPT_NONEG,
 			parse_file_arg),
@@ -584,6 +623,8 @@ 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_STRING(0, "separator", &separator, N_("text"),
+			N_("insert <text> as separator before appending to an existing note")),
 		OPT_END()
 	};
 	int edit = !strcmp(argv[0], "edit");
@@ -619,7 +660,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
 		char *prev_buf = read_object_file(note, &type, &size);
 
 		if (d.buf.len && prev_buf && size)
-			strbuf_insertstr(&d.buf, 0, "\n");
+			insert_separator(&d.buf);
 		if (prev_buf && size)
 			strbuf_insert(&d.buf, 0, prev_buf, size);
 		free(prev_buf);
git format-patch a38d39a4c50d1275833aba54c4dbdfce9e2e9ca1  --thread -v 4 --output-directory=outgoing/git-notes-append/v4 --cover-letter  --range-diff 196e80358ediff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index e7807e052a..e8bc9934ed 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -521,6 +521,65 @@ test_expect_success 'listing non-existing notes fails' '
 	test_must_be_empty actual
 '
 
+test_expect_success 'append: specify an empty 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 --separator="" -m "notes-2" &&
+	git notes show >actual &&
+	test_cmp expect actual
+
+'
+
+test_expect_success 'append: specify separatoro with line break' '
+	test_when_finished git notes remove HEAD &&
+	cat >expect <<-\EOF &&
+		notes-1
+		-------
+		notes-2
+	EOF
+
+	git notes add -m "notes-1" &&
+	separator=$(printf "%s\n" "-------") &&
+	git notes append --separator="$separator" -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 to existing note with "git notes append"' '
 	cat >expect <<-EOF &&
 		Initial set of notes
-- 
2.38.1.386.g6952793f2d9.dirty
Previous: Teng LongNext: Ævar Arnfjörð Bjarmason
Message 76 of 91 in “notes.c: introduce "--no-blankline" option”
  1. 0/2 notes.c: introduce "--no-blankline" optionTeng Long, Oct 13, 2022
  2. 1/2 notes.c: introduce "--no-blankline" optionTeng Long, Oct 13, 2022
  3. Junio C HamanoOct 13, 2022
  4. Teng LongOct 17, 2022
  5. Ævar Arnfjörð BjarmasonOct 13, 2022
  6. Teng LongOct 17, 2022
  7. 2/2 notes.c: fixed tip when target and append note are both emptyTeng Long, Oct 13, 2022
  8. Ævar Arnfjörð BjarmasonOct 13, 2022
  9. Phillip WoodOct 13, 2022
  10. Ævar Arnfjörð BjarmasonOct 13, 2022
  11. Phillip WoodOct 15, 2022
  12. Teng LongOct 18, 2022
  13. Teng LongOct 18, 2022
  14. Teng LongOct 18, 2022
  15. Ævar Arnfjörð BjarmasonOct 18, 2022
  16. 0/3 notes.c: introduce "--blank-line" optionTeng Long, Nov 7, 2022
  17. 1/3 notes.c: introduce "--blank-line" optionTeng Long, Nov 7, 2022
  18. Ævar Arnfjörð BjarmasonNov 7, 2022
  19. Eric SunshineNov 7, 2022
  20. Ævar Arnfjörð BjarmasonNov 7, 2022
  21. Taylor BlauNov 7, 2022
  22. Ævar Arnfjörð BjarmasonNov 7, 2022
  23. Taylor BlauNov 8, 2022
  24. Teng LongNov 8, 2022
  25. Teng LongNov 8, 2022
  26. Ævar Arnfjörð BjarmasonNov 8, 2022
  27. Teng LongNov 9, 2022
  28. Ævar Arnfjörð BjarmasonNov 7, 2022
  29. Teng LongNov 8, 2022
  30. Taylor BlauNov 7, 2022
  31. Teng LongNov 8, 2022
  32. 2/3 notes.c: fixed tip when target and append note are both emptyTeng Long, Nov 7, 2022
  33. Ævar Arnfjörð BjarmasonNov 7, 2022
  34. Taylor BlauNov 7, 2022
  35. Ævar Arnfjörð BjarmasonNov 7, 2022
  36. Taylor BlauNov 7, 2022
  37. Teng LongNov 8, 2022
  38. 3/3 notes.c: drop unreachable code in "append_edit()"Teng Long, Nov 7, 2022
  39. Ævar Arnfjörð BjarmasonNov 7, 2022
  40. Ævar Arnfjörð BjarmasonNov 7, 2022
  41. Teng LongNov 9, 2022
  42. Teng LongNov 9, 2022
  43. 0/5 notes.c: introduce "--no-blank-line" optionTeng Long, Nov 9, 2022
  44. 1/5 notes.c: cleanup 'strbuf_grow' call in 'append_edit'Teng Long, Nov 9, 2022
  45. 2/5 notes.c: cleanup for "designated init" and "char ptr init"Teng Long, Nov 9, 2022
  46. 4/5 notes.c: provide tips when target and append note are both emptyTeng Long, Nov 9, 2022
  47. 3/5 notes.c: drop unreachable code in 'append_edit()'Teng Long, Nov 9, 2022
  48. 5/5 notes.c: introduce "--no-blank-line" optionTeng Long, Nov 9, 2022
  49. 0/5 notes.c: introduce "--no-blank-line" optionTeng Long, Nov 28, 2022
  50. Junio C HamanoNov 29, 2022
  51. Taylor BlauNov 29, 2022
  52. Teng LongNov 29, 2022
  53. Junio C HamanoNov 29, 2022
  54. Teng LongDec 15, 2022
  55. Eric SunshineDec 19, 2022
  56. Teng LongDec 21, 2022
  57. Junio C HamanoDec 21, 2022
  58. Teng LongDec 22, 2022
  59. Eric SunshineDec 23, 2022
  60. 0/5 notes.c: introduce "--separator" optioTeng Long, Jan 12, 2023
  61. 1/5 notes.c: cleanup 'strbuf_grow' call in 'append_edit'Teng Long, Jan 12, 2023
  62. Eric SunshineJan 15, 2023
  63. Teng LongJan 28, 2023
  64. 2/5 notes.c: cleanup for "designated init" and "char ptr init"Teng Long, Jan 12, 2023
  65. Ævar Arnfjörð BjarmasonJan 12, 2023
  66. Teng LongJan 28, 2023
  67. 4/5 notes.c: provide tips when target and append note are both emptyTeng Long, Jan 12, 2023
  68. Ævar Arnfjörð BjarmasonJan 12, 2023
  69. Eric SunshineJan 15, 2023
  70. 3/5 notes.c: drop unreachable code in 'append_edit()'Teng Long, Jan 12, 2023
  71. Eric SunshineJan 15, 2023
  72. Eric SunshineJan 15, 2023
  73. Teng LongJan 28, 2023
  74. Eric SunshineJan 30, 2023
  75. Teng LongFeb 1, 2023
  76. 5/5 notes.c: introduce "--separator" optionTeng Long, Jan 12, 2023
  77. Ævar Arnfjörð BjarmasonJan 12, 2023
  78. Eric SunshineJan 15, 2023
  79. Eric SunshineJan 15, 2023
  80. 0/3 notes.c: introduce "--separator" optionTeng Long, Feb 16, 2023
  81. 1/3 notes.c: cleanup 'strbuf_grow' call in 'append_edit'Teng Long, Feb 16, 2023
  82. Junio C HamanoFeb 16, 2023
  83. Teng LongFeb 20, 2023
  84. 2/3 notes.c: cleanup for "designated init"Teng Long, Feb 16, 2023
  85. Junio C HamanoFeb 16, 2023
  86. 3/3 notes.c: introduce "--separator" optionTeng Long, Feb 16, 2023
  87. Junio C HamanoFeb 16, 2023
  88. Teng LongFeb 20, 2023
  89. Junio C HamanoFeb 21, 2023
  90. Teng LongFeb 22, 2023
  91. Junio C HamanoFeb 22, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.