Skip to content

Commit 438a37f

Browse files
authored
git: worktree, optimize infiles function for very large repos (#1853)
* git: worktree, optimize infiles function for very large repos
1 parent 67c7006 commit 438a37f

1 file changed

Lines changed: 22 additions & 11 deletions

File tree

worktree.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) ([]
385385
return nil, err
386386
}
387387

388-
var removedFiles []string
388+
removedFiles := make([]string, 0, len(changes))
389+
filesMap := buildFilePathMap(files)
389390
for _, ch := range changes {
390391
a, err := ch.Action()
391392
if err != nil {
@@ -407,7 +408,7 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) ([]
407408
}
408409

409410
if len(files) > 0 {
410-
contains := inFiles(files, name)
411+
contains := inFiles(filesMap, name)
411412
if !contains {
412413
continue
413414
}
@@ -436,15 +437,11 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) ([]
436437
return removedFiles, w.r.Storer.SetIndex(idx)
437438
}
438439

439-
func inFiles(files []string, v string) bool {
440+
// inFiles checks if the given file is in the list of files. The incoming filepaths in files should be cleaned before calling this function.
441+
func inFiles(files map[string]struct{}, v string) bool {
440442
v = filepath.Clean(v)
441-
for _, s := range files {
442-
if filepath.Clean(s) == v {
443-
return true
444-
}
445-
}
446-
447-
return false
443+
_, exists := files[v]
444+
return exists
448445
}
449446

450447
func (w *Worktree) resetWorktree(t *object.Tree, files []string) error {
@@ -459,6 +456,7 @@ func (w *Worktree) resetWorktree(t *object.Tree, files []string) error {
459456
}
460457
b := newIndexBuilder(idx)
461458

459+
filesMap := buildFilePathMap(files)
462460
for _, ch := range changes {
463461
if err := w.validChange(ch); err != nil {
464462
return err
@@ -476,7 +474,7 @@ func (w *Worktree) resetWorktree(t *object.Tree, files []string) error {
476474
continue
477475
}
478476

479-
contains := inFiles(files, file)
477+
contains := inFiles(filesMap, file)
480478
if !contains {
481479
continue
482480
}
@@ -1206,3 +1204,16 @@ func (b *indexBuilder) Add(e *index.Entry) {
12061204
func (b *indexBuilder) Remove(name string) {
12071205
delete(b.entries, filepath.ToSlash(name))
12081206
}
1207+
1208+
// buildFilePathMap creates a map of cleaned file paths for efficient lookup.
1209+
// Returns nil if the input slice is empty.
1210+
func buildFilePathMap(files []string) map[string]struct{} {
1211+
if len(files) == 0 {
1212+
return nil
1213+
}
1214+
filesMap := make(map[string]struct{}, len(files))
1215+
for _, f := range files {
1216+
filesMap[filepath.Clean(f)] = struct{}{}
1217+
}
1218+
return filesMap
1219+
}

0 commit comments

Comments
 (0)