Skip to content

Commit

Permalink
feat: optimize git walker
Browse files Browse the repository at this point in the history
Signed-off-by: Brian McGee <[email protected]>
  • Loading branch information
brianmcgee committed May 7, 2024
1 parent 8b92dca commit 2e77e12
Showing 1 changed file with 52 additions and 10 deletions.
62 changes: 52 additions & 10 deletions walk/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package walk

import (
"context"
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"

"github.com/charmbracelet/log"
"github.com/go-git/go-git/v5/plumbing/format/index"

"github.com/go-git/go-git/v5"
)
Expand Down Expand Up @@ -39,9 +38,57 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
return fmt.Errorf("failed to open git index: %w", err)
}

// cache in-memory whether a path is present in the git index
var cache map[string]bool

for path := range g.paths {

err = filepath.Walk(path, func(path string, info fs.FileInfo, err error) error {
if path == g.root {
// we can just iterate the index entries
for _, entry := range idx.Entries {
select {
case <-ctx.Done():
return ctx.Err()
default:
path := filepath.Join(g.root, entry.Name)

// stat the file
info, err := os.Lstat(path)

file := File{
Path: path,
RelPath: relPathFn(path),
Info: info,
}

if err = fn(&file, err); err != nil {
return err
}
}
}
continue
}

// otherwise we ensure the git index entries are cached and then check if they are in the git index
if cache == nil {
cache = make(map[string]bool)
for _, entry := range idx.Entries {
cache[entry.Name] = true
}
}

relPath, err := filepath.Rel(g.root, path)
if err != nil {
return fmt.Errorf("failed to find relative path for %v: %w", path, err)
}

_, ok := cache[relPath]
if !(path == g.root || ok) {
log.Debugf("path %v not found in git index, skipping", path)
continue
}

return filepath.Walk(path, func(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
}
Expand All @@ -51,9 +98,8 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {
return err
}

if _, err = idx.Entry(relPath); errors.Is(err, index.ErrEntryNotFound) {
// we skip this path as it's not staged
log.Debugf("Path not found in git index, skipping: %v, %v", relPath, path)
if _, ok := cache[relPath]; !ok {
log.Debugf("path %v not found in git index, skipping", path)
return nil
}

Expand All @@ -65,10 +111,6 @@ func (g *gitWalker) Walk(ctx context.Context, fn WalkFunc) error {

return fn(&file, err)
})
if err != nil {
return err
}

}

return nil
Expand Down

0 comments on commit 2e77e12

Please sign in to comment.