فهرست منبع

Merge pull request #8393 from ThomasWaldmann/fix-compact-nonunique-names

fixes for non-unique archive names
TW 8 ماه پیش
والد
کامیت
97d1e18626

+ 3 - 3
src/borg/archiver/compact_cmd.py

@@ -62,7 +62,7 @@ class ArchiveGarbageCollector:
         """Iterate over all items in all archives, create the dicts id -> size of all used/wanted chunks."""
         used_chunks = {}  # chunks referenced by item.chunks
         wanted_chunks = {}  # additional "wanted" chunks seen in item.chunks_healthy
-        archive_infos = self.manifest.archives.list()
+        archive_infos = self.manifest.archives.list(sort_by=["ts"])
         num_archives = len(archive_infos)
         pi = ProgressIndicatorPercent(
             total=num_archives, msg="Computing used/wanted chunks %3.1f%%", step=0.1, msgid="compact.analyze_archives"
@@ -70,8 +70,8 @@ class ArchiveGarbageCollector:
         total_size, total_files = 0, 0
         for i, info in enumerate(archive_infos):
             pi.show(i)
-            logger.info(f"Analyzing archive {info.name} ({i + 1}/{num_archives})")
-            archive = Archive(self.manifest, info.name)
+            logger.info(f"Analyzing archive {info.name} {info.ts} {bin_to_hex(info.id)} ({i + 1}/{num_archives})")
+            archive = Archive(self.manifest, info.id)
             # archive metadata size unknown, but usually small/irrelevant:
             used_chunks[archive.id] = 0
             for id in archive.metadata.item_ptrs:

+ 6 - 5
src/borg/archiver/diff_cmd.py

@@ -4,7 +4,7 @@ import json
 import sys
 import os
 
-from ._common import with_repository, with_archive, build_matcher, Highlander
+from ._common import with_repository, build_matcher, Highlander
 from ..archive import Archive
 from ..constants import *  # NOQA
 from ..helpers import BaseFormatter, DiffFormatter, archivename_validator, PathSpec, BorgJsonEncoder
@@ -16,8 +16,7 @@ logger = create_logger()
 
 class DiffMixIn:
     @with_repository(compatibility=(Manifest.Operation.READ,))
-    @with_archive
-    def do_diff(self, args, repository, manifest, archive):
+    def do_diff(self, args, repository, manifest):
         """Diff contents of two archives"""
         if args.format is not None:
             format = args.format
@@ -26,8 +25,10 @@ class DiffMixIn:
         else:
             format = os.environ.get("BORG_DIFF_FORMAT", "{change} {path}{NL}")
 
-        archive1 = archive
-        archive2 = Archive(manifest, args.other_name)
+        archive1_info = manifest.archives.get_one(args.name)
+        archive2_info = manifest.archives.get_one(args.other_name)
+        archive1 = Archive(manifest, archive1_info.id)
+        archive2 = Archive(manifest, archive2_info.id)
 
         can_compare_chunk_ids = (
             archive1.metadata.get("chunker_params", False) == archive2.metadata.get("chunker_params", True)

+ 1 - 1
src/borg/archiver/transfer_cmd.py

@@ -97,7 +97,7 @@ class TransferMixIn:
             else:
                 if not dry_run:
                     print(f"{name} {ts_str} {id_hex}: copying archive to destination repo...")
-                other_archive = Archive(other_manifest, name)
+                other_archive = Archive(other_manifest, id)
                 archive = (
                     Archive(manifest, name, cache=cache, create=True, progress=args.progress) if not dry_run else None
                 )

+ 7 - 7
src/borg/fuse.py

@@ -280,12 +280,12 @@ class FuseBackend:
         for archive in self._manifest.archives.list_considering(self._args):
             if self.versions:
                 # process archives immediately
-                self._process_archive(archive.name)
+                self._process_archive(archive.id)
             else:
                 # lazily load archives, create archive placeholder inode
                 archive_inode = self._create_dir(parent=1, mtime=int(archive.ts.timestamp() * 1e9))
                 self.contents[1][os.fsencode(archive.name)] = archive_inode
-                self.pending_archives[archive_inode] = archive.name
+                self.pending_archives[archive_inode] = archive
 
     def get_item(self, inode):
         item = self._inode_cache.get(inode)
@@ -302,9 +302,9 @@ class FuseBackend:
 
     def check_pending_archive(self, inode):
         # Check if this is an archive we need to load
-        archive_name = self.pending_archives.pop(inode, None)
-        if archive_name is not None:
-            self._process_archive(archive_name, [os.fsencode(archive_name)])
+        archive_info = self.pending_archives.pop(inode, None)
+        if archive_info is not None:
+            self._process_archive(archive_info.id, [os.fsencode(archive_info.name)])
 
     def _allocate_inode(self):
         self.inode_count += 1
@@ -328,11 +328,11 @@ class FuseBackend:
             inode = self.contents[inode][segment]
         return inode
 
-    def _process_archive(self, archive_name, prefix=[]):
+    def _process_archive(self, archive_id, prefix=[]):
         """Build FUSE inode hierarchy from archive metadata"""
         self.file_versions = {}  # for versions mode: original path -> version
         t0 = time.perf_counter()
-        archive = Archive(self._manifest, archive_name)
+        archive = Archive(self._manifest, archive_id)
         strip_components = self._args.strip_components
         matcher = build_matcher(self._args.patterns, self._args.paths)
         hlm = HardLinkManager(id_type=bytes, info_type=str)  # hlid -> path

+ 1 - 1
src/borg/helpers/parseformat.py

@@ -828,7 +828,7 @@ class ArchiveFormatter(BaseFormatter):
         if self._archive is None or self._archive.id != self.id:
             from ..archive import Archive
 
-            self._archive = Archive(self.manifest, self.name, iec=self.iec)
+            self._archive = Archive(self.manifest, self.id, iec=self.iec)
         return self._archive
 
     def get_meta(self, key, default=None):

+ 2 - 1
src/borg/testsuite/archiver/__init__.py

@@ -169,7 +169,8 @@ def open_archive(repo_path, name):
     repository = Repository(repo_path, exclusive=True)
     with repository:
         manifest = Manifest.load(repository, Manifest.NO_OPERATION_CHECK)
-        archive = Archive(manifest, name)
+        archive_info = manifest.archives.get_one(name)
+        archive = Archive(manifest, archive_info.id)
     return archive, repository