split the god modules: archive.py (12 classes) and the pack machinery inside repository.py
- Dominant language
- Python
- Stars
- 13.7k
- Forks
- 875
- Avg merge
- 12h 37m
- Merged PRs (30d)
- 199
Description
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.py` keeps 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](https://claude.com/claude-code)
Contributor guide
Assessment
This issue has not been assessed yet.