docs(cache): recommend delete-on-merge, and say what ancestry still covers
CI / shellcheck + selftests (pull_request) Successful in 1m27s

`daniel/zemyna` enabled `default_delete_branch_after_merge` after this
branch was written, so the deleted-branch signal will fire there on
future merges. That makes the setting worth recommending — it is the
cheapest case for this scheme, decidable from `ls-remote` with no
checkout, no objects and no walk — and it does not make the ancestry
signal redundant.

Three things it leaves behind, now enumerated in the README's eviction
section rather than implied: every branch merged before the setting was
turned on, of which zemyna carried 48 and which nothing retroactively
deletes; every merge whose deletion the forge declines or is never asked
to make, since it is best-effort and silent and an API merge without the
flag never asks; and every repo that has not enabled it, which is the
default.

Two present-tense claims about one repo's configuration are reworded
into the conditions they were standing in for, in prune-cache.sh's
header and beside is_merged_dead, plus the two in the selftest that
asserted the forge keeps branches rather than describing the fixture.
No behaviour change; the suite is green and unchanged at 61 assertions.

Refs #20.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JXMQCJ5Eg5f9G9cfYzyh4Z
This commit is contained in:
2026-09-07 00:27:11 -05:00
co-authored by Claude Fable 5.1
parent 24f87a6b98
commit 38a6387936
3 changed files with 34 additions and 16 deletions
+5 -5
View File
@@ -46,10 +46,10 @@
# empty a tree its owner may still restore under a live cache name. Its
# fixture is an OLD directory renamed a moment ago — production's shape,
# and what lets it tell the two timestamps apart.
# 15. A MERGED-BUT-UNDELETED BRANCH IS DEAD TOO. This forge keeps branches
# after merge, so `ls-remote` reports them forever and scenario 1's
# signal never fires for them — which is how three 40 GB caches sat on a
# full volume until somebody removed them by hand (gitdan-actions#20). A
# 15. A MERGED-BUT-UNDELETED BRANCH IS DEAD TOO. A branch the forge did not
# delete at merge stays on `ls-remote` forever, so scenario 1's signal
# never fires for it — which is how three 40 GB caches sat on a full
# volume until somebody removed them by hand (gitdan-actions#20). A
# branch whose tip is an ancestor of a protected branch's tip is pruned
# like a deleted one; an unmerged branch beside it is not.
# 16. AND "CANNOT TELL" IS STILL NOT DEATH, at both granularities: a branch
@@ -314,7 +314,7 @@ assert_log "may still be evicting it" "the deferral gives its actual reason"
echo
echo "=== 15: a merged-but-undeleted branch is dead too ==="
# This forge keeps a PR's branch after the merge, so `ls-remote` reports it
# A branch the forge did not delete at merge, which `ls-remote` then reports
# forever. Built the way that happens: a branch merged into dev with a merge
# commit, still pushed, beside one branched at the same point and NOT merged.
git="git -c user.email=t@t -c user.name=t -c commit.gpgsign=false"
+8 -4
View File
@@ -28,8 +28,9 @@
# removed UNCONDITIONALLY, not gated on free space. A directory for a
# branch nothing will build again is pure loss; waiting for disk pressure
# to notice means paying for it until then. Two signals make a branch
# dead, and the second exists because the first alone is inert on a forge
# that keeps branches after merge (gitdan-actions#20):
# dead, and the second exists because the first alone is inert wherever
# a merged branch stays on origin — the default, and still the outcome
# whenever delete-on-merge declines or is not asked (gitdan-actions#20):
#
# DELETED — the branch is no longer on origin at all.
# MERGED — the branch is still on origin, but its tip is an ancestor
@@ -434,8 +435,11 @@ fi
#
# True when the branch this directory belongs to is still on origin but every
# commit it holds is already on a protected branch — a merged PR whose branch
# the forge did not delete, which is the case zemyna hits on every merge and
# which the deleted-branch signal above can never see.
# the forge did not delete, which the deleted-branch signal above can never
# see. Enabling delete-on-merge narrows this to the branches merged before it
# was enabled, the ones its deletion declines (protected, or used by another
# open PR), and the merges that never ask (an API merge without the flag);
# see README's eviction section.
#
# Memoised per tip because target-<key> and snapshot-<key> share one branch,
# and because the "cannot tell" warning belongs to the branch rather than to