mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
4c845597b2
Three follow-ups from the review of #3533, which landed shared-branch retention across the removal surface. Each is small and independent; they share a branch because they came out of the same pass. ## `wt step prune` counted kinds, not outcomes A candidate's kind is what the scan selected, not what the removal took. A branch a sibling worktree still has checked out is retained, so a worktree candidate can take the worktree and leave the branch standing. The summary counted the kind anyway: ```console ○ Worktree directory missing for feature; pruned ↳ branch checked out at ~/code/repo.feature ✓ Pruned 1 branch ← the branch is right there ``` `prune_summary` now counts the planned outcome, so that reads `✓ Pruned 1 worktree` — the stale entry, which is all that went. Both `--format=json` payloads gained `branch_deleted` for the same reason: a consumer reading `{"branch": "feature", "kind": "branch_only"}` would reasonably conclude the branch is gone. The predicate has one home now. `RemoveResult::to_json` already computed `branch_deleted` inline; it moved to `RemoveResult::deletes_branch()` and both callers share it. That incidentally fixes a detached worktree reporting `"branch_deleted": true` beside a null branch — it has no branch to delete. `wt step prune --dry-run` had the same defect and no per-item line to contradict it, so it now predicts retention too. A `Prunable` item has no plan until `try_remove` prunes its stale entry, so the dry run asks `live_sibling_checkout` — the same predicate the plan would. ## `RemoveTarget::Branch` now means "a branch with no worktree" All three callers resolve first and pass `Path` for anything with a worktree, so the arm handling "the branch turned out to have a worktree" was unreachable at selection time — codecov confirmed it never executed. Deleting it would have been enough, but the arm was a live hazard rather than dead weight: the picker builds a fresh `Repository` and re-lists worktrees between selecting a row and removing it, so a `wt switch` in another terminal can give a branch-only row a worktree mid-flight. The old code would then have removed that worktree, from a row that said "delete this branch" — the same defect class #3533 fixed. ```console ✗ Branch feature gained a worktree @ ~/code/repo.feature since it was selected; to remove that worktree, run wt remove ~/code/repo.feature ``` `test_prepare_removal_refuses_branch_that_gained_a_worktree` covers the picker path. I checked it fails when the guard is neutralized rather than passing trivially. ## `affected tests (windows, advisory)` was permanently red git calls a file binary only when it finds a NUL byte in the first 8000, and two of the committed loose objects under `tests/fixtures/*/_git/` are zlib streams small enough to have none. Those diff as text, so `git diff` writes raw deflate into its output, and `cargo affected` aborts decoding it as a string before running a test. Reproduced with `git show <commit> -- <object>` (invalid UTF-8, byte `0x95` at position 5403) and confirmed fixed — the same command now reports `Binary files … differ`. The rest of `_git/` stays text worth reading. ## Testing `prune_summary_counts_a_retained_branch_as_worktree_only` covers the counting; `test_prune_retains_branch_checked_out_in_another_worktree` gained an assertion on the summary line, and I verified it fails when the guard is removed. The six `.snap` changes are all the same added `branch_deleted` key. > _This was written by Claude Code on behalf of max_ --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
26 lines
1.6 KiB
Plaintext
26 lines
1.6 KiB
Plaintext
# Collapse auto-generated files in GitHub PR diffs. These are regenerated by
|
|
# `test_docs_are_in_sync` in tests/integration_tests/readme_sync.rs — edits
|
|
# belong in the primary source (src/cli/mod.rs for command pages,
|
|
# docs/content/*.md for everything else).
|
|
skills/worktrunk/reference/*.md linguist-generated=true
|
|
# Skill-only files and the top-level README symlink are primary sources — edited
|
|
# directly, not regenerated from docs/content/. Exempt them so real edits stay
|
|
# visible in PR diffs.
|
|
skills/worktrunk/reference/README.md linguist-generated=false
|
|
skills/worktrunk/reference/shell-integration.md linguist-generated=false
|
|
skills/worktrunk/reference/troubleshooting.md linguist-generated=false
|
|
docs/static/*.md linguist-generated=true
|
|
docs/static/llms.txt linguist-generated=true
|
|
docs/static/.well-known/agent-skills/index.json linguist-generated=true
|
|
# Shell templates are embedded into the binary at compile time (askama); a
|
|
# CRLF checkout would leak \r into the shell code Windows-built binaries emit.
|
|
templates/* text eol=lf
|
|
# A fixture's object store and index are git's own binary formats, but git only
|
|
# calls a file binary when it finds a NUL in the first 8000 bytes, and a small
|
|
# enough zlib object may have none. Those diff as text, so `git diff` writes raw
|
|
# deflate into its output and any tool that decodes that output as a string
|
|
# fails on it — which is how `cargo affected` came to abort before running a
|
|
# test. The rest of `_git/` (HEAD, config, refs) is text worth reading.
|
|
tests/fixtures/*/_git/objects/** binary
|
|
tests/fixtures/*/_git/index binary
|