.
C Pushing\sagain\skeeps\sthe\swork
D 2026-10-05T22:38:59.266
E 2026-10-05T22:40:00 d1a8603068d2d2c40c238ea17a43dbde8864b606
N text/x-markdown
U dmestas
W 1816
A forge can keep a branch for its owners: anyone may push, but only an owner's
check-ins may join `trunk`. zit has refused such pushes since 0.3.0. The
refusal was correct and it stranded people. Someone who committed onto trunk
with autosync on, which is what a newcomer does first, got one line naming
the branch and no way out they could guess. For two of the three ways a
check-in lands on trunk, the obvious fix, amending it onto another branch and
pushing again, was refused too, on every push after.
0.3.38 fixes both halves. The server now asks where a pushed check-in really
ends up the way its own derive does, replaying the push over the history it
builds on, newest move winning as in Fossil. Amending a refused check-in
elsewhere and pushing again now works whatever shape the push took, and the
refusal says so, with the hash filled in.
Behind a front that allows it, the person need not know even that. The first
refusal says what the next push will do:
```
check-in 9e1c5d97f9be would join protected branch 'trunk'. Your next push,
including the autosync after your next commit, keeps it on branch
attempt/jan/9e1c5d97f9be
```
and the next push lands there. The server writes the move itself, in the same
commit as the push, so trunk never shows the check-in. Stock Fossil prints
where it went as "Server says: ...", and `fossil sync` brings the move home
in the same exchange. zit prints it as `server: ...` and pulls the move after
a push. The front is told by a header and can open a landing.
Nothing moves without the pusher being told first, and the way out by hand
still works for anyone who would rather name the branch themselves.
Replaying the push the way the derive does also closed five ways past the
protection that judging tags by name had left open. The release notes list
them.
Z 983931dc627534fbae85ce3e0b5006cc