{"thread":{"id":"13903","subject":"[PATCH 1/2] git-reflog: add new option '--exclude=' to expire subcommand","startedAt":"2008-06-11T21:28:45Z","lastAt":"2008-06-11T21:28:45Z","messageCount":1,"participants":["Brandon Casey"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"79505","messageId":"OB99Y9Hiy2c1naDAzYj91bRmhr-KtTLrzzhzcVSN6-blyrxKhqEWtg@cipher.nrlssc.navy.mil","threadId":"13903","inReplyTo":null,"subject":"[PATCH 1/2] git-reflog: add new option '--exclude=' to expire subcommand","fromName":"Brandon Casey","fromEmail":"casey@nrlssc.navy.mil","sentAt":"2008-06-11T21:28:45Z","receivedAt":"2008-06-11T21:28:45Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"This new option will allow refs to be specified which will be skipped\nwhen expiring, i.e. they will not be expired. Currently it is convenient\nto use the '--all' option to operate on _all_ reflogs. In some cases it\nmay be convenient to operate on _all_ reflogs except one or two or ...\n\nThe primary motivation behind this option is to allow git-gc to exclude\nrefs/stash when calling git-reflog to expire reflogs.\n\nSigned-off-by: Brandon Casey <casey@nrlssc.navy.mil>\n---\n\n\nI had one reservation against using --exclude= as the option name and that\nis that --exclude= is generally used with a glob. In the future this can easily\nbe extended to accept a glob, and may be necessary depending on how per-branch\nstashes are implemented. For now it is not necessary (for me).\n\n-brandon\n\n\n Documentation/git-reflog.txt |    5 +++++\n builtin-reflog.c             |   27 ++++++++++++++++++++++++---\n t/t1410-reflog.sh            |   16 +++++++++++++++-\n 3 files changed, 44 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt\nindex 8492aea..d1c4a14 100644\n--- a/Documentation/git-reflog.txt\n+++ b/Documentation/git-reflog.txt\n@@ -65,6 +65,11 @@ should not have to ever worry about missing objects, because the current\n prune and pack-objects know about reflogs and protect objects referred by\n them.\n \n+--exclude=<ref>::\n+\tWhen expiring, do not operate on the reflog of the named ref.\n+\tThis option may be used multiple times to exclude more than one ref.\n+\tThis is not a glob, it is a ref name such as `stash` or `refs/stash`.\n+\n --expire=<time>::\n \tEntries older than this time are pruned.  Without the\n \toption it is taken from configuration `gc.reflogExpire`,\ndiff --git a/builtin-reflog.c b/builtin-reflog.c\nindex 897d1dc..9bb964b 100644\n--- a/builtin-reflog.c\n+++ b/builtin-reflog.c\n@@ -350,7 +350,9 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n {\n \tstruct cmd_reflog_expire_cb cb;\n \tunsigned long now = time(NULL);\n-\tint i, status, do_all;\n+\tint i, n, status, do_all;\n+\tconst char **excludes = NULL;\n+\tint num_excludes = 0;\n \n \tgit_config(reflog_expire_config, NULL);\n \n@@ -375,6 +377,11 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n \t\tconst char *arg = argv[i];\n \t\tif (!strcmp(arg, \"--dry-run\") || !strcmp(arg, \"-n\"))\n \t\t\tcb.dry_run = 1;\n+\t\telse if (!prefixcmp(arg, \"--exclude=\")) {\n+\t\t\texcludes = xrealloc(excludes,\n+\t\t\t\tsizeof(*excludes) * (num_excludes+1));\n+\t\t\texcludes[num_excludes++] = arg+10;\n+\t\t}\n \t\telse if (!prefixcmp(arg, \"--expire=\"))\n \t\t\tcb.expire_total = approxidate(arg + 9);\n \t\telse if (!prefixcmp(arg, \"--expire-unreachable=\"))\n@@ -415,7 +422,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n \t\tfor_each_reflog(collect_reflog, &collected);\n \t\tfor (i = 0; i < collected.nr; i++) {\n \t\t\tstruct collected_reflog *e = collected.e[i];\n-\t\t\tstatus |= expire_reflog(e->reflog, e->sha1, 0, &cb);\n+\t\t\tfor (n = 0; n < num_excludes; n++)\n+\t\t\t\tif (refname_match(excludes[n], e->reflog,\n+\t\t\t\t\t    ref_rev_parse_rules))\n+\t\t\t\t\tbreak;\n+\t\t\tif (n == num_excludes)\n+\t\t\t\tstatus |= expire_reflog(e->reflog, e->sha1, 0,\n+\t\t\t\t\t&cb);\n \t\t\tfree(e);\n \t\t}\n \t\tfree(collected.e);\n@@ -428,8 +441,16 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)\n \t\t\tstatus |= error(\"%s points nowhere!\", ref);\n \t\t\tcontinue;\n \t\t}\n-\t\tstatus |= expire_reflog(ref, sha1, 0, &cb);\n+\t\tfor (n = 0; n < num_excludes; n++)\n+\t\t\tif (refname_match(excludes[n], ref,\n+\t\t\t\t    ref_rev_parse_rules))\n+\t\t\t\tbreak;\n+\t\tif (n == num_excludes)\n+\t\t\tstatus |= expire_reflog(ref, sha1, 0, &cb);\n \t}\n+\n+\tfree(excludes);\n+\n \treturn status;\n }\n \ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex 73f830d..d33f3d0 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -158,6 +158,19 @@ test_expect_success 'reflog expire' '\n \tcheck_fsck \"dangling commit $K\"\n '\n \n+test_expect_success 'reflog expire --exclude=' '\n+\n+\tgit reflog expire --exclude=master \\\n+\t\t--expire=now \\\n+\t\t--expire-unreachable=now \\\n+\t\t--all &&\n+\n+\tloglen=$(wc -l <.git/logs/HEAD) &&\n+\ttest $loglen = 0 &&\n+\tloglen=$(wc -l <.git/logs/refs/heads/master) &&\n+\ttest $loglen = 2\n+'\n+\n test_expect_success 'prune and fsck' '\n \n \tgit prune &&\n@@ -188,7 +201,8 @@ test_expect_success 'delete' '\n \ttest_tick &&\n \tgit commit -m tiger C &&\n \n-\ttest 5 = $(git reflog | wc -l) &&\n+\ttest 3 = $(git reflog | wc -l) &&\n+\ttest 5 = $(git reflog show master | wc -l) &&\n \n \tgit reflog delete master@{1} &&\n \tgit reflog show master > output &&\n-- \n1.5.5.3\n"}]}