rewrite-verify
Checks a git filter-repo rewrite commit by commit against a written declaration of what should change, and exits non-zero at the first undeclared difference.
- Year
- 2026
- Kind
- Security · Python
- Status
- Shipped

You rewrite history to remove a leaked secret, then force-push. rewrite-verify checks that the rewrite did only that. You write down what was meant to change: paths removed, text replaced, message lines stripped, identities remapped. It walks every commit and compares trees, messages, authors, dates, parents, tags and refs. It fails closed: only exit 0 means verified.
It is tested on nine fixture rewrites, each made by a real filter-repo run. One is honest. Eight each slip in one undeclared change, from a deleted file to a dropped merge parent, and each is caught at the right commit. A security review found two ways to fool it into exit 0: a forged commit-graph and a Python-only codec. Both now have regression tests.
On a synthetic 5,000-commit history it verifies in 6.65 seconds. Its limit is the declaration itself: if the filter file forgot a secret, it will accept a rewrite that kept it. It checks history, not the object store, so an old blob left behind unreachable is not caught.
