notes remove: --ignore-missing
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 May 2011 23:02:58 +0000 (16:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 19 May 2011 17:46:42 +0000 (10:46 -0700)
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>
Documentation/git-notes.txt
builtin/notes.c
t/t3301-notes.sh
index e2e1c4c88de04a951bd0baa1de76ed391b00d512..8bbffdf64858a2f462d8a47d4db136b4d0477dc4 100644 (file)
@@ -17,7 +17,7 @@ SYNOPSIS
 'git notes' merge [-v | -q] [-s <strategy> ] <notes_ref>
 'git notes' merge --commit [-v | -q]
 'git notes' merge --abort [-v | -q]
-'git notes' remove [<object>...]
+'git notes' remove [--ignore-missing] [<object>...]
 'git notes' prune [-n | -v]
 'git notes' get-ref
 
@@ -155,6 +155,10 @@ OPTIONS
        'GIT_NOTES_REF' and the "core.notesRef" configuration.  The ref
        is taken to be in `refs/notes/` if it is not qualified.
 
+--ignore-missing::
+       Do not consider it an error to request removing notes from an
+       object that does not have notes attached to it.
+
 -n::
 --dry-run::
        Do not remove anything; just report the object names whose notes
index 30cee0fd3cf0713502eb7d47c683b7186069bc61..541f776ebb18ef7acbddee17299470538f4415f7 100644 (file)
@@ -953,7 +953,9 @@ static int merge(int argc, const char **argv, const char *prefix)
        return result < 0; /* return non-zero on conflicts */
 }
 
-static int remove_one_note(struct notes_tree *t, const char *name)
+#define MISSING_OK 1
+
+static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag)
 {
        int status;
        unsigned char sha1[20];
@@ -964,12 +966,16 @@ static int remove_one_note(struct notes_tree *t, const char *name)
                fprintf(stderr, _("Object %s has no note\n"), name);
        else
                fprintf(stderr, _("Removing note for object %s\n"), name);
-       return status;
+       return (flag & MISSING_OK) ? 0 : status;
 }
 
 static int remove_cmd(int argc, const char **argv, const char *prefix)
 {
+       unsigned flag = 0;
        struct option options[] = {
+               OPT_BIT(0, "ignore-missing", &flag,
+                       "attempt to remove non-existent note is not an error",
+                       MISSING_OK),
                OPT_END()
        };
        struct notes_tree *t;
@@ -981,10 +987,10 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
        t = init_notes_check("remove");
 
        if (!argc) {
-               retval = remove_one_note(t, "HEAD");
+               retval = remove_one_note(t, "HEAD", flag);
        } else {
                while (*argv) {
-                       retval |= remove_one_note(t, *argv);
+                       retval |= remove_one_note(t, *argv, flag);
                        argv++;
                }
        }
index f49879e034de847cf249b5d4aa507fd62d4abf64..e820a6bc708a85ef05416d090bebe6039ac9ebfe 100755 (executable)
@@ -455,6 +455,26 @@ test_expect_success 'removing is atomic' '
        test "$before" = "$after"
 '
 
+test_expect_success 'removing with --ignore-missing' '
+       before=$(git rev-parse --verify refs/notes/commits) &&
+       test_when_finished "git update-ref refs/notes/commits $before" &&
+
+       # We have only two -- add another and make sure it stays
+       git notes add -m "extra" &&
+       git notes list HEAD >after-removal-expect &&
+       git notes remove --ignore-missing HEAD^^ HEAD^^^ HEAD^ &&
+       git notes list | sed -e "s/ .*//" >actual &&
+       test_cmp after-removal-expect actual
+'
+
+test_expect_success 'removing with --ignore-missing but bogus ref' '
+       before=$(git rev-parse --verify refs/notes/commits) &&
+       test_when_finished "git update-ref refs/notes/commits $before" &&
+       test_must_fail git notes remove --ignore-missing HEAD^^ HEAD^^^ NO-SUCH-COMMIT &&
+       after=$(git rev-parse --verify refs/notes/commits) &&
+       test "$before" = "$after"
+'
+
 test_expect_success 'list notes with "git notes list"' '
        git notes list > output &&
        test_cmp expect output