From 266996e24df24097328ca9ea1dc863960fbf8eaf Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Tue, 22 Oct 2013 12:06:56 -0500 Subject: [PATCH] Fix top-level non-dir metadata restoration with /foo/latest/target/ syntax. 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 --- cmd/restore-cmd.py | 14 +++++--------- t/test-meta.sh | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cmd/restore-cmd.py b/cmd/restore-cmd.py index 124578e..9c5d941 100755 --- a/cmd/restore-cmd.py +++ b/cmd/restore-cmd.py @@ -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): diff --git a/t/test-meta.sh b/t/test-meta.sh index 6f28cd0..217db03 100755 --- a/t/test-meta.sh +++ b/t/test-meta.sh @@ -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 -- 2.39.2