Skip to content

Commit 53746cf

Browse files
committed
fix(branch_sweep): stop reporting origin/HEAD as an unmerged branch
The first live run listed a branch named `origin` under KEEP with verdict UNKNOWN. No such branch exists: `refs/remotes/origin/HEAD` is a symbolic ref, and git renders its `%(refname:short)` as bare `origin` — which survives both the `origin/` strip and the `!= HEAD` guard, so it fell through to branch_contribution as `origin/origin`, came back UNKNOWN, and was filed as outstanding work. Nothing was ever at risk: UNKNOWN is fail-safe and never enters the delete set. The cost is honesty. It reported PyAutoBrain as having 3 unmerged branches when it has 2, and invited a reader to go looking for work that does not exist — a null result dressed as a finding, which is the D1 mistake docs/agent_failure_modes.md already names. Iterating full refnames and stripping the real prefix removes the ambiguity at the source rather than special-casing the rendered string. The regression test was checked the only way worth trusting: it fails against the old iteration and passes against the new one. It also pins the count, so a future phantom entry fails the assertion rather than quietly inflating a total nobody re-derives. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwqicJpMqmcT5RVbyNwdKq
1 parent 248331c commit 53746cf

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

bin/branch_sweep.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,13 @@ while read -r b; do
182182
fi ;;
183183
*) keep+=("$b $word") ;; # UNKNOWN is never safe
184184
esac
185-
done < <(g for-each-ref --format='%(refname:short)' refs/remotes/origin | sed 's|^origin/||')
185+
# Full refnames, not `:short`. Git abbreviates refs/remotes/origin/HEAD to
186+
# bare `origin`, which survives an `origin/` strip and a `!= HEAD` guard,
187+
# then reads as a branch named "origin" with verdict UNKNOWN — a symbolic
188+
# ref rendered as an unmerged branch. Harmless (UNKNOWN is never deletable)
189+
# but it is a null result dressed as a finding, which is the D1 mistake.
190+
done < <(g for-each-ref --format='%(refname)' refs/remotes/origin \
191+
| sed 's|^refs/remotes/origin/||')
186192

187193
echo
188194
echo "Branch sweep — $OWNER/$NAME (mode: $MODE, base: $BASE)"

tests/test_branch_sweep.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,22 @@ def test_audit_classifies_every_branch(world):
130130
assert "archive/condemned/something\tgut-transit-ref" in out
131131

132132

133+
def test_symbolic_head_is_not_reported_as_a_branch(world):
134+
"""refs/remotes/origin/HEAD must not surface as a branch called "origin".
135+
136+
Git abbreviates that ref to bare `origin`, which slips past an `origin/`
137+
strip and a `!= HEAD` guard and then lands in KEEP with verdict UNKNOWN —
138+
a symbolic ref rendered as unmerged work. It was never deletable, so the
139+
cost is a wrong count and a reader misled about what is outstanding.
140+
"""
141+
clone, _, bin_dir = world
142+
out = _sweep(clone, bin_dir).stdout
143+
assert "origin\tUNKNOWN" not in out
144+
assert "\n origin\t" not in out
145+
# the real answer for this fixture, with nothing invented alongside it
146+
assert "1 unmerged" in out
147+
148+
133149
def test_audit_never_deletes(world):
134150
clone, origin, bin_dir = world
135151
before = _git(origin, "for-each-ref", "--format=%(refname)", "refs/heads")

0 commit comments

Comments
 (0)