Browse Source

Add --ignore-zeros flag to import-tar

Fixes #7432.
Artem Sheremet 2 years ago
parent
commit
3c941ae604
2 changed files with 34 additions and 1 deletions
  1. 7 1
      src/borg/archiver/tar_cmds.py
  2. 27 0
      src/borg/testsuite/archiver/tar_cmds.py

+ 7 - 1
src/borg/archiver/tar_cmds.py

@@ -289,7 +289,7 @@ class TarMixIn:
             file_status_printer=self.print_file_status,
         )
 
-        tar = tarfile.open(fileobj=tarstream, mode="r|")
+        tar = tarfile.open(fileobj=tarstream, mode="r|", ignore_zeros=args.ignore_zeros)
 
         while True:
             tarinfo = tar.next()
@@ -487,6 +487,12 @@ class TarMixIn:
             help="only display items with the given status characters",
         )
         subparser.add_argument("--json", action="store_true", help="output stats as JSON (implies --stats)")
+        subparser.add_argument(
+            "--ignore-zeros",
+            dest="ignore_zeros",
+            action="store_true",
+            help="ignore zero-filled blocks in the input tarball",
+        )
 
         archive_group = subparser.add_argument_group("Archive options")
         archive_group.add_argument(

+ 27 - 0
src/borg/testsuite/archiver/tar_cmds.py

@@ -143,6 +143,33 @@ class ArchiverTestCase(ArchiverTestCaseBase):
             self.cmd(f"--repo={self.repository_location}", "extract", "dst")
         self.assert_dirs_equal("input", "output/input", ignore_ns=True, ignore_xattrs=True)
 
+    @requires_gnutar
+    def test_import_tar_with_ignore_zeros(self):
+        self.create_test_files(create_hardlinks=False)  # hardlinks become separate files
+        os.unlink("input/flagfile")
+        with changedir("input"):
+            subprocess.check_call(["tar", "cf", "file1.tar", "file1"])
+            subprocess.check_call(["tar", "cf", "the_rest.tar", "--exclude", "file1*", "."])
+            with open("concatenated.tar", "wb") as concatenated:
+                with open("file1.tar", "rb") as file1:
+                    concatenated.write(file1.read())
+                # Clean up for assert_dirs_equal.
+                os.unlink("file1.tar")
+
+                with open("the_rest.tar", "rb") as the_rest:
+                    concatenated.write(the_rest.read())
+                # Clean up for assert_dirs_equal.
+                os.unlink("the_rest.tar")
+
+        self.cmd(f"--repo={self.repository_location}", "rcreate", "--encryption=none")
+        self.cmd(f"--repo={self.repository_location}", "import-tar", "--ignore-zeros", "dst", "input/concatenated.tar")
+        # Clean up for assert_dirs_equal.
+        os.unlink("input/concatenated.tar")
+
+        with changedir(self.output_path):
+            self.cmd(f"--repo={self.repository_location}", "extract", "dst")
+        self.assert_dirs_equal("input", "output", ignore_ns=True, ignore_xattrs=True)
+
     def test_roundtrip_pax_borg(self):
         self.create_test_files()
         self.cmd(f"--repo={self.repository_location}", "rcreate", "--encryption=none")