git-reflog: add option --rewrite to update reflog entries while expiring
authorBrandon Casey <casey@nrlssc.navy.mil>
Fri, 22 Feb 2008 18:56:50 +0000 (12:56 -0600)
committerJunio C Hamano <gitster@pobox.com>
Sat, 23 Feb 2008 06:57:38 +0000 (22:57 -0800)
Certain sanity checks on the reflog assume that each entry will contain
a reference to the previous entry. i.e. that the "old" sha1 field of a
reflog entry will be equal to the "new" sha1 field of the previous entry.

When reflog entries are deleted, this assumption may not hold. This patch
adds a new option to git-reflog which causes the subcommands "expire" and
"delete" to rewrite the "old" sha1 field of each reflog entry so that it
points to the previous reflog entry.

Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-reflog.c

index 77f70a62ab0f8fed0ceb5f12efac5d5965cbe227..f685d76e8daec5f472475499f58cd03e986f790c 100644 (file)
@@ -15,7 +15,7 @@
 static const char reflog_expire_usage[] =
 "git-reflog (show|expire) [--verbose] [--dry-run] [--stale-fix] [--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...";
 static const char reflog_delete_usage[] =
-"git-reflog delete [--verbose] [--dry-run] <refs>...";
+"git-reflog delete [--verbose] [--dry-run] [--rewrite] <refs>...";
 
 static unsigned long default_reflog_expire;
 static unsigned long default_reflog_expire_unreachable;
@@ -24,6 +24,7 @@ struct cmd_reflog_expire_cb {
        struct rev_info revs;
        int dry_run;
        int stalefix;
+       int rewrite;
        int verbose;
        unsigned long expire_total;
        unsigned long expire_unreachable;
@@ -35,6 +36,7 @@ struct expire_reflog_cb {
        const char *ref;
        struct commit *ref_commit;
        struct cmd_reflog_expire_cb *cmd;
+       unsigned char last_kept_sha1[20];
 };
 
 struct collected_reflog {
@@ -216,6 +218,9 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
        if (timestamp < cb->cmd->expire_total)
                goto prune;
 
+       if (cb->cmd->rewrite)
+               osha1 = cb->last_kept_sha1;
+
        old = new = NULL;
        if (cb->cmd->stalefix &&
            (!keep_entry(&old, osha1) || !keep_entry(&new, nsha1)))
@@ -243,6 +248,7 @@ static int expire_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
                        sha1_to_hex(osha1), sha1_to_hex(nsha1),
                        email, timestamp, sign, zone,
                        message);
+               hashcpy(cb->last_kept_sha1, nsha1);
        }
        if (cb->cmd->verbose)
                printf("keep %s", message);
@@ -364,6 +370,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
                        cb.expire_unreachable = approxidate(arg + 21);
                else if (!strcmp(arg, "--stale-fix"))
                        cb.stalefix = 1;
+               else if (!strcmp(arg, "--rewrite"))
+                       cb.rewrite = 1;
                else if (!strcmp(arg, "--all"))
                        do_all = 1;
                else if (!strcmp(arg, "--verbose"))
@@ -433,6 +441,8 @@ static int cmd_reflog_delete(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 (!strcmp(arg, "--rewrite"))
+                       cb.rewrite = 1;
                else if (!strcmp(arg, "--verbose"))
                        cb.verbose = 1;
                else if (!strcmp(arg, "--")) {