[PATCH 1/2] git-reflog: add new option '--exclude=' to expire subcommand
From: Brandon Casey <hidden>
Date: 2016-06-15 22:44:43
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
This new option will allow refs to be specified which will be skipped when expiring, i.e. they will not be expired. Currently it is convenient to use the '--all' option to operate on _all_ reflogs. In some cases it may be convenient to operate on _all_ reflogs except one or two or ... The primary motivation behind this option is to allow git-gc to exclude refs/stash when calling git-reflog to expire reflogs. Signed-off-by: Brandon Casey <redacted> --- I had one reservation against using --exclude= as the option name and that is that --exclude= is generally used with a glob. In the future this can easily be extended to accept a glob, and may be necessary depending on how per-branch stashes are implemented. For now it is not necessary (for me). -brandon Documentation/git-reflog.txt | 5 +++++ builtin-reflog.c | 27 ++++++++++++++++++++++++--- t/t1410-reflog.sh | 16 +++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 8492aea..d1c4a14 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt@@ -65,6 +65,11 @@ should not have to ever worry about missing objects, because the current prune and pack-objects know about reflogs and protect objects referred by them. +--exclude=<ref>:: + When expiring, do not operate on the reflog of the named ref. + This option may be used multiple times to exclude more than one ref. + This is not a glob, it is a ref name such as `stash` or `refs/stash`. + --expire=<time>:: Entries older than this time are pruned. Without the option it is taken from configuration `gc.reflogExpire`,
diff --git a/builtin-reflog.c b/builtin-reflog.c
index 897d1dc..9bb964b 100644
--- a/builtin-reflog.c
+++ b/builtin-reflog.c@@ -350,7 +350,9 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) { struct cmd_reflog_expire_cb cb; unsigned long now = time(NULL); - int i, status, do_all; + int i, n, status, do_all; + const char **excludes = NULL; + int num_excludes = 0; git_config(reflog_expire_config, NULL);
@@ -375,6 +377,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) const char *arg = argv[i]; if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n")) cb.dry_run = 1; + else if (!prefixcmp(arg, "--exclude=")) { + excludes = xrealloc(excludes, + sizeof(*excludes) * (num_excludes+1)); + excludes[num_excludes++] = arg+10; + } else if (!prefixcmp(arg, "--expire=")) cb.expire_total = approxidate(arg + 9); else if (!prefixcmp(arg, "--expire-unreachable="))
@@ -415,7 +422,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) for_each_reflog(collect_reflog, &collected); for (i = 0; i < collected.nr; i++) { struct collected_reflog *e = collected.e[i]; - status |= expire_reflog(e->reflog, e->sha1, 0, &cb); + for (n = 0; n < num_excludes; n++) + if (refname_match(excludes[n], e->reflog, + ref_rev_parse_rules)) + break; + if (n == num_excludes) + status |= expire_reflog(e->reflog, e->sha1, 0, + &cb); free(e); } free(collected.e);
@@ -428,8 +441,16 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) status |= error("%s points nowhere!", ref); continue; } - status |= expire_reflog(ref, sha1, 0, &cb); + for (n = 0; n < num_excludes; n++) + if (refname_match(excludes[n], ref, + ref_rev_parse_rules)) + break; + if (n == num_excludes) + status |= expire_reflog(ref, sha1, 0, &cb); } + + free(excludes); + return status; }
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 73f830d..d33f3d0 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh@@ -158,6 +158,19 @@ test_expect_success 'reflog expire' ' check_fsck "dangling commit $K" ' +test_expect_success 'reflog expire --exclude=' ' + + git reflog expire --exclude=master \ + --expire=now \ + --expire-unreachable=now \ + --all && + + loglen=$(wc -l <.git/logs/HEAD) && + test $loglen = 0 && + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 2 +' + test_expect_success 'prune and fsck' ' git prune &&
@@ -188,7 +201,8 @@ test_expect_success 'delete' ' test_tick && git commit -m tiger C && - test 5 = $(git reflog | wc -l) && + test 3 = $(git reflog | wc -l) && + test 5 = $(git reflog show master | wc -l) && git reflog delete master@{1} && git reflog show master > output &&
--
1.5.5.3