forked from TrueCloudLab/restic
find: Correct tree pruning optimization
The `find` command will now take care to only mark trees as "not found" when the pattern couldn't be found within any subtree. Closes #1825, #1823
This commit is contained in:
parent
e2d347a698
commit
ce01ca30d6
1 changed files with 18 additions and 9 deletions
|
@ -144,7 +144,7 @@ func (s *statefulOutput) PrintNormal(prefix string, node *restic.Node) {
|
||||||
Verbosef("\n")
|
Verbosef("\n")
|
||||||
}
|
}
|
||||||
s.oldsn = s.newsn
|
s.oldsn = s.newsn
|
||||||
Verbosef("Found matching entries in snapshot %s\n", s.oldsn.ID())
|
Verbosef("Found matching entries in snapshot %s\n", s.oldsn.ID().Str())
|
||||||
}
|
}
|
||||||
Printf(formatNode(prefix, node, s.ListLong) + "\n")
|
Printf(formatNode(prefix, node, s.ListLong) + "\n")
|
||||||
}
|
}
|
||||||
|
@ -180,17 +180,20 @@ type Finder struct {
|
||||||
notfound restic.IDSet
|
notfound restic.IDSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string) error {
|
// findInTree traverses a tree and outputs matches. foundInSubtree is true if
|
||||||
|
// some match has been found within some subtree. If err is non-nil, the value
|
||||||
|
// of foundInSubtree is invalid.
|
||||||
|
func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string) (foundInSubtree bool, err error) {
|
||||||
if f.notfound.Has(treeID) {
|
if f.notfound.Has(treeID) {
|
||||||
debug.Log("%v skipping tree %v, has already been checked", prefix, treeID)
|
debug.Log("%v skipping tree %v, has already been checked", prefix, treeID)
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.Log("%v checking tree %v\n", prefix, treeID)
|
debug.Log("%v checking tree %v\n", prefix, treeID)
|
||||||
|
|
||||||
tree, err := f.repo.LoadTree(ctx, treeID)
|
tree, err := f.repo.LoadTree(ctx, treeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
|
@ -204,7 +207,7 @@ func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string
|
||||||
|
|
||||||
m, err := path.Match(f.pat.pattern, name)
|
m, err := path.Match(f.pat.pattern, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if m {
|
if m {
|
||||||
|
@ -224,8 +227,13 @@ func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "dir" {
|
if node.Type == "dir" {
|
||||||
if err := f.findInTree(ctx, *node.Subtree, path.Join(prefix, node.Name)); err != nil {
|
foundSubtree, err := f.findInTree(ctx, *node.Subtree, path.Join(prefix, node.Name))
|
||||||
return err
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if foundSubtree {
|
||||||
|
found = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,14 +242,15 @@ func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string
|
||||||
f.notfound.Insert(treeID)
|
f.notfound.Insert(treeID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return found, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error {
|
func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error {
|
||||||
debug.Log("searching in snapshot %s\n for entries within [%s %s]", sn.ID(), f.pat.oldest, f.pat.newest)
|
debug.Log("searching in snapshot %s\n for entries within [%s %s]", sn.ID(), f.pat.oldest, f.pat.newest)
|
||||||
|
|
||||||
f.out.newsn = sn
|
f.out.newsn = sn
|
||||||
return f.findInTree(ctx, *sn.Tree, "/")
|
_, err := f.findInTree(ctx, *sn.Tree, "/")
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
|
Loading…
Reference in a new issue