Browse Source

add commandline argument --sparse

default is to not create sparse files.

if you give --sparse, it will create a hole in the sparse output file when a all-zero chunk is extracted.
Thomas Waldmann 10 years ago
parent
commit
ee80db4eb2
3 changed files with 8 additions and 4 deletions
  1. 2 2
      attic/archive.py
  2. 5 1
      attic/archiver.py
  3. 1 1
      attic/testsuite/archiver.py

+ 2 - 2
attic/archive.py

@@ -233,7 +233,7 @@ class Archive:
         cache.rollback()
         return stats
 
-    def extract_item(self, item, restore_attrs=True, dry_run=False):
+    def extract_item(self, item, restore_attrs=True, dry_run=False, sparse=False):
         if dry_run:
             if b'chunks' in item:
                 for _ in self.pipeline.fetch_many([c[0] for c in item[b'chunks']], is_preloaded=True):
@@ -272,7 +272,7 @@ class Archive:
                 with open(path, 'wb') as fd:
                     ids = [c[0] for c in item[b'chunks']]
                     for data in self.pipeline.fetch_many(ids, is_preloaded=True):
-                        if ZEROS.startswith(data):
+                        if sparse and ZEROS.startswith(data):
                             # all-zero chunk: create a hole in a sparse file
                             fd.seek(len(data), 1)
                         else:

+ 5 - 1
attic/archiver.py

@@ -195,6 +195,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                           numeric_owner=args.numeric_owner)
         patterns = adjust_patterns(args.paths, args.excludes)
         dry_run = args.dry_run
+        sparse = args.sparse
         strip_components = args.strip_components
         dirs = []
         for item in archive.iter_items(lambda item: not exclude_path(item[b'path'], patterns), preload=True):
@@ -215,7 +216,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                         dirs.append(item)
                         archive.extract_item(item, restore_attrs=False)
                     else:
-                        archive.extract_item(item)
+                        archive.extract_item(item, sparse=sparse)
             except IOError as e:
                 self.print_error('%s: %s', remove_surrogates(orig_path), e)
 
@@ -585,6 +586,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         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('--sparse', dest='sparse',
+                               action='store_true', default=False,
+                               help='create holes in output sparse file from all-zero chunks')
         subparser.add_argument('archive', metavar='ARCHIVE',
                                type=location_validator(archive=True),
                                help='archive to extract')

+ 1 - 1
attic/testsuite/archiver.py

@@ -216,7 +216,7 @@ class ArchiverTestCase(ArchiverTestCaseBase):
         self.attic('init', self.repository_location)
         self.attic('create', self.repository_location + '::test', 'input')
         with changedir('output'):
-            self.attic('extract', self.repository_location + '::test')
+            self.attic('extract', '--sparse', self.repository_location + '::test')
         self.assert_dirs_equal('input', 'output/input')
         filename = os.path.join(self.output_path, 'input', 'sparse')
         with open(filename, 'rb') as fd: