Skip to content
zit Artifact [e7d4992eed]
Login

Artifact [e7d4992eed]

Artifact e7d4992eedc05bae9e3b51d6fcf77a0aad608e0c065a3d228691b6deca0458f1:


# zit 0.3.27

zit 0.3.27 gives a refused protected-branch push a way back: the pusher
moves the check-in to another branch and pushes again, and it lands there.

No artifact, tag namespace, sync message, or on-disk repository format
changed.

## A refused check-in can be amended onto another branch

A push that would join a protected branch is refused, and correctly so.
But the obvious recovery — `zit amend X --branch other`, which cancels
`sym-trunk` on X from a control artifact — was refused as well. The rule
judged a cancel by the name it carried and never by whether the server held
its target, so it treated "move this check-in you never admitted" the same
as "remove this check-in you hold". Every later push from that checkout
then carried the same refused round, and the only exits were a fresh clone
or a local purge and recommit.

Two things changed in the rule, both on the server:

- A cancel aimed at a check-in the server does not hold is admitted. It
  removes that check-in from nothing the server has, so the check-in is
  judged where it joins instead — in the same round when the two travel
  together, or on its own arrival otherwise. This is the principle the rule
  already applied to `closed`. A cancel on a check-in the server holds is
  refused exactly as before, because that is how a check-in leaves a
  protected branch.

- When a check-in is judged, a control artifact in the same round that moves
  it — the `*branch=B` and `*sym-B` a branch move mints against its hash —
  now counts. Judging the check-in by its parent alone would have put it
  straight back on the branch it was refused from.

Two smaller corrections fell out of testing this:

- A check-in the server already holds, re-offered in a push, is no longer
  judged as joining anything. It was judged when it arrived; re-offering it
  is a no-op, not a claim.

- The end-to-end fixture that builds a raw push from a clone was comparing
  raw digests against hex names, so it never excluded anything and every
  push it built re-sent the server's own artifacts. The refusal it pinned
  was real, but for the wrong reason. It now excludes what it means to.

The fronted push remains the front's rule: `protect_globs` decide which
branches are guarded, and nothing here introduces a new identity question
or a new header.

## Compatibility

- No on-disk repository or wire format changed; Fossil RFC revision 00
  remains the target.
- A pushed control artifact cancelling `sym-B` on a check-in the server
  does not hold was previously refused naming `B`. It is now admitted, and
  the check-in it targets is judged on its own.
- A held check-in re-sent in a push against a protected branch was
  previously refused as a join. It is now ignored.

## Qualification

`zig fmt --check`, `zig build test`, `e2e`, `smoke`, `git-import-e2e`,
`git-export-e2e`, and `dst`, plus the three-runner CI battery.