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" {