From d4cfdfa5844187c512482bffb4f165321416dd7f Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Tue, 17 Feb 2026 11:36:23 -0800 Subject: [PATCH] fix: resolve_target fallback via git worktree list for external worktrees Add a git worktree list --porcelain fallback as last resort in resolve_target() before returning "not found". This catches worktrees created outside the gtr-managed directory (e.g. via raw git worktree add) that the directory scan cannot find. Only runs when all fast-path checks fail, so zero performance impact on the happy path. --- lib/core.sh | 18 ++++++++++++++++++ tests/core_resolve_target.bats | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/core.sh b/lib/core.sh index 9622120..ff26de1 100644 --- a/lib/core.sh +++ b/lib/core.sh @@ -299,6 +299,24 @@ resolve_target() { done fi + # Last resort: ask git for all worktrees (catches non-gtr-managed worktrees) + local wt_path wt_branch + while IFS= read -r line; do + case "$line" in + "worktree "*) wt_path="${line#worktree }" ;; + "branch "*) + wt_branch="${line#branch refs/heads/}" + if [ "$wt_branch" = "$identifier" ]; then + local is_main=0 + [ "$wt_path" = "$repo_root" ] && is_main=1 + printf "%s\t%s\t%s\n" "$is_main" "$wt_path" "$wt_branch" + return 0 + fi + ;; + "") wt_path="" ; wt_branch="" ;; + esac + done < <(git -C "$repo_root" worktree list --porcelain 2>/dev/null) + log_error "Worktree not found for branch: $identifier" return 1 } diff --git a/tests/core_resolve_target.bats b/tests/core_resolve_target.bats index 9ad196d..7d8f9b3 100644 --- a/tests/core_resolve_target.bats +++ b/tests/core_resolve_target.bats @@ -81,6 +81,18 @@ teardown() { [ "$status" -eq 1 ] } +# ── porcelain fallback ───────────────────────────────────────────────────────── + +@test "resolve_target finds externally-created worktree via porcelain fallback" { + # Create a worktree with raw git (outside gtr-managed directory) + local ext_dir="${TEST_REPO}-external" + git -C "$TEST_REPO" worktree add "$ext_dir" -b external-branch --quiet + local result + result=$(resolve_target "external-branch" "$TEST_REPO" "$TEST_WORKTREES_DIR" "") + # Assert: found with is_main=0, correct branch, path ends with expected suffix + [[ "$result" == "0"$'\t'*"-external"$'\t'"external-branch" ]] +} + # ── discover_repo_root from worktree ────────────────────────────────────────── @test "discover_repo_root returns main repo root when called from a worktree" {