Skip to content

Commit 7f71e15

Browse files
committed
search by entire branch list
1 parent fda3c95 commit 7f71e15

4 files changed

Lines changed: 63 additions & 3 deletions

File tree

internal/tui/checkoutview/data.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ type StackRow struct {
6666
Created time.Time
6767
HasCreated bool
6868

69+
// Branches is the full ordered list of branch names in the stack. Only
70+
// BottomBranch and TopBranch are displayed; the complete list exists so
71+
// search can match any branch, including mid-stack ones.
72+
Branches []string
73+
6974
// LocalStack points at the local stack when Type == TypeLocal, so the caller
7075
// can check out its branches directly without cloning. It is nil for
7176
// remote-only rows, which are cloned by stack number instead.
@@ -185,6 +190,10 @@ func localRow(ls *stack.Stack, rs *github.RemoteStack) (StackRow, bool) {
185190
row.BottomBranch = ls.Branches[0].Branch
186191
row.TopBranch = ls.Branches[len(ls.Branches)-1].Branch
187192
}
193+
row.Branches = make([]string, len(ls.Branches))
194+
for i := range ls.Branches {
195+
row.Branches[i] = ls.Branches[i].Branch
196+
}
188197

189198
if rs != nil {
190199
if rs.Number != 0 {
@@ -219,6 +228,10 @@ func remoteRow(rs *github.RemoteStack) (StackRow, bool) {
219228
BottomBranch: rs.PRDetails[0].Head.Ref,
220229
TopBranch: rs.PRDetails[len(rs.PRDetails)-1].Head.Ref,
221230
}
231+
row.Branches = make([]string, len(rs.PRDetails))
232+
for i, p := range rs.PRDetails {
233+
row.Branches[i] = p.Head.Ref
234+
}
222235
if t, ok := parseTime(rs.CreatedAt); ok {
223236
row.Created, row.HasCreated = t, true
224237
}

internal/tui/checkoutview/data_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,31 @@ func TestBuildRows_ClosedNonMergedStackIsKept(t *testing.T) {
219219
assert.Equal(t, StatusCounts{Closed: 2}, rows[0].Status)
220220
}
221221

222+
func TestBuildRows_PopulatesAllBranchesForSearch(t *testing.T) {
223+
local := []stack.Stack{{
224+
Number: 3,
225+
Trunk: stack.BranchRef{Branch: "main"},
226+
Branches: []stack.BranchRef{
227+
{Branch: "a"}, {Branch: "b"}, {Branch: "c"},
228+
},
229+
}}
230+
rows := BuildRows(local, nil)
231+
require.Len(t, rows, 1)
232+
assert.Equal(t, []string{"a", "b", "c"}, rows[0].Branches, "local rows carry every branch name for search")
233+
234+
remote := []github.RemoteStack{{
235+
ID: 1, Number: 9, Base: github.RemoteStackBase{Ref: "main"},
236+
PRDetails: []github.RemoteStackPR{
237+
{Number: 1, State: "open", Head: github.RemoteStackPRHead{Ref: "r1"}},
238+
{Number: 2, State: "open", Head: github.RemoteStackPRHead{Ref: "r2"}},
239+
{Number: 3, State: "open", Head: github.RemoteStackPRHead{Ref: "r3"}},
240+
},
241+
}}
242+
rrows := BuildRows(nil, remote)
243+
require.Len(t, rrows, 1)
244+
assert.Equal(t, []string{"r1", "r2", "r3"}, rrows[0].Branches, "remote rows carry every branch name for search")
245+
}
246+
222247
func TestBuildRows_UntrackedLocalWithMergedPRFlag(t *testing.T) {
223248
local := []stack.Stack{{
224249
Number: 3,

internal/tui/checkoutview/model.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,12 @@ func matchesQuery(r StackRow, q string) bool {
214214
if q == "" {
215215
return true
216216
}
217-
hay := strings.ToLower(strings.Join([]string{
218-
r.NumberDisplay(), r.Summary(), r.Base, r.Type.String(),
219-
}, " "))
217+
// Search the stack number, base, type, and every branch name — including
218+
// mid-stack branches that are not shown in the Branches column.
219+
parts := make([]string, 0, len(r.Branches)+5)
220+
parts = append(parts, r.NumberDisplay(), r.Base, r.Type.String(), r.BottomBranch, r.TopBranch)
221+
parts = append(parts, r.Branches...)
222+
hay := strings.ToLower(strings.Join(parts, " "))
220223
return strings.Contains(hay, q)
221224
}
222225

internal/tui/checkoutview/model_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,25 @@ func TestSearchMatchesNumberAndType(t *testing.T) {
123123
assert.Equal(t, TypeRemote, m.filtered[0].Type)
124124
}
125125

126+
func TestSearchMatchesMidStackBranch(t *testing.T) {
127+
rows := []StackRow{
128+
{Number: 7, Type: TypeLocal, BottomBranch: "feat/bottom", TopBranch: "feat/top",
129+
Branches: []string{"feat/bottom", "feat/middle-xyz", "feat/top"}, Base: "main"},
130+
{Number: 8, Type: TypeRemote, BottomBranch: "other/a", TopBranch: "other/b",
131+
Branches: []string{"other/a", "other/b"}, Base: "main"},
132+
}
133+
m := sized(New(rows))
134+
m = drive(m, runeKey("/"))
135+
for _, r := range "middle" {
136+
m = drive(m, tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{r}})
137+
}
138+
139+
require.Len(t, m.filtered, 1, "a mid-stack branch name should match")
140+
assert.Equal(t, 7, m.filtered[0].Number)
141+
// The matched mid-stack branch is not shown in the Branches column.
142+
assert.NotContains(t, stripANSI(m.View()), "middle-xyz")
143+
}
144+
126145
func TestCursorNavigationClamps(t *testing.T) {
127146
m := sized(New(sampleRows()))
128147
// Up at the top stays at 0.

0 commit comments

Comments
 (0)