builtin-notes: Add "remove" subcommand for removing existing notes
Using "git notes remove" is equivalent to specifying an empty note message. The patch includes tests verifying correct behaviour of the new subcommand. Signed-off-by: Johan Herland <johan@herland.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johan Herland committed
Feb 13, 2010 at 22:28 UTC
92b3385fca620f47580d695b80b96432c76f0822
3 files changed
+73
-34
Documentation/git-notes.txt
+10
-5
@@ -8,14 +8,14 @@ git-notes - Add/inspect commit notes
8
SYNOPSIS
9
--------
10
[verse]
11
-'git notes' (edit [-F <file> | -m <msg>] | show) [commit]
11
+'git notes' (edit [-F <file> | -m <msg>] | show | remove) [commit]
12
13
DESCRIPTION
14
-----------
15
-This command allows you to add notes to commit messages, without
16
-changing the commit. To discern these notes from the message stored
17
-in the commit object, the notes are indented like the message, after
18
-an unindented line saying "Notes:".
15
+This command allows you to add/remove notes to/from commit messages,
16
+without changing the commit. To discern these notes from the message
17
+stored in the commit object, the notes are indented like the message,
18
+after an unindented line saying "Notes:".
19
20
To disable commit notes, you have to set the config variable
21
core.notesRef to the empty string. Alternatively, you can set it
@@ -32,6 +32,11 @@ edit::
32
show::
33
Show the notes for a given commit (defaults to HEAD).
34
35
+remove::
36
+ Remove the notes for a given commit (defaults to HEAD).
37
+ This is equivalent to specifying an empty note message to
38
+ the `edit` subcommand.
39
+
40
41
OPTIONS
42
-------
builtin-notes.c
+36
-29
@@ -20,6 +20,7 @@
20
static const char * const git_notes_usage[] = {
21
"git notes edit [-m <msg> | -F <file>] [<object>]",
22
"git notes show [<object>]",
23
+ "git notes remove [<object>]",
24
NULL
25
};
26
@@ -197,9 +198,10 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
198
struct notes_tree *t;
199
unsigned char object[20], new_note[20];
200
const unsigned char *note;
200
- const char *object_ref, *logmsg;
201
+ const char *object_ref;
202
+ char logmsg[100];
203
202
- int edit = 0, show = 0;
204
+ int edit = 0, show = 0, remove = 0;
205
const char *msgfile = NULL;
206
struct msg_arg msg = { 0, STRBUF_INIT };
207
struct option options[] = {
@@ -218,10 +220,22 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
220
edit = 1;
221
else if (argc && !strcmp(argv[0], "show"))
222
show = 1;
223
+ else if (argc && !strcmp(argv[0], "remove"))
224
+ remove = 1;
225
222
- if (edit + show != 1)
226
+ if (edit + show + remove != 1)
227
usage_with_options(git_notes_usage, options);
228
229
+ if ((msg.given || msgfile) && !edit) {
230
+ error("cannot use -m/-F options with %s subcommand.", argv[0]);
231
+ usage_with_options(git_notes_usage, options);
232
+ }
233
+
234
+ if (msg.given && msgfile) {
235
+ error("mixing -m and -F options is not allowed.");
236
+ usage_with_options(git_notes_usage, options);
237
+ }
238
+
239
object_ref = argc == 2 ? argv[1] : "HEAD";
240
if (argc > 2) {
241
error("too many parameters");
@@ -236,7 +250,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
250
251
if (prefixcmp(t->ref, "refs/notes/"))
252
die("Refusing to %s notes in %s (outside of refs/notes/)",
239
- edit ? "edit" : "show", t->ref);
253
+ argv[0], t->ref);
254
255
note = get_note(t, object);
256
@@ -250,35 +264,28 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
264
return execv_git_cmd(show_args);
265
}
266
253
- /* edit command */
254
-
255
- if (msg.given || msgfile) {
256
- if (msg.given && msgfile) {
257
- error("mixing -m and -F options is not allowed.");
258
- usage_with_options(git_notes_usage, options);
259
- }
260
- if (msg.given)
261
- strbuf_addbuf(&buf, &(msg.buf));
262
- else {
263
- if (!strcmp(msgfile, "-")) {
264
- if (strbuf_read(&buf, 0, 1024) < 0)
265
- die_errno("cannot read '%s'", msgfile);
266
- } else {
267
- if (strbuf_read_file(&buf, msgfile, 1024) < 0)
268
- die_errno("could not open or read '%s'",
269
- msgfile);
270
- }
271
- }
267
+ /* edit/remove command */
268
+
269
+ if (remove)
270
+ strbuf_reset(&buf);
271
+ else if (msg.given)
272
+ strbuf_addbuf(&buf, &(msg.buf));
273
+ else if (msgfile) {
274
+ if (!strcmp(msgfile, "-")) {
275
+ if (strbuf_read(&buf, 0, 1024) < 0)
276
+ die_errno("cannot read '%s'", msgfile);
277
+ } else if (strbuf_read_file(&buf, msgfile, 1024) < 0)
278
+ die_errno("could not open or read '%s'", msgfile);
279
}
280
274
- create_note(object, &buf, msg.given || msgfile, note, new_note);
275
- if (is_null_sha1(new_note)) {
281
+ create_note(object, &buf, msg.given || msgfile || remove, note,
282
+ new_note);
283
+ if (is_null_sha1(new_note))
284
remove_note(t, object);
277
- logmsg = "Note removed by 'git notes edit'";
278
- } else {
285
+ else
286
add_note(t, object, new_note, combine_notes_overwrite);
280
- logmsg = "Note added by 'git notes edit'";
281
- }
287
+ snprintf(logmsg, sizeof(logmsg), "Note %s by 'git notes %s'",
288
+ is_null_sha1(new_note) ? "removed" : "added", argv[0]);
289
commit_notes(t, logmsg);
290
291
free_notes(t);
t/t3301-notes.sh
+27
@@ -265,6 +265,33 @@ test_expect_success 'verify non-creation of note with -m ""' '
265
! git notes show
266
'
267
268
+test_expect_success 'remove note with "git notes remove" (setup)' '
269
+ git notes remove HEAD^
270
+'
271
+
272
+cat > expect-rm-remove << EOF
273
+commit bd1753200303d0a0344be813e504253b3d98e74d
274
+Author: A U Thor <author@example.com>
275
+Date: Thu Apr 7 15:17:13 2005 -0700
276
+
277
+ 5th
278
+
279
+commit 15023535574ded8b1a89052b32673f84cf9582b8
280
+Author: A U Thor <author@example.com>
281
+Date: Thu Apr 7 15:16:13 2005 -0700
282
+
283
+ 4th
284
+EOF
285
+
286
+printf "\n" >> expect-rm-remove
287
+cat expect-multiline >> expect-rm-remove
288
+
289
+test_expect_success 'verify note removal with "git notes remove"' '
290
+ git log -4 > output &&
291
+ test_cmp expect-rm-remove output &&
292
+ ! git notes show HEAD^
293
+'
294
+
295
test_expect_success 'create other note on a different notes ref (setup)' '
296
: > a6 &&
297
git add a6 &&