1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2025-03-09 00:00:02 +01:00

restic rewrite: correct the problems created by a git rebase:

cmd_rewrite.go: missed out on gatherFilters
cmd_rewrite_integration_test.go: missing declaration of `strings`
rewriter.go: changed logic around `KeepEmptyDirecoryGlobal` and the integrity of
  empty subdirectories
rewriter_test.go: missing seconf parameter for `NewSnapshotSizeRewriter`.
This commit is contained in:
Winfried Plappert 2025-02-19 13:01:23 +00:00
parent 270562e8d9
commit f6e0dac1ad
4 changed files with 73 additions and 30 deletions

View file

@ -145,6 +145,11 @@ func rewriteSnapshot(ctx context.Context, repo *repository.Repository, sn *resti
return false, err
}
includeByNameFuncs, err := opts.IncludePatternOptions.CollectPatterns(Warnf)
if err != nil {
return false, err
}
metadata, err := opts.Metadata.convert()
if err != nil {
@ -354,3 +359,53 @@ func runRewrite(ctx context.Context, opts RewriteOptions, gopts GlobalOptions, a
return nil
}
// gatherFilters defines the method for walker.NodeRewrite
func gatherFilters(rejectByNameFuncs []filter.RejectByNameFunc, includeByNameFuncs []filter.IncludeByNameFunc) (rewriteNode walker.NodeRewriteFunc) {
if len(includeByNameFuncs) > 0 {
inSelectByName := func(nodepath string, node *restic.Node) bool {
for _, include := range includeByNameFuncs {
if node.Type == restic.NodeTypeDir {
// always include directories
return true
}
flag1, flag2 := include(nodepath)
if flag1 && flag2 {
return flag1 && flag2
}
}
return false
}
rewriteNode = func(node *restic.Node, path string) *restic.Node {
if inSelectByName(path, node) {
if node.Type != restic.NodeTypeDir {
Verboseff("including %s\n", path)
}
return node
}
return nil
}
} else {
exSelectByName := func(nodepath string) bool {
for _, reject := range rejectByNameFuncs {
if reject(nodepath) {
return false
}
}
return true
}
rewriteNode = func(node *restic.Node, path string) *restic.Node {
if exSelectByName(path) {
return node
}
Verboseff("excluding %s\n", path)
return nil
}
}
return rewriteNode
}

View file

@ -3,6 +3,7 @@ package main
import (
"context"
"path/filepath"
"strings"
"testing"
"github.com/restic/restic/internal/filter"

View file

@ -26,7 +26,7 @@ type RewriteOpts struct {
AllowUnstableSerialization bool
DisableNodeCache bool
RemoveEmptyDirectoryGlobal bool
KeepEmptyDirecoryGlobal bool
}
type idMap map[restic.ID]restic.ID
@ -41,6 +41,8 @@ func NewTreeRewriter(opts RewriteOpts) *TreeRewriter {
rw := &TreeRewriter{
opts: opts,
}
rw.opts.KeepEmptyDirecoryGlobal = true
if !opts.DisableNodeCache {
rw.replaces = make(idMap)
}
@ -59,7 +61,7 @@ func NewTreeRewriter(opts RewriteOpts) *TreeRewriter {
return rw
}
func NewSnapshotSizeRewriter(rewriteNode NodeRewriteFunc, removeEmptyDirectoryGlobal bool) (*TreeRewriter, QueryRewrittenSizeFunc) {
func NewSnapshotSizeRewriter(rewriteNode NodeRewriteFunc, keepEmptyDirecory bool) (*TreeRewriter, QueryRewrittenSizeFunc) {
var count uint
var size uint64
@ -73,8 +75,8 @@ func NewSnapshotSizeRewriter(rewriteNode NodeRewriteFunc, removeEmptyDirectoryGl
return node
},
DisableNodeCache: true,
// RemoveEmptyDirectoryGlobal = false will force old behaviour for --exclude variants
RemoveEmptyDirectoryGlobal: removeEmptyDirectoryGlobal,
// KeepEmptyDirecoryGlobal will force old behaviour for --exclude variants
KeepEmptyDirecoryGlobal: keepEmptyDirecory,
})
ss := func() SnapshotSize {
@ -118,16 +120,14 @@ func (t *TreeRewriter) RewriteTree(ctx context.Context, repo BlobLoadSaver, node
debug.Log("filterTree: %s, nodeId: %s\n", nodepath, nodeID.Str())
tb := restic.NewTreeJSONBuilder()
for _, node := range curTree.Nodes {
if ctx.Err() != nil {
return restic.ID{}, ctx.Err()
}
path := path.Join(nodepath, node.Name)
node = t.opts.RewriteNode(node, path)
if node == nil {
continue
}
// explicitely exclude empty directory - so it will be saved
if len(curTree.Nodes) > 0 {
countInserts := 0
for _, node := range curTree.Nodes {
if ctx.Err() != nil {
return restic.ID{}, ctx.Err()
}
path := path.Join(nodepath, node.Name)
node = t.opts.RewriteNode(node, path)
@ -154,7 +154,7 @@ func (t *TreeRewriter) RewriteTree(ctx context.Context, repo BlobLoadSaver, node
}
// check for empty subtree condition here
if t.opts.RemoveEmptyDirectoryGlobal && err == nil && newID.IsNull() {
if !t.opts.KeepEmptyDirecoryGlobal && err == nil && newID.IsNull() {
continue
}
@ -163,24 +163,11 @@ func (t *TreeRewriter) RewriteTree(ctx context.Context, repo BlobLoadSaver, node
if err != nil {
return restic.ID{}, err
}
continue
countInserts++
}
// treat nil as null id
var subtree restic.ID
if node.Subtree != nil {
subtree = *node.Subtree
}
newID, err := t.RewriteTree(ctx, repo, path, subtree)
if err != nil {
return restic.ID{}, err
}
node.Subtree = &newID
err = tb.AddNode(node)
if err != nil {
return restic.ID{}, err
// check for empty node list
if t.opts.RemoveEmptyDirectoryGlobal && countInserts == 0 {
if !t.opts.KeepEmptyDirecoryGlobal && countInserts == 0 {
// current subdirectory is empty - due to no includes: create condition here
return restic.ID{}, nil
}

View file

@ -334,7 +334,7 @@ func TestSnapshotSizeQuery(t *testing.T) {
}
return node
}
rewriter, querySize := NewSnapshotSizeRewriter(rewriteNode)
rewriter, querySize := NewSnapshotSizeRewriter(rewriteNode, false)
newRoot, err := rewriter.RewriteTree(ctx, modrepo, "/", root)
if err != nil {
t.Error(err)