feat: harden stale-file change detection with mtime+size fingerprint (#17) #22
Reference in New Issue
Block a user
Delete Branch "feat/17-stale-size-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #17
Problem
PR #15 added stale-file protection, but the check compares bare
disk_mtime != self._loaded_mtime. This misses a concurrent external write when:A missed detection means BCC silently overwrites an external edit without ever showing
StaleDialog.Fix
Pair mtime with file size.
bcc_core.pygets a newConfigStat(NamedTuple[mtime, size]) andconfig_fingerprint(path)helper alongside the existingconfig_mtime()(kept, still used/tested independently).bcc.py'sMainWindow._loaded_mtimebecomes_loaded_stat: core.ConfigStat | None, populated viaconfig_fingerprint()at load and at both save-completion paths (normal save + merge). The save-path stale check now triggers ondisk_stat != self._loaded_stat, which is true when either mtime or size differs.A full content hash is out of scope per the issue — size+mtime is the intended middle ground.
Files changed
bcc_core.py— addConfigStatNamedTuple +config_fingerprint()bcc.py—_loaded_mtime→_loaded_stat; stale check now compares the full fingerprinttests/test_core.py— 3 new tests, including the required regression case: write a file, snapshot it, rewrite with different (larger) content, force the original mtime back viaos.utime, and assert the change is still detected because size differsVerification
ruff check .— all checks passedruff format --check .— cleanpytest— 95 passed (was 92 onmain; +3 new tests), including the hardening regression testNote: one incidental fix included —
bcc_core.py's existing non-breaking-space normalization (_normalize_unicode) used a literal NBSP character in.replace(...); rewritten aschr(0xA0)for robustness. No behavior change.Supervisor review (Cowork): approve. CI run #157 green; isolated diff.
ConfigStat(mtime,size) +config_fingerprintcorrectly catches the same-mtime-different-size case, and the regression test forces the original mtime viaos.utimeto prove it. Minor: this PR also rewrites the_normalize_unicodeNBSP line (behavior-identical) — it'll conflict with #23/#24/#25 which did the same; resolve by taking that line from any one branch at merge. Ready for v1.2.0.Superseded by #26 (release: v1.2.0), which merged this change into
mainas part of the integrated release. Closing.Pull request closed