fix: move the refs and the pin together or not at all

Recaling refs while the pin stays put produces exactly the state the
all-or-nothing rule exists to prevent: a profile whose refs describe one
revision and whose source_commit names another. The tool manufactured it
on mariani, where three prose runs it could not rewrite kept
bump_commit refusing while eleven refs had already moved.

Asking for both writes is now atomic. The work happens on a copy, which
is promoted only when the pin follows, and a rebase is refused outright
when something visible beforehand will hold the pin: an annotated ref,
one under a mode key, or a prose run whose tokens cannot be located well
enough to rewrite. Where the block only appears after the write, the
copy is discarded and the profile is named on stderr rather than left
half moved.

mariani is back on its pin and stays at four refs to read, which is
honest: three of them have to be rewritten by hand before anything can
advance.
This commit is contained in:
Abdessamad Derraz committed 2026-09-04 18:55:15 +02:00
1 parent 09406ba5d4
commit c738073f66
3 files changed
+143 -14

No files matched your search

+8
View File
@@ -345,6 +345,14 @@ python scripts/profile_sync.py --all --rebase-refs --bump-commit --dry-run
python scripts/profile_sync.py --all --rebase-refs --bump-commit
```
Asking for both makes the pass atomic. The work happens on a copy, and the
copy is promoted only when the pin follows the refs; a profile whose refs
describe one revision while its pin names another is the state the
all-or-nothing rule exists to prevent, and recaling alone produces it. What
holds a pin back is an annotated ref, one under a mode key, or a prose run the
pass cannot rewrite without guessing: those are repaired first, by hand or
with `--realign-prose`.
The first prints the plan and changes nothing: `would recale` per ref and
`would set source_commit` per profile. It reaches that plan by running the
real write path over a throwaway copy, so the planned bump reads the text