mirror of
https://github.com/restic/restic.git
synced 2024-09-10 05:10:32 +02:00
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
|
package walker
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"path"
|
||
|
|
||
|
"github.com/restic/restic/internal/debug"
|
||
|
"github.com/restic/restic/internal/restic"
|
||
|
)
|
||
|
|
||
|
type RejectByNameFunc func(path string) bool
|
||
|
|
||
|
type TreeFilterVisitor struct {
|
||
|
CheckExclude RejectByNameFunc
|
||
|
PrintExclude func(string)
|
||
|
}
|
||
|
|
||
|
func FilterTree(ctx context.Context, repo restic.Repository, nodepath string, nodeID restic.ID, visitor *TreeFilterVisitor) (newNodeID restic.ID, err error) {
|
||
|
curTree, err := restic.LoadTree(ctx, repo, nodeID)
|
||
|
if err != nil {
|
||
|
return restic.ID{}, err
|
||
|
}
|
||
|
|
||
|
debug.Log("filterTree: %s, nodeId: %s\n", nodepath, nodeID.Str())
|
||
|
|
||
|
changed := false
|
||
|
tb := restic.NewTreeJSONBuilder()
|
||
|
for _, node := range curTree.Nodes {
|
||
|
path := path.Join(nodepath, node.Name)
|
||
|
if visitor.CheckExclude(path) {
|
||
|
if visitor.PrintExclude != nil {
|
||
|
visitor.PrintExclude(path)
|
||
|
}
|
||
|
changed = true
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if node.Subtree == nil {
|
||
|
err = tb.AddNode(node)
|
||
|
if err != nil {
|
||
|
return restic.ID{}, err
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
newID, err := FilterTree(ctx, repo, path, *node.Subtree, visitor)
|
||
|
if err != nil {
|
||
|
return restic.ID{}, err
|
||
|
}
|
||
|
if !node.Subtree.Equal(newID) {
|
||
|
changed = true
|
||
|
}
|
||
|
node.Subtree = &newID
|
||
|
err = tb.AddNode(node)
|
||
|
if err != nil {
|
||
|
return restic.ID{}, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if changed {
|
||
|
tree, err := tb.Finalize()
|
||
|
if err != nil {
|
||
|
return restic.ID{}, err
|
||
|
}
|
||
|
|
||
|
// Save new tree
|
||
|
newTreeID, _, _, err := repo.SaveBlob(ctx, restic.TreeBlob, tree, restic.ID{}, false)
|
||
|
debug.Log("filterTree: save new tree for %s as %v\n", nodepath, newTreeID)
|
||
|
return newTreeID, err
|
||
|
}
|
||
|
|
||
|
return nodeID, nil
|
||
|
}
|