Skip to main content
Lanes, changes & history

Rewrite history safely

What stays stable, what a rewrite still costs, and how to reverse one.

Written By Dustin

Last updated About 1 month ago

Rewriting history in TOVIO is safer than in Git, and it is not free.

What survives

Change ids. Amend, rebase, split, absorb, cherry-pick โ€” the chg: id is preserved, so reviews, comments, blame attribution and recorded dependencies stay attached. This is the whole reason rewriting is routine here.

What changes

Commit ids. Content addressing guarantees it: different content, different blake3: hash. Anything referring to a commit hash rather than a change id will point at the old snapshot.

What it still costs

  • Colleagues may get content conflicts. Not a divergence error โ€” lanes converge โ€” but if they edited lines you rewrote, that is a real disagreement, surfaced as a conflict object.
  • Exported Git mirrors get new hashes. A bridged Git remote sees a rewrite as a rewrite, and the bridge never force-pushes: it refuses with TVO-MIG-006 rather than discarding remote history.
  • Signatures. On a repository requiring signed commits, rewritten commits need signing again. A land --rebase re-signs the author's changes as you.

What a rewrite refuses to do

It will not cross a merge commit. Rebase, split and absorb all refuse with TVO-OP-014 rather than flatten a merge and drop its second-parent lineage. Keep the range you are rewriting a linear first-parent chain.

The safety net

tovio explain undo               # the op-log, and what undo would restore
tovio explain undo --limit 50
tovio undo
tovio undo --to <op-id>          # rewind past several operations at once

Rewrites are op-log operations and reverse like anything else. explain undo lists the recent operations with their op-ids and shows the state each would restore; explain undo --to <op-id> previews the restore before you commit to it. Op-ids also appear in every undo/redo --json result.

Tags do not participate

A tag is immutable. Rewriting history under a tag does not move it, and re-pointing it requires --force plus, over the wire, a verified tag:force authorization.