Skip to content

Commit 5133ead

Browse files
committed
Revert "reflog expire: don't use lookup_commit_reference_gently()"
During Git 2.35 timeframe, daf1d82 (reflog expire: don't use lookup_commit_reference_gently(), 2021-12-22) replaced a call to lookup_commit_reference_gently() with a call to lookup_commit(). What it failed to consider was that our refs do not necessarily point at commits (most notably, we have annotated and signed tags), and more importantly that lookup_commit() does not dereference a tag to return a commit; instead it returns NULL when a tag is given. Since the commit returned is used as a starting point for the reachability check, this ejected the commits that are reachable only by an annotated tag out of the set of reachable commits, breaking the computation to correctly implement the "--expire-unreachable" option. We also started giving an error message that the API function expected to be fed a commit object. This problem hasn't been reported or noticed for a long time, probably because the "refs/tags/" hierarchy by default is not covered by reflogs, as nobody usually moves tags. Revert the change to correctly find the commit pointed at by the ref to restore the previous behaviour, but do so only in a more modern codebase, as we had significant code churn since then and it is not grave enough to worry about for older maintenance tracks. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3c2a3fd commit 5133ead

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

reflog.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ void reflog_expiry_prepare(const char *refname,
330330
if (!cb->cmd.expire_unreachable || is_head(refname)) {
331331
cb->unreachable_expire_kind = UE_HEAD;
332332
} else {
333-
commit = lookup_commit(the_repository, oid);
333+
commit = lookup_commit_reference_gently(the_repository,
334+
oid, 1);
334335
if (commit && is_null_oid(&commit->object.oid))
335336
commit = NULL;
336337
cb->unreachable_expire_kind = commit ? UE_NORMAL : UE_ALWAYS;

t/t1410-reflog.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ test_expect_success rewind '
146146
test_line_count = 5 output
147147
'
148148

149+
test_expect_success 'reflog expire should not barf on an annotated tag' '
150+
test_when_finished "git tag -d v0.tag || :" &&
151+
git -c core.logAllRefUpdates=always \
152+
tag -a -m "tag name" v0.tag main &&
153+
git reflog expire --dry-run refs/tags/v0.tag 2>err &&
154+
test_grep ! "error: [Oo]bject .* not a commit" err
155+
'
156+
149157
test_expect_success 'corrupt and check' '
150158
151159
corrupt $F &&

0 commit comments

Comments
 (0)