Skip to content

Commit 6d751be

Browse files
peffgitster
authored andcommitted
refs: omit dangling symrefs when using GIT_REF_PARANOIA
Dangling symrefs aren't actually a corruption problem. It's perfectly fine for refs/remotes/origin/HEAD to point to an unborn branch. And in particular, if you are trying to establish reachability, a symref that points nowhere doesn't matter either way. Any ref it could point to will be examined during the rest of the traversal. It's possible that a symref pointing nowhere _could_ be a sign that the ref it was meant to point to was deleted accidentally (e.g., via corruption). But there is no particular reason to think that is true for any given case, and in the meantime, GIT_REF_PARANOIA kicking in automatically for some operations means they'll fail unnecessarily. So let's loosen it just a bit. The new test in t5312 shows off an example that is safe, but currently fails (and no longer does after this patch). Note that we don't do anything if the caller explicitly asked for DO_FOR_EACH_INCLUDE_BROKEN. In that case they may be looking for dangling symrefs themselves, and setting GIT_REF_PARANOIA should not _loosen_ things from what the caller asked for. Signed-off-by: Jeff King <[email protected]> Reviewed-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8dccb22 commit 6d751be

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

refs.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,10 +1418,14 @@ struct ref_iterator *refs_ref_iterator_begin(
14181418
{
14191419
struct ref_iterator *iter;
14201420

1421-
if (ref_paranoia < 0)
1422-
ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1423-
if (ref_paranoia)
1424-
flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1421+
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
1422+
if (ref_paranoia < 0)
1423+
ref_paranoia = git_env_bool("GIT_REF_PARANOIA", 0);
1424+
if (ref_paranoia) {
1425+
flags |= DO_FOR_EACH_INCLUDE_BROKEN;
1426+
flags |= DO_FOR_EACH_OMIT_DANGLING_SYMREFS;
1427+
}
1428+
}
14251429

14261430
iter = refs->be->iterator_begin(refs, prefix, flags);
14271431

t/t5312-prune-corruption.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ test_expect_success 'destructive repack keeps packed object' '
6262
git cat-file -e $bogus
6363
'
6464

65+
test_expect_success 'destructive repack not confused by dangling symref' '
66+
test_when_finished "git symbolic-ref -d refs/heads/dangling" &&
67+
git symbolic-ref refs/heads/dangling refs/heads/does-not-exist &&
68+
git repack -ad &&
69+
test_must_fail git cat-file -e $bogus
70+
'
71+
6572
# We create two new objects here, "one" and "two". Our
6673
# main branch points to "two", which is deleted,
6774
# corrupting the repository. But we'd like to make sure

0 commit comments

Comments
 (0)