notes remove: --ignore-missing

Depending on the application, it is not necessarily an error for an object to lack a note, especially if the only thing the caller wants to make sure is that notes are cleared for an object. By passing this option from the command line, the "git notes remove" command considers it a success if the object did not have any note to begin with. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed May 18, 2011 at 16:02 UTC 2d370d2fbcf896912cc0739b806224f9a270bb5e
3 files changed +35 -5
Documentation/git-notes.txt
+5 -1
@@ -17,7 +17,7 @@ SYNOPSIS
17 'git notes' merge [-v | -q] [-s <strategy> ] <notes_ref>
18 'git notes' merge --commit [-v | -q]
19 'git notes' merge --abort [-v | -q]
20 -'git notes' remove [<object>...]
20 +'git notes' remove [--ignore-missing] [<object>...]
21 'git notes' prune [-n | -v]
22 'git notes' get-ref
23
@@ -155,6 +155,10 @@ OPTIONS
155 'GIT_NOTES_REF' and the "core.notesRef" configuration. The ref
156 is taken to be in `refs/notes/` if it is not qualified.
157
158 +--ignore-missing::
159 + Do not consider it an error to request removing notes from an
160 + object that does not have notes attached to it.
161 +
162 -n::
163 --dry-run::
164 Do not remove anything; just report the object names whose notes
builtin/notes.c
+10 -4
@@ -953,7 +953,9 @@ static int merge(int argc, const char **argv, const char *prefix)
953 return result < 0; /* return non-zero on conflicts */
954 }
955
956 -static int remove_one_note(struct notes_tree *t, const char *name)
956 +#define MISSING_OK 1
957 +
958 +static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag)
959 {
960 int status;
961 unsigned char sha1[20];
@@ -964,12 +966,16 @@ static int remove_one_note(struct notes_tree *t, const char *name)
966 fprintf(stderr, _("Object %s has no note\n"), name);
967 else
968 fprintf(stderr, _("Removing note for object %s\n"), name);
967 - return status;
969 + return (flag & MISSING_OK) ? 0 : status;
970 }
971
972 static int remove_cmd(int argc, const char **argv, const char *prefix)
973 {
974 + unsigned flag = 0;
975 struct option options[] = {
976 + OPT_BIT(0, "ignore-missing", &flag,
977 + "attempt to remove non-existent note is not an error",
978 + MISSING_OK),
979 OPT_END()
980 };
981 struct notes_tree *t;
@@ -981,10 +987,10 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
987 t = init_notes_check("remove");
988
989 if (!argc) {
984 - retval = remove_one_note(t, "HEAD");
990 + retval = remove_one_note(t, "HEAD", flag);
991 } else {
992 while (*argv) {
987 - retval |= remove_one_note(t, *argv);
993 + retval |= remove_one_note(t, *argv, flag);
994 argv++;
995 }
996 }
t/t3301-notes.sh
+20
@@ -455,6 +455,26 @@ test_expect_success 'removing is atomic' '
455 test "$before" = "$after"
456 '
457
458 +test_expect_success 'removing with --ignore-missing' '
459 + before=$(git rev-parse --verify refs/notes/commits) &&
460 + test_when_finished "git update-ref refs/notes/commits $before" &&
461 +
462 + # We have only two -- add another and make sure it stays
463 + git notes add -m "extra" &&
464 + git notes list HEAD >after-removal-expect &&
465 + git notes remove --ignore-missing HEAD^^ HEAD^^^ HEAD^ &&
466 + git notes list | sed -e "s/ .*//" >actual &&
467 + test_cmp after-removal-expect actual
468 +'
469 +
470 +test_expect_success 'removing with --ignore-missing but bogus ref' '
471 + before=$(git rev-parse --verify refs/notes/commits) &&
472 + test_when_finished "git update-ref refs/notes/commits $before" &&
473 + test_must_fail git notes remove --ignore-missing HEAD^^ HEAD^^^ NO-SUCH-COMMIT &&
474 + after=$(git rev-parse --verify refs/notes/commits) &&
475 + test "$before" = "$after"
476 +'
477 +
478 test_expect_success 'list notes with "git notes list"' '
479 git notes list > output &&
480 test_cmp expect output