Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions cli/bash/commands/basectl/subcommands/gh_branch_worktree.sh
Original file line number Diff line number Diff line change
Expand Up @@ -517,13 +517,14 @@ base_gh_worktree_prune_delete_branch() {
upstream="$(base_gh_branch_upstream "$branch")"
if [[ "$merge_source" != github && -n "$upstream" ]] && ! base_gh_branch_merged_to_ref "$branch" "$upstream"; then
printf 'SKIP-BRANCH %s not fully merged to upstream %s\n' "$branch" "$upstream"
return 0
return 1
fi

if base_gh_branch_delete "$branch" "$merge_source"; then
printf 'DELETE %s\n' "$branch"
else
printf 'SKIP-BRANCH %s git branch -d refused\n' "$branch"
return 1
fi
}

Expand Down Expand Up @@ -621,7 +622,9 @@ base_gh_worktree_prune() {
elif git worktree remove "$path" >/dev/null 2>&1; then
printf 'REMOVE %s (%s)\n' "$path" "$branch"
removed=$((removed + 1))
base_gh_worktree_prune_delete_branch "$branch" "$merge_source"
if ! base_gh_worktree_prune_delete_branch "$branch" "$merge_source"; then
failed=$((failed + 1))
fi
else
printf 'FAIL %s (%s) git worktree remove failed\n' "$path" "$branch"
failed=$((failed + 1))
Expand Down
33 changes: 33 additions & 0 deletions cli/bash/commands/basectl/tests/gh-branch-worktree.bats
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,39 @@ EOF
! git -C "$repo" show-ref --verify --quiet refs/heads/merged-work
}

@test "basectl gh worktree prune reports retained branches after deletion failure" {
local repo worktree

repo="$TEST_TMPDIR/repo"
worktree="$TEST_TMPDIR/merged-worktree"
init_git_repo "$repo"
printf 'hello\n' > "$repo/README.md"
commit_all "$repo" "Initial commit"
git -C "$repo" branch merged-work
git -C "$repo" worktree add "$worktree" merged-work >/dev/null 2>&1

run env \
HOME="$TEST_HOME" \
BASE_HOME="$BASE_REPO_ROOT" \
bash -c '
cd "$1"
source "$BASE_HOME/base_init.sh"
source "$BASE_HOME/cli/bash/commands/basectl/subcommands/gh.sh"
base_gh_worktree_prune_delete_branch() {
printf "SKIP-BRANCH %s simulated branch delete failure\n" "$1"
return 1
}
base_gh_subcommand_main worktree prune --yes
' bash "$repo"

[ "$status" -eq 1 ]
[[ "$output" == *"REMOVE "*"/merged-worktree (merged-work)"* ]]
[[ "$output" == *"SKIP-BRANCH merged-work simulated branch delete failure"* ]]
[[ "$output" == *"Summary: 1 removed, 1 skipped current/default, 0 skipped dirty, 0 skipped unmerged, 1 failed."* ]]
[ ! -e "$worktree" ]
git -C "$repo" show-ref --verify --quiet refs/heads/merged-work
}

@test "basectl gh worktree prune skips dirty worktrees" {
local repo worktree

Expand Down
4 changes: 4 additions & 0 deletions docs/github-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ a merged GitHub PR, then deletes the now-free local branch when safe. Resolve an
reported GitHub verification failures and rerun the preview before applying it
with `--yes`.

If a worktree is removed but its local branch cannot be deleted, the command
retains the branch, reports the incomplete cleanup, and exits nonzero. Resolve
the branch condition before treating the cleanup as complete.

When `basectl gh branch prune` reports branches attached to worktrees, preview
those worktrees with `basectl gh worktree prune`, apply the safe removals with
`basectl gh worktree prune --yes`, and rerun the branch-prune command. The
Expand Down
Loading