]> arthur.barton.de Git - bup.git/commitdiff
Fix top-level non-dir metadata restoration with /foo/latest/target/ syntax.
authorRob Browning <rlb@defaultvalue.org>
Tue, 22 Oct 2013 17:06:56 +0000 (12:06 -0500)
committerRob Browning <rlb@defaultvalue.org>
Wed, 23 Oct 2013 21:46:53 +0000 (16:46 -0500)
Previously something like "bup restore -C dest /foo/latest/bar/" would
fail to restore metadata for top-level, non-directory paths inside
bar.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
cmd/restore-cmd.py
t/test-meta.sh

index 124578e42685cb65a3dab622750850121060b9ef..9c5d941a4bcf4099479ecd9f36c7de969e2cd4e1 100755 (executable)
@@ -149,7 +149,7 @@ def find_dir_item_metadata_by_name(dir, name):
             meta_stream.close()
 
 
-def do_root(n):
+def do_root(n, restore_root_meta=True):
     # Very similar to do_node(), except that this function doesn't
     # create a path for n's destination directory (and so ignores
     # n.fullname).  It assumes the destination is '.', and restores
@@ -162,7 +162,7 @@ def do_root(n):
         mfile = n.metadata_file() # VFS file -- cannot close().
         if mfile:
             meta_stream = mfile.open()
-            meta = metadata.Metadata.read(meta_stream)
+            root_meta = metadata.Metadata.read(meta_stream)
         print_info(n, '.')
         total_restored += 1
         plog('Restoring: %d\r' % total_restored)
@@ -172,8 +172,8 @@ def do_root(n):
             if meta_stream and not stat.S_ISDIR(sub.mode):
                 m = metadata.Metadata.read(meta_stream)
             do_node(n, sub, m)
-        if meta:
-            meta.apply_to_path('.', restore_numeric_ids = opt.numeric_ids)
+        if root_meta and restore_root_meta:
+            root_meta.apply_to_path('.', restore_numeric_ids = opt.numeric_ids)
     finally:
         if meta_stream:
             meta_stream.close()
@@ -267,11 +267,7 @@ for d in extra:
         if not isdir:
             add_error('%r: not a directory' % d)
         else:
-            if name == '.':
-                do_root(n)
-            else:
-                for sub in n:
-                    do_node(n, sub)
+            do_root(n, restore_root_meta = (name == '.'))
     else:
         # Source is /foo/what/ever -- extract ./ever to cwd.
         if isinstance(n, vfs.FakeSymlink):
index 6f28cd09169c9bd7a60039c67d7dd0019df6c2a7..217db037ee336aa43997f75e5aa184fe10c59410 100755 (executable)
@@ -151,7 +151,27 @@ WVSTART 'metadata save/restore (general)'
     setup-test-tree
     cd "$TOP/bupmeta.tmp"
     test-src-save-restore
-)
+
+    # Test a deeper subdir/ to make sure top-level non-dir metadata is
+    # restored correctly.  We need at least one dir and one non-dir at
+    # the "top-level".
+    WVPASS test -f src/lib/__init__.py
+    WVPASS test -d src/lib/bup
+    rm -rf src.bup
+    mkdir src.bup
+    export BUP_DIR=$(pwd)/src.bup
+    WVPASS bup init
+    touch -t 201111111111 src-restore # Make sure the top won't match.
+    WVPASS bup index src
+    WVPASS bup save -t -n src src
+    force-delete src-restore
+    WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/lib/"
+    touch -t 201211111111 src-restore # Make sure the top won't match.
+    # Check that the only difference is the top dir.
+    $TOP/t/compare-trees -c src/lib/ src-restore/ > tmp-compare-trees
+    WVPASSEQ $(cat tmp-compare-trees | wc -l) 2
+    tail -n +2 tmp-compare-trees | WVPASS grep -qE '^\.d[^ ]+ \./$'
+) || WVFAIL
 
 # Test that we pull the index (not filesystem) metadata for any
 # unchanged files whenever we're saving other files in a given