1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-11-22 04:42:37 +03:00

Use git ls-files to list all file suggestions

This commit is contained in:
Stefan Haller
2025-11-20 08:41:44 +01:00
parent 9d24963ea0
commit 1c1676a5d9
3 changed files with 63 additions and 13 deletions

View File

@@ -451,3 +451,19 @@ func (self *WorkingTreeCommands) MergeFileForObjectIDs(strategy string, oursID s
return self.cmd.New(cmdArgs).RunWithOutput() return self.cmd.New(cmdArgs).RunWithOutput()
} }
// Returns all tracked files in the repo (not in the working tree). The returned entries are
// relative paths to the repo root, using '/' as the path separator on all platforms.
// Does not really belong in WorkingTreeCommands, but it's close enough, and we don't seem to have a
// better place for it right now.
func (self *WorkingTreeCommands) AllRepoFiles() ([]string, error) {
cmdArgs := NewGitCmd("ls-files").Arg("-z").ToArgv()
output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
if err != nil {
return nil, err
}
if output == "" {
return []string{}, nil
}
return strings.Split(strings.TrimRight(output, "\x00"), "\x00"), nil
}

View File

@@ -563,3 +563,32 @@ func TestWorkingTreeResetHard(t *testing.T) {
}) })
} }
} }
func TestWorkingTreeCommands_AllRepoFiles(t *testing.T) {
scenarios := []struct {
name string
runner *oscommands.FakeCmdObjRunner
expected []string
}{
{
name: "no files",
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"ls-files", "-z"}, "", nil),
expected: []string{},
},
{
name: "two files",
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"ls-files", "-z"}, "dir/file1.txt\x00dir2/file2.go\x00", nil),
expected: []string{"dir/file1.txt", "dir2/file2.go"},
},
}
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner})
result, err := instance.AllRepoFiles()
assert.NoError(t, err)
assert.Equal(t, s.expected, result)
})
}
}

View File

@@ -2,15 +2,14 @@ package helpers
import ( import (
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/jesseduffield/generics/set"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/jesseduffield/minimal/gitignore"
"github.com/samber/lo" "github.com/samber/lo"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"gopkg.in/ozeidan/fuzzy-patricia.v3/patricia" "gopkg.in/ozeidan/fuzzy-patricia.v3/patricia"
@@ -92,22 +91,28 @@ func (self *SuggestionsHelper) GetBranchNameSuggestionsFunc() func(string) []*ty
func (self *SuggestionsHelper) GetFilePathSuggestionsFunc() func(string) []*types.Suggestion { func (self *SuggestionsHelper) GetFilePathSuggestionsFunc() func(string) []*types.Suggestion {
_ = self.c.WithWaitingStatus(self.c.Tr.LoadingFileSuggestions, func(gocui.Task) error { _ = self.c.WithWaitingStatus(self.c.Tr.LoadingFileSuggestions, func(gocui.Task) error {
trie := patricia.NewTrie() trie := patricia.NewTrie()
// load every non-gitignored file in the repo
ignore, err := gitignore.FromGit() // load every file in the repo
files, err := self.c.Git().WorkingTree.AllRepoFiles()
if err != nil { if err != nil {
return err return err
} }
err = ignore.Walk(".", seen := set.New[string]()
func(path string, info os.FileInfo, err error) error { for _, file := range files {
if err != nil { // For every file we also want to add its parent directories, but only once.
return err for i := range len(file) {
if file[i] == '/' {
dir := file[:i]
if !seen.Includes(dir) {
trie.Insert(patricia.Prefix(dir), dir)
seen.Add(dir)
} }
if path != "." {
trie.Insert(patricia.Prefix(path), path)
} }
return nil }
})
trie.Insert(patricia.Prefix(file), file)
}
// cache the trie for future use // cache the trie for future use
self.c.Model().FilesTrie = trie self.c.Model().FilesTrie = trie