From e6c6d2533d4839b2042fdc72d3898d35f5d1a32a Mon Sep 17 00:00:00 2001 From: Rootiest Date: Wed, 9 Sep 2026 21:14:04 -0400 Subject: [PATCH] fix(git-clean): strip the '+' other-worktree marker too git branch -vv marks column 1 with '+' (not '*') for a branch checked out in another linked worktree. Only '*' was stripped from $1, so a gone branch shown with '+' left a bogus "+" entry in $gone_branches that then failed to delete: error: branch '+' not found. Add a regression case reproducing the '+'-marked gone-branch line via the existing git-clean mock handler in tests/test-network-fish.fish. --- functions/git-clean.fish | 7 ++++++- tests/test-network-fish.fish | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/functions/git-clean.fish b/functions/git-clean.fish index c2dbe35..51732c3 100644 --- a/functions/git-clean.fish +++ b/functions/git-clean.fish @@ -44,7 +44,12 @@ function git-clean --description 'Sync main, prune remotes, and delete orphaned git fetch --prune --quiet # 2. Identify orphaned branches and current branch - set -l gone_branches (git branch -vv | awk '/: gone\]/ {gsub(/\*/, ""); print $1}') + # git branch -vv marks column 1 with '*' for the current worktree's + # branch or '+' for a branch checked out in another linked worktree. + # Only '*' was stripped here, so a gone branch checked out elsewhere + # left its '+' glued onto $1, producing a bogus "+" entry that later + # failed to delete ("branch '+' not found"). + set -l gone_branches (git branch -vv | awk '/: gone\]/ {sub(/^[*+]/, ""); print $1}') set -l current_branch (git branch --show-current) if test -n "$gone_branches" diff --git a/tests/test-network-fish.fish b/tests/test-network-fish.fish index 2d170c1..7293627 100644 --- a/tests/test-network-fish.fish +++ b/tests/test-network-fish.fish @@ -535,6 +535,31 @@ begin check "git-clean: detects and deletes orphaned branch" true (string match -q '*Deleting orphaned local branches*' -- $clean_del_out; and echo true; or echo false) check "git-clean: orphaned branch was deleted" false (git rev-parse --verify --quiet orphaned-feat >/dev/null 2>&1; and echo true; or echo false) + # Regression: git branch -vv marks a branch checked out in ANOTHER + # linked worktree with '+', not '*'. Only '*' used to be stripped, so + # a gone branch shown with '+' left a bogus "+" entry that then failed + # to delete ("branch '+' not found"). + reset_mocks + git branch orphaned-worktree-feat + set -l clean_git_handler2 $MOCK_DIR/git_clean_shim2.sh + printf '%s\n' \ + '#!/bin/sh' \ + 'for a in "$@"; do' \ + ' if [ "$a" = "-vv" ]; then' \ + ' echo " main 1234567 [origin/main] initial"' \ + ' echo "+ orphaned-worktree-feat abcdef0 [origin/orphaned-worktree-feat: gone] feature"' \ + ' exit 0' \ + ' fi' \ + done \ + "exec $real_git \"\$@\"" >$clean_git_handler2 + chmod +x $clean_git_handler2 + + set -gx MOCK_GIT_HANDLER $clean_git_handler2 + set -l plus_out (git-clean 2>&1) + check "git-clean: '+' worktree marker does not leak into a branch name" false (string match -q "*branch '+' not found*" -- $plus_out; and echo true; or echo false) + check "git-clean: '+'-marked gone branch is still deleted" false (git rev-parse --verify --quiet orphaned-worktree-feat >/dev/null 2>&1; and echo true; or echo false) + + reset_mocks builtin cd $prev_pwd end