# resume picker: make worktree porcelain parsing block-scoped (trail finding)

`5ef1842`→[main](/content/gh/entireio/cli/commits/main/index.html)·

Soph·1mo ago·2 files·+59 added/-5 removed

Factor the `git worktree list --porcelain` parsing in branchCheckedOutElsewhere into parseWorktreeForBranch and make it block-scoped: reset the worktree path at each blank-line block boundary and only consider a `branch` line when a worktree line was seen in the same block. A detached worktree (no branch line) can no longer pair a branch with a stale path or return an empty path. Also drops the now-dead rawRoot!="" guard (the empty case returns earlier).

Adds TestParseWorktreeForBranch covering a detached worktree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Changes

2

- cmd/entire/cli

- Mresume_picker.go+17/-5

- Mresume_picker_test.go+42

```
440 unmodified lines

```go

dec := exec.CommandContext(ctx, "git", "worktree", "list", "--porcelain")
if rawRoot != "" {
    gitCmd.Dir = rawRoot
}
gitCmd.Dir = rawRoot
out, err := gitCmd.Output()
if err != nil {
    return "", false
}

return parseWorktreeForBranch(string(out), branch, currentRoot)
}

// parseWorktreeForBranch scans `git worktree list --porcelain` output and returns
// the path of a worktree (other than currentRoot) that has branch checked out.
//
// Each worktree is a block beginning with a `worktree <path>` line and separated
// by a blank line; a `branch <ref>` line only appears for non-detached worktrees.
// curPath is reset at each block boundary and a branch line is only considered
// when a worktree line was seen in the same block, so a detached worktree (no
// branch line) can never pair a branch with a stale path or return an empty one.
func parseWorktreeForBranch(porcelain, branch, currentRoot string) (string, bool) {
	var curPath string
	for _, line := range strings.Split(string(out), "\n") {
	for _, line := range strings.Split(porcelain, "\n") {
		switch {
		case line == "":
			curPath = "" // block boundary
		case strings.HasPrefix(line, "worktree "):
			curPath = strings.TrimPrefix(line, "worktree ")
		case strings.HasPrefix(line, "branch "):
		case strings.HasPrefix(line, "branch ") && curPath != "":
			name := strings.TrimPrefix(strings.TrimPrefix(line, "branch "), "refs/heads/")
			if name == branch && normalizeWorktreePath(curPath) != currentRoot {
				return curPath, true
			}
		}
	}
}

Mcmd/entire/cli/resume_picker.go+17/-5

```

480 unmodified lines

```go

// TestParseWorktreeForBranch covers the porcelain parser, including a detached
// worktree (no branch line) that must not cause a stale or empty-path match.
func TestParseWorktreeForBranch(t *testing.T) {
	t.Parallel()

porcelain := strings.Join([]string{
		"worktree /repo/main",
		"HEAD 1111111111111111111111111111111111111111",
		"branch refs/heads/main",
		"",
		"worktree /repo/wt-feat",
		"HEAD 2222222222222222222222222222222222222222",
		"branch refs/heads/feat",
		"",
		"worktree /repo/wt-detached",
		"HEAD 3333333333333333333333333333333333333333",
		"detached",
		"",
	}, "\n")

// A branch checked out in another worktree is found, with its path.
	if path, ok := parseWorktreeForBranch(porcelain, "feat", "/repo/main"); !ok || path != "/repo/wt-feat" {
		t.Errorf("feat: got (%q, %v), want (/repo/wt-feat, true)", path, ok)
	}

// The current worktree's own branch is not "elsewhere".
	if path, ok := parseWorktreeForBranch(porcelain, "main", "/repo/main"); ok {
		t.Errorf("main from its own worktree should not match, got (%q, %v)", path, ok)
	}

// A branch on no worktree is not found.
	if _, ok := parseWorktreeForBranch(porcelain, "nope", "/repo/main"); ok {
		t.Error("unknown branch should not match")
	}

// A name equal to the detached worktree's path must not match (the detached
	// block has no branch line, so nothing is attributed to it).
	if _, ok := parseWorktreeForBranch(porcelain, "/repo/wt-detached", "/repo/main"); ok {
		t.Error("detached worktree must not produce a branch match")
	}
}

// TestBranchCheckedOutElsewhere verifies worktree awareness: a branch checked
// out in another worktree is detected (with its path), while the current
// worktree's own branch and unknown branches are not flagged.
