split the god modules: archive.py (12 classes) and the pack machinery inside repository.py
From a global code review of the borg2 codebase (2026-08). Companion to #10016.
Problem
Two modules have accreted far too many responsibilities:
src/borg/archive.py (~2500 lines) contains: Statistics, BackupIO/backup_io_iter, DownloadPipeline, ChunkBuffer/CacheChunkBuffer, Archive, MetadataCollector, ChunksProcessor, FilesystemObjectProcessors, TarfileObjectProcessors, RobustUnpacker, ArchiveChecker, and ArchiveRecreater. That is the read pipeline, the write pipeline, the archive entity, the checker, and the recreater in one file — nearly every change to any of them touches this module, and it is a magnet for circular imports (see #10016).
src/borg/repository.py (~1450 lines) contains both the Repository API and the entire pack subsystem: PackWriter, PackReader, PackTracker, check_pack_objects, superseded_gap_ranges, plus compact_pack/merge_packs/transform_pack. The pack format is a self-contained concern with its own invariants and tests.
Proposed direction
Mirror the successful borg.archiver split (one command per module):
borg/archive/package:statistics.py,pipeline.py(DownloadPipeline/ChunkBuffer),archive.py(the entity),create.py(the processors + MetadataCollector),check.py,recreate.py.borg/packs/package for PackWriter/PackReader/PackTracker and the pack-level compact/merge/transform operations;repository.pykeeps the Repository API and delegates.
Mechanical moves, no behavior change intended; 2.0 breaking internal API makes this cheap now and much more expensive later.
Generated with Claude Code
Source: borgbackup/borg