From 33bcf31bae7d5f6ac5d7b6f64abc7188687c4070 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Mon, 5 Jan 2015 21:40:43 +0100 Subject: [PATCH] Fix incremental backup Copying blobs (for unchanged files and subtrees) from old BlobList to new BlobList was missing --- archiver.go | 5 ++++- cmd/restic/cmd_backup.go | 9 +++++++-- tree.go | 27 +++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/archiver.go b/archiver.go index 6e475a5be..4f8e04385 100644 --- a/archiver.go +++ b/archiver.go @@ -32,7 +32,7 @@ type Archiver struct { p *Progress } -func NewArchiver(s Server, p *Progress) (*Archiver, error) { +func NewArchiver(s Server, bl *BlobList, p *Progress) (*Archiver, error) { var err error arch := &Archiver{ s: s, @@ -56,6 +56,9 @@ func NewArchiver(s Server, p *Progress) (*Archiver, error) { arch.Filter = func(string, os.FileInfo) bool { return true } arch.bl = NewBlobList() + if bl != nil { + arch.bl.Merge(bl) + } arch.ch = NewContentHandler(s) // load all blobs from all snapshots diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index 290938c26..8615e3503 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -120,6 +120,7 @@ func (cmd CmdBackup) Execute(args []string) error { return err } + var bl *restic.BlobList if parentSnapshotID != nil { fmt.Printf("load old snapshot\n") ch := restic.NewContentHandler(s) @@ -133,7 +134,11 @@ func (cmd CmdBackup) Execute(args []string) error { return err } - newTree.CopyFrom(oldTree) + bl = restic.NewBlobList() + err = newTree.CopyFrom(bl, oldTree, ch.BlobList()) + if err != nil { + return err + } } archiveProgress := restic.NewProgress(time.Second) @@ -170,7 +175,7 @@ func (cmd CmdBackup) Execute(args []string) error { } } - arch, err := restic.NewArchiver(s, archiveProgress) + arch, err := restic.NewArchiver(s, bl, archiveProgress) if err != nil { fmt.Fprintf(os.Stderr, "err: %v\n", err) } diff --git a/tree.go b/tree.go index 7752e1d7c..cd665dc00 100644 --- a/tree.go +++ b/tree.go @@ -120,7 +120,7 @@ func LoadTreeRecursive(path string, ch *ContentHandler, id backend.ID) (Tree, er } // CopyFrom recursively copies all content from other to t. -func (t Tree) CopyFrom(other Tree) { +func (t Tree) CopyFrom(bl *BlobList, other Tree, otherBl *BlobList) error { for _, node := range t { // only process files and dirs if node.Type != "file" && node.Type != "dir" { @@ -140,18 +140,41 @@ func (t Tree) CopyFrom(other Tree) { if node.SameContent(oldNode) { // copy Content node.Content = oldNode.Content + + // copy storage IDs + for _, id := range node.Content { + blob, err := otherBl.Find(Blob{ID: id}) + if err != nil { + return err + } + + bl.Insert(blob) + } } } else { // fill in all subtrees from old subtree - node.tree.CopyFrom(*oldNode.tree) + err := node.tree.CopyFrom(bl, *oldNode.tree, otherBl) + if err != nil { + return err + } // check if tree has changed if node.tree.Equals(*oldNode.tree) { // if nothing has changed, copy subtree ID node.Subtree = oldNode.Subtree + + // and store blob in bloblist + blob, err := otherBl.Find(Blob{ID: oldNode.Subtree}) + if err != nil { + return err + } + + bl.Insert(blob) } } } + + return nil } // Equals returns true if t and other have exactly the same nodes.