reflog --expire-unreachable: avoid merge-base computation
authorJunio C Hamano <gitster@pobox.com>
Wed, 7 Apr 2010 18:09:12 +0000 (11:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 7 Apr 2010 18:09:12 +0000 (11:09 -0700)
commitb4ca1db968eb57d9cd869337bffa254e0b2c83bd
treefd771aca19a235e6c102ff46ac4b85f14fd4b9d2
parent902f235378cb2b2f6dd5dd664b9630c95321f0ae
reflog --expire-unreachable: avoid merge-base computation

The option tells the command to expire older reflog entries that refer to
commits that are no longer reachable from the tip of the ref the reflog is
associated with.  To avoid repeated merge_base() invocations, we used to
mark commits that are known to be reachable by walking the history from
the tip until we hit commits that are older than expire-total (which is
the timestamp before which all the reflog entries are expired).

However, it is a different matter if a commit is _not_ known to be
reachable and the commit is known to be unreachable.  Because you can
rewind a ref to an ancient commit and then reset it back to the original
tip, a recent reflog entry can point at a commit that older than the
expire-total timestamp and we shouldn't expire it.  For that reason, we
had to run merge-base computation when a commit is _not_ known to be
reachable.

This introduces a lazy/on-demand traversal of the history to mark
reachable commits in steps.  As before, we mark commits that are newer
than expire-total to optimize the normal case before walking reflog, but
we dig deeper from the commits the initial step left off when we encounter
a commit that is not known to be reachable.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-reflog.c