From 9e55d26b693d1591418f3bf7c431a0332d7c8dc0 Mon Sep 17 00:00:00 2001 From: yzxcj797 Date: Sat, 22 Aug 2026 06:40:54 +0800 Subject: [PATCH] Match worktree branch names in the Worktrees pane filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Worktrees pane's '/' filter only matched the worktree name, so searching a branch name — the natural way to find the worktree that has it checked out — returned nothing (#5945). The filter fields now include the worktree's branch alongside its name. Based on the patch attached to the issue by @phanirithvij (adapted: comment added, regression test added). --- pkg/gui/context/worktrees_context.go | 6 +- pkg/gui/context/worktrees_context_test.go | 73 +++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 pkg/gui/context/worktrees_context_test.go diff --git a/pkg/gui/context/worktrees_context.go b/pkg/gui/context/worktrees_context.go index 3e45f2d45..2fa044700 100644 --- a/pkg/gui/context/worktrees_context.go +++ b/pkg/gui/context/worktrees_context.go @@ -16,8 +16,10 @@ var _ types.IListContext = (*WorktreesContext)(nil) func NewWorktreesContext(c *ContextCommon) *WorktreesContext { viewModel := NewFilteredListViewModel( func() []*models.Worktree { return c.Model().Worktrees }, - func(Worktree *models.Worktree) []string { - return []string{Worktree.Name} + // Filtering matches the worktree name AND its branch, so searching a + // branch name surfaces its worktree (#5945). + func(worktree *models.Worktree) []string { + return []string{worktree.Name, worktree.Branch} }, ) diff --git a/pkg/gui/context/worktrees_context_test.go b/pkg/gui/context/worktrees_context_test.go new file mode 100644 index 000000000..7c23b1840 --- /dev/null +++ b/pkg/gui/context/worktrees_context_test.go @@ -0,0 +1,73 @@ +package context + +import ( + "os" + "testing" + + "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/stretchr/testify/assert" +) + +// The Worktrees pane's filter matches the worktree name AND its branch, so +// searching a branch name surfaces its worktree (#5945). Pinned against the +// real FilteredList the context wires up, using the same getFilterFields +// shape NewWorktreesContext passes. +func TestWorktreesFilterMatchesBranchName(t *testing.T) { + worktrees := []*models.Worktree{ + {Name: "frontend", Branch: "feature/login"}, + {Name: "backend", Branch: "main"}, + {Name: "docs", Branch: "docs/rewrite"}, + } + + filtered := NewFilteredList( + func() []*models.Worktree { return worktrees }, + func(worktree *models.Worktree) []string { + return []string{worktree.Name, worktree.Branch} + }, + ) + + getNames := func() []string { + names := make([]string, 0) + for _, w := range filtered.GetFilteredList() { + names = append(names, w.Name) + } + return names + } + + // By worktree name (unchanged behavior). + filtered.SetFilter("front", false) + assert.Equal(t, []string{"frontend"}, getNames()) + + // By branch name — the #5945 ask. + filtered.SetFilter("login", false) + assert.Equal(t, []string{"frontend"}, getNames()) + + // A branch prefix shared by name and branch fields. + filtered.SetFilter("docs", false) + assert.Equal(t, []string{"docs"}, getNames()) + + // No match clears the list. + filtered.SetFilter("nonexistent", false) + assert.Empty(t, getNames()) + + // Clearing the filter restores everything. + filtered.ClearFilter() + assert.Len(t, getFilteredListWorktrees(filtered), 3) +} + +func getFilteredListWorktrees(filtered *FilteredList[*models.Worktree]) []*models.Worktree { + return filtered.GetFilteredList() +} + +// Source pin: the production context must actually wire the branch into its +// filter fields — the behavioral test above constructs its own FilteredList, +// so it cannot detect the wiring regressing. +func TestWorktreesContextWiresBranchIntoFilterFields(t *testing.T) { + source, err := os.ReadFile("worktrees_context.go") + if err != nil { + t.Fatalf("read worktrees_context.go: %v", err) + } + assert.Contains(t, string(source), + "return []string{worktree.Name, worktree.Branch}", + "NewWorktreesContext must include worktree.Branch in getFilterFields (#5945)") +}