"git notes prune" will remove all notes that annotate unreachable/non- existing objects. The patch includes tests verifying correct behaviour of the new subcommand. Suggested-by: Junio C Hamano <gitster@xxxxxxxxx> Signed-off-by: Johan Herland <johan@xxxxxxxxxxx> --- Documentation/git-notes.txt | 4 +- builtin-notes.c | 28 ++++++++----- t/t3306-notes-prune.sh | 94 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 11 deletions(-) create mode 100755 t/t3306-notes-prune.sh diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index a52d23a..3973f90 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -8,7 +8,7 @@ git-notes - Add/inspect commit notes SYNOPSIS -------- [verse] -'git notes' (edit [-F <file> | -m <msg>] | show | remove) [commit] +'git notes' (edit [-F <file> | -m <msg>] | show | remove | prune) [commit] DESCRIPTION ----------- @@ -37,6 +37,8 @@ remove:: This is equivalent to specifying an empty note message to the `edit` subcommand. +prune:: + Remove all notes for non-existing/unreachable objects. OPTIONS ------- diff --git a/builtin-notes.c b/builtin-notes.c index 7c40075..48bc455 100644 --- a/builtin-notes.c +++ b/builtin-notes.c @@ -21,6 +21,7 @@ static const char * const git_notes_usage[] = { "git notes edit [-m <msg> | -F <file>] [<object>]", "git notes show [<object>]", "git notes remove [<object>]", + "git notes prune", NULL }; @@ -201,7 +202,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix) const char *object_ref; char logmsg[100]; - int edit = 0, show = 0, remove = 0; + int edit = 0, show = 0, remove = 0, prune = 0; const char *msgfile = NULL; struct msg_arg msg = { 0, STRBUF_INIT }; struct option options[] = { @@ -222,8 +223,10 @@ int cmd_notes(int argc, const char **argv, const char *prefix) show = 1; else if (argc && !strcmp(argv[0], "remove")) remove = 1; + else if (argc && !strcmp(argv[0], "prune")) + prune = 1; - if (edit + show + remove != 1) + if (edit + show + remove + prune != 1) usage_with_options(git_notes_usage, options); if ((msg.given || msgfile) && !edit) { @@ -237,7 +240,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix) } object_ref = argc == 2 ? argv[1] : "HEAD"; - if (argc > 2) { + if (argc > 2 || (prune && argc > 1)) { error("too many parameters"); usage_with_options(git_notes_usage, options); } @@ -264,7 +267,7 @@ int cmd_notes(int argc, const char **argv, const char *prefix) return execv_git_cmd(show_args); } - /* edit/remove command */ + /* edit/remove/prune command */ if (remove) strbuf_reset(&buf); @@ -278,12 +281,17 @@ int cmd_notes(int argc, const char **argv, const char *prefix) die_errno("could not open or read '%s'", msgfile); } - create_note(object, &buf, msg.given || msgfile || remove, note, - new_note); - if (is_null_sha1(new_note)) - remove_note(t, object); - else - add_note(t, object, new_note, combine_notes_overwrite); + if (prune) { + hashclr(new_note); + prune_notes(t); + } else { + create_note(object, &buf, msg.given || msgfile || remove, note, + new_note); + if (is_null_sha1(new_note)) + remove_note(t, object); + else + add_note(t, object, new_note, combine_notes_overwrite); + } snprintf(logmsg, sizeof(logmsg), "Note %s by 'git notes %s'", is_null_sha1(new_note) ? "removed" : "added", argv[0]); commit_notes(t, logmsg); diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh new file mode 100755 index 0000000..b0adc7e --- /dev/null +++ b/t/t3306-notes-prune.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +test_description='Test git notes prune' + +. ./test-lib.sh + +test_expect_success 'setup: create a few commits with notes' ' + + : > file1 && + git add file1 && + test_tick && + git commit -m 1st && + git notes edit -m "Note #1" && + : > file2 && + git add file2 && + test_tick && + git commit -m 2nd && + git notes edit -m "Note #2" && + : > file3 && + git add file3 && + test_tick && + git commit -m 3rd && + git notes edit -m "Note #3" +' + +cat > expect <<END_OF_LOG +commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 +Author: A U Thor <author@xxxxxxxxxxx> +Date: Thu Apr 7 15:15:13 2005 -0700 + + 3rd + +Notes: + Note #3 + +commit 08341ad9e94faa089d60fd3f523affb25c6da189 +Author: A U Thor <author@xxxxxxxxxxx> +Date: Thu Apr 7 15:14:13 2005 -0700 + + 2nd + +Notes: + Note #2 + +commit ab5f302035f2e7aaf04265f08b42034c23256e1f +Author: A U Thor <author@xxxxxxxxxxx> +Date: Thu Apr 7 15:13:13 2005 -0700 + + 1st + +Notes: + Note #1 +END_OF_LOG + +test_expect_success 'verify commits and notes' ' + + git log > actual && + test_cmp expect actual +' + +test_expect_success 'remove some commits' ' + + git reset --hard HEAD~2 && + git reflog expire --expire=now HEAD && + git gc --prune=now +' + +test_expect_success 'verify that commits are gone' ' + + ! git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + ! git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 && + git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f +' + +test_expect_success 'verify that notes are still present' ' + + git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && + git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f +' + +test_expect_success 'prune notes' ' + + git notes prune +' + +test_expect_success 'verify that notes are gone' ' + + ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + ! git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && + git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f +' + +test_done -- 1.7.0.rc1.141.gd3fd -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html