fix files cache rebuild from an archive without ctime - #10299
Merged
ThomasWaldmann merged 1 commit intoSep 1, 2026
Conversation
_build_files_cache read item.ctime unconditionally, but an archive item does not necessarily have a ctime: - borg create --noctime omits it, - on Windows it is never archived (st_ctime is the file creation time there and gets archived as birthtime, see borgbackup#8730), - very old archives only have mtime, as the comment in stat_attrs() says. Rebuilding the files cache from such an archive crashed: AttributeError: attribute ctime not found That is reachable whenever the local files cache is missing while a previous archive exists, i.e. after the cache directory was lost, or on a fresh machine - always on Windows, and with --noctime everywhere. Both timestamps are read with item.get() now. A timestamp the archive does not have is cached as 0, which can not compare equal to the timestamp seen in the file system, so the file is considered changed and gets chunked again if that timestamp is part of the files cache mode. The tracking of the newest ctime/mtime skips missing values instead of comparing them.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #10299 +/- ##
==========================================
+ Coverage 87.55% 87.61% +0.06%
==========================================
Files 103 103
Lines 18676 18674 -2
Branches 2872 2872
==========================================
+ Hits 16352 16362 +10
+ Misses 1622 1611 -11
+ Partials 702 701 -1 ☔ View full report in Codecov by Harness. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #10292, where the Windows CI run turned this up. It is an independent pre-existing bug.
The bug
_build_files_cache()readsitem.ctimeunconditionally, but an archive item does not necessarilyhave a ctime.
stat_attrs()stores it only conditionally:So rebuilding the files cache from a previous archive crashes:
This happens always on Windows (ctime is never archived there) and with
--noctimeon everyplatform. It is reachable whenever the local files cache is missing while a previous archive exists
— a fresh machine, or a lost/cleared cache directory — i.e. exactly the situation the repo-side
rebuild exists for.
Reproducer on Linux/macOS:
It went unnoticed because nothing exercised the repo-side rebuild path on Windows CI until #10292
added a test that removes the local files cache.
The fix
Both timestamps are read with
item.get(). A timestamp the archive does not have is cached as0,which cannot compare equal to the timestamp seen in the file system — so if that timestamp is part
of the files cache mode, the file is considered changed and gets chunked again, which is the safe
outcome. The tracking of the newest ctime/mtime skips missing values instead of comparing them; the
two copy-pasted blocks for the two timestamps collapsed into a loop.
Tests
test_files_cache_rebuild_without_ctimeuses--noctimerather than relying on Windows CI, so itcovers this on every platform. Verified it fails without the fix on both
archiverandremote_archiver.It comes with a
_remove_files_cache()test helper (removes the local files cache of a series toforce the rebuild), which #10292 then also uses.
Full test suite: 2928 passed, 981 skipped.
ruff checkclean.