mirror of
https://github.com/borgbackup/borg.git
synced 2026-03-20 17:42:08 -04:00
parent
8f4e0f7506
commit
193fb1fcd5
4 changed files with 36 additions and 3 deletions
2
CHANGES
2
CHANGES
|
|
@ -7,6 +7,8 @@ Version 0.14
|
|||
------------
|
||||
|
||||
(feature release, released on X)
|
||||
- Added support for stripping leading path segments (#95)
|
||||
"attic extract --strip-segments X"
|
||||
- Add workaround for old Linux systems without acl_extended_file_no_follow (#96)
|
||||
- Add MacPorts' path to the default openssl search path (#101)
|
||||
- HashIndex improvements, eliminates unnecessary IO on low memory systems.
|
||||
|
|
|
|||
|
|
@ -191,14 +191,21 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
archive = Archive(repository, key, manifest, args.archive.archive,
|
||||
numeric_owner=args.numeric_owner)
|
||||
patterns = adjust_patterns(args.paths, args.excludes)
|
||||
dry_run = args.dry_run
|
||||
strip_components = args.strip_components
|
||||
dirs = []
|
||||
for item in archive.iter_items(lambda item: not exclude_path(item[b'path'], patterns), preload=True):
|
||||
orig_path = item[b'path']
|
||||
if strip_components:
|
||||
item[b'path'] = os.sep.join(orig_path.split(os.sep)[strip_components:])
|
||||
if not item[b'path']:
|
||||
continue
|
||||
if not args.dry_run:
|
||||
while dirs and not item[b'path'].startswith(dirs[-1][b'path']):
|
||||
archive.extract_item(dirs.pop(-1))
|
||||
self.print_verbose(remove_surrogates(item[b'path']))
|
||||
self.print_verbose(remove_surrogates(orig_path))
|
||||
try:
|
||||
if args.dry_run:
|
||||
if dry_run:
|
||||
archive.extract_item(item, dry_run=True)
|
||||
else:
|
||||
if stat.S_ISDIR(item[b'mode']):
|
||||
|
|
@ -207,7 +214,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
else:
|
||||
archive.extract_item(item)
|
||||
except IOError as e:
|
||||
self.print_error('%s: %s', remove_surrogates(item[b'path']), e)
|
||||
self.print_error('%s: %s', remove_surrogates(orig_path), e)
|
||||
|
||||
if not args.dry_run:
|
||||
while dirs:
|
||||
|
|
@ -572,6 +579,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
|
|||
subparser.add_argument('--numeric-owner', dest='numeric_owner',
|
||||
action='store_true', default=False,
|
||||
help='only obey numeric user and group identifiers')
|
||||
subparser.add_argument('--strip-components', dest='strip_components',
|
||||
type=int, default=0, metavar='NUMBER',
|
||||
help='Remove the specified number of leading path elements. Pathnames with fewer elements will be silently skipped.')
|
||||
subparser.add_argument('archive', metavar='ARCHIVE',
|
||||
type=location_validator(archive=True),
|
||||
help='archive to extract')
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from contextlib import contextmanager
|
||||
import filecmp
|
||||
import os
|
||||
import posix
|
||||
|
|
@ -41,6 +42,12 @@ class AtticTestCase(unittest.TestCase):
|
|||
assert_raises = unittest.TestCase.assertRaises
|
||||
assert_true = unittest.TestCase.assertTrue
|
||||
|
||||
@contextmanager
|
||||
def assert_creates_file(self, path):
|
||||
self.assert_true(not os.path.exists(path), '{} should not exist'.format(path))
|
||||
yield
|
||||
self.assert_true(os.path.exists(path), '{} should exist'.format(path))
|
||||
|
||||
def assert_dirs_equal(self, dir1, dir2):
|
||||
diff = filecmp.dircmp(dir1, dir2)
|
||||
self._assert_dirs_equal_cmp(diff)
|
||||
|
|
|
|||
|
|
@ -165,6 +165,20 @@ class ArchiverTestCase(ArchiverTestCaseBase):
|
|||
# end the same way as info_output
|
||||
assert info_output2.endswith(info_output)
|
||||
|
||||
def test_strip_components(self):
|
||||
self.attic('init', self.repository_location)
|
||||
self.create_regular_file('dir/file')
|
||||
self.attic('create', self.repository_location + '::test', 'input')
|
||||
with changedir('output'):
|
||||
self.attic('extract', self.repository_location + '::test', '--strip-components', '3')
|
||||
self.assert_true(not os.path.exists('file'))
|
||||
with self.assert_creates_file('file'):
|
||||
self.attic('extract', self.repository_location + '::test', '--strip-components', '2')
|
||||
with self.assert_creates_file('dir/file'):
|
||||
self.attic('extract', self.repository_location + '::test', '--strip-components', '1')
|
||||
with self.assert_creates_file('input/dir/file'):
|
||||
self.attic('extract', self.repository_location + '::test', '--strip-components', '0')
|
||||
|
||||
def test_extract_include_exclude(self):
|
||||
self.attic('init', self.repository_location)
|
||||
self.create_regular_file('file1', size=1024 * 80)
|
||||
|
|
|
|||
Loading…
Reference in a new issue