mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-23 14:41:43 +00:00
Implement --keep-tag-files to preserve directory roots/tag-files
We also add --keep-tag-files to keep in the archive the root directory and the tag/exclusion file in the archive. This is taken from a attic PR (and adapted for borg): commit f61e22cacc90e76e6c8f4b23677eee62c09e97ac Author: Yuri D'Elia <yuri.delia@eurac.edu> Date: Mon Dec 15 12:27:43 2014 +0100
This commit is contained in:
parent
a6a8a4ebd9
commit
7d178e09b0
3 changed files with 34 additions and 9 deletions
|
@ -167,7 +167,8 @@ def do_create(self, args):
|
|||
else:
|
||||
restrict_dev = None
|
||||
self._process(archive, cache, args.excludes, args.exclude_caches, args.exclude_if_present,
|
||||
skip_inodes, path, restrict_dev, read_special=args.read_special, dry_run=dry_run)
|
||||
args.keep_tag_files, skip_inodes, path, restrict_dev,
|
||||
read_special=args.read_special, dry_run=dry_run)
|
||||
if not dry_run:
|
||||
archive.save(timestamp=args.timestamp)
|
||||
if args.progress:
|
||||
|
@ -183,7 +184,8 @@ def do_create(self, args):
|
|||
return self.exit_code
|
||||
|
||||
def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
|
||||
skip_inodes, path, restrict_dev, read_special=False, dry_run=False):
|
||||
keep_tag_files, skip_inodes, path, restrict_dev,
|
||||
read_special=False, dry_run=False):
|
||||
if exclude_path(path, excludes):
|
||||
return
|
||||
try:
|
||||
|
@ -209,7 +211,11 @@ def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
|
|||
status = 'E'
|
||||
self.print_warning('%s: %s', path, e)
|
||||
elif stat.S_ISDIR(st.st_mode):
|
||||
if dir_is_tagged(path, exclude_caches, exclude_if_present):
|
||||
tag_path = dir_is_tagged(path, exclude_caches, exclude_if_present)
|
||||
if tag_path:
|
||||
if keep_tag_files:
|
||||
archive.process_dir(path, st)
|
||||
archive.process_file(tag_path, st, cache)
|
||||
return
|
||||
if not dry_run:
|
||||
status = archive.process_dir(path, st)
|
||||
|
@ -222,8 +228,8 @@ def _process(self, archive, cache, excludes, exclude_caches, exclude_if_present,
|
|||
for filename in sorted(entries):
|
||||
entry_path = os.path.normpath(os.path.join(path, filename))
|
||||
self._process(archive, cache, excludes, exclude_caches, exclude_if_present,
|
||||
skip_inodes, entry_path, restrict_dev, read_special=read_special,
|
||||
dry_run=dry_run)
|
||||
keep_tag_files, skip_inodes, entry_path, restrict_dev,
|
||||
read_special=read_special, dry_run=dry_run)
|
||||
elif stat.S_ISLNK(st.st_mode):
|
||||
if not dry_run:
|
||||
status = archive.process_symlink(path, st)
|
||||
|
@ -788,6 +794,9 @@ def build_parser(self, args=None, prog=None):
|
|||
subparser.add_argument('--exclude-if-present', dest='exclude_if_present',
|
||||
metavar='FILENAME', action='append', type=str,
|
||||
help='exclude directories that contain the specified file')
|
||||
subparser.add_argument('--keep-tag-files', dest='keep_tag_files',
|
||||
action='store_true', default=False,
|
||||
help='keep tag files of excluded caches/directories')
|
||||
subparser.add_argument('-c', '--checkpoint-interval', dest='checkpoint_interval',
|
||||
type=int, default=300, metavar='SECONDS',
|
||||
help='write checkpoint every SECONDS seconds (Default: 300)')
|
||||
|
|
|
@ -450,16 +450,18 @@ def dir_is_cachedir(path):
|
|||
|
||||
def dir_is_tagged(path, exclude_caches, exclude_if_present):
|
||||
"""Determines whether the specified path is excluded by being a cache
|
||||
directory or containing the user-specified tag file.
|
||||
directory or containing the user-specified tag file. Returns the
|
||||
path of the tag file (either CACHEDIR.TAG or the matching
|
||||
user-specified file)
|
||||
"""
|
||||
if exclude_caches and dir_is_cachedir(path):
|
||||
return True
|
||||
return os.path.join(path, 'CACHEDIR.TAG')
|
||||
if exclude_if_present is not None:
|
||||
for tag in exclude_if_present:
|
||||
tag_path = os.path.join(path, tag)
|
||||
if os.path.isfile(tag_path):
|
||||
return True
|
||||
return False
|
||||
return tag_path
|
||||
return None
|
||||
|
||||
|
||||
def format_time(t):
|
||||
|
|
|
@ -510,6 +510,20 @@ def test_exclude_tagged(self):
|
|||
self.cmd('extract', self.repository_location + '::test')
|
||||
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'tagged3'])
|
||||
|
||||
def test_exclude_keep_tagged(self):
|
||||
self.cmd('init', self.repository_location)
|
||||
self.create_regular_file('file1', size=1024 * 80)
|
||||
self.create_regular_file('tagged1/.NOBACKUP')
|
||||
self.create_regular_file('tagged1/file2', size=1024 * 80)
|
||||
self.create_regular_file('tagged2/CACHEDIR.TAG', contents = b'Signature: 8a477f597d28d172789f06886806bc55 extra stuff')
|
||||
self.create_regular_file('tagged2/file3', size=1024 * 80)
|
||||
self.cmd('create', '--exclude-if-present', '.NOBACKUP', '--exclude-caches', '--keep-tag-files', self.repository_location + '::test', 'input')
|
||||
with changedir('output'):
|
||||
self.cmd('extract', self.repository_location + '::test')
|
||||
self.assert_equal(sorted(os.listdir('output/input')), ['file1', 'tagged1', 'tagged2'])
|
||||
self.assert_equal(sorted(os.listdir('output/input/tagged1')), ['.NOBACKUP'])
|
||||
self.assert_equal(sorted(os.listdir('output/input/tagged2')), ['CACHEDIR.TAG'])
|
||||
|
||||
def test_path_normalization(self):
|
||||
self.cmd('init', self.repository_location)
|
||||
self.create_regular_file('dir1/dir2/file', size=1024 * 80)
|
||||
|
|
Loading…
Reference in a new issue