|
@@ -37,12 +37,12 @@ type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
|
|
|
|
|
|
type currentPath struct {
|
|
|
path string
|
|
|
- f os.FileInfo
|
|
|
+ stat *types.Stat
|
|
|
// fullPath string
|
|
|
}
|
|
|
|
|
|
// doubleWalkDiff walks both directories to create a diff
|
|
|
-func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (err error) {
|
|
|
+func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn, filter FilterFunc) (err error) {
|
|
|
g, ctx := errgroup.WithContext(ctx)
|
|
|
|
|
|
var (
|
|
@@ -86,14 +86,22 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (er
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
- var f os.FileInfo
|
|
|
- k, p := pathChange(f1, f2)
|
|
|
+ var f *types.Stat
|
|
|
+ var f2copy *currentPath
|
|
|
+ if f2 != nil {
|
|
|
+ statCopy := *f2.stat
|
|
|
+ if filter != nil {
|
|
|
+ filter(f2.path, &statCopy)
|
|
|
+ }
|
|
|
+ f2copy = ¤tPath{path: f2.path, stat: &statCopy}
|
|
|
+ }
|
|
|
+ k, p := pathChange(f1, f2copy)
|
|
|
switch k {
|
|
|
case ChangeKindAdd:
|
|
|
if rmdir != "" {
|
|
|
rmdir = ""
|
|
|
}
|
|
|
- f = f2.f
|
|
|
+ f = f2.stat
|
|
|
f2 = nil
|
|
|
case ChangeKindDelete:
|
|
|
// Check if this file is already removed by being
|
|
@@ -101,30 +109,30 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (er
|
|
|
if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
|
|
|
f1 = nil
|
|
|
continue
|
|
|
- } else if rmdir == "" && f1.f.IsDir() {
|
|
|
+ } else if rmdir == "" && f1.stat.IsDir() {
|
|
|
rmdir = f1.path + string(os.PathSeparator)
|
|
|
} else if rmdir != "" {
|
|
|
rmdir = ""
|
|
|
}
|
|
|
f1 = nil
|
|
|
case ChangeKindModify:
|
|
|
- same, err := sameFile(f1, f2)
|
|
|
+ same, err := sameFile(f1, f2copy)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if f1.f.IsDir() && !f2.f.IsDir() {
|
|
|
+ if f1.stat.IsDir() && !f2copy.stat.IsDir() {
|
|
|
rmdir = f1.path + string(os.PathSeparator)
|
|
|
} else if rmdir != "" {
|
|
|
rmdir = ""
|
|
|
}
|
|
|
- f = f2.f
|
|
|
+ f = f2.stat
|
|
|
f1 = nil
|
|
|
f2 = nil
|
|
|
if same {
|
|
|
continue loop0
|
|
|
}
|
|
|
}
|
|
|
- if err := changeFn(k, p, f, nil); err != nil {
|
|
|
+ if err := changeFn(k, p, &StatInfo{f}, nil); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
}
|
|
@@ -159,28 +167,17 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) {
|
|
|
|
|
|
func sameFile(f1, f2 *currentPath) (same bool, retErr error) {
|
|
|
// If not a directory also check size, modtime, and content
|
|
|
- if !f1.f.IsDir() {
|
|
|
- if f1.f.Size() != f2.f.Size() {
|
|
|
+ if !f1.stat.IsDir() {
|
|
|
+ if f1.stat.Size_ != f2.stat.Size_ {
|
|
|
return false, nil
|
|
|
}
|
|
|
|
|
|
- t1 := f1.f.ModTime()
|
|
|
- t2 := f2.f.ModTime()
|
|
|
- if t1.UnixNano() != t2.UnixNano() {
|
|
|
+ if f1.stat.ModTime != f2.stat.ModTime {
|
|
|
return false, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- ls1, ok := f1.f.Sys().(*types.Stat)
|
|
|
- if !ok {
|
|
|
- return false, nil
|
|
|
- }
|
|
|
- ls2, ok := f2.f.Sys().(*types.Stat)
|
|
|
- if !ok {
|
|
|
- return false, nil
|
|
|
- }
|
|
|
-
|
|
|
- return compareStat(ls1, ls2)
|
|
|
+ return compareStat(f1.stat, f2.stat)
|
|
|
}
|
|
|
|
|
|
// compareStat returns whether the stats are equivalent,
|