Rewrite history safely¶
Rewriting history in TOVIO is not the high-wire act it is in Git. The single idea that removes the fear:
a change keeps its stable Change ID through every rewrite. Amend, split,
squash, absorb, reorder, rebase — the commit hashes change, but chg:a3f7b2 is still chg:a3f7b2. You
(and your teammates, CI, and agents) can always point at the same unit of work no matter how its history
is reshaped.
Every rewrite is one undo away
Each command on this page is op-logged and reversible with a single tovio undo. There is no
force-push, no detached HEAD, no "diverged history," and no way to strand your work. Reshape freely;
take it back if you don't like it. See Undo and redo recorded operations for the
local retention and peer-observation boundaries.
Implemented and specification-only rewrite verbs
tovio commit --amend, tovio change split, tovio change absorb, and tovio rebase /
tovio change rebase have landed and preserve Change IDs. The standalone tovio amend,
tovio squash, and tovio reorder remain specification-only; those sections document intended
behavior, not commands you can run today.
Why this is safe (the Change ID)¶
A Git rebase rewrites commit hashes, which is why it feels dangerous — references break, history "diverges," and recovery means spelunking the reflog. TOVIO separates two identities:
- The Commit ID (
blake3:…) is a content hash. It does change when content changes. - The Change ID (
chg:…) is a stable name assigned when work began. It never changes.
So a rewrite produces new commits under the same change. References to the change stay valid.
tovio change show chg:a3f7b2 always resolves to that change's current commit, before and after any
rewrite. Affirming this is why every rewrite prints a line like "Change IDs unchanged" or "same
Change IDs — your work kept its identity." For the full mental model behind Change IDs, see the
concepts.
Amend — fold edits into the current change¶
The everyday rewrite. Add more edits, or fix the message, without starting a new change:
This folds the current working change into the last commit and preserves its Change ID; omit -m to
keep the existing message (Commit your work).
No standalone tovio amend
The CLI specification also spells this tovio amend; that verb is not implemented. Use
tovio commit --amend.
Split — divide one change into several¶
split recovers granularity after the fact — TOVIO has no staging index, so you don't pre-select what
goes in a commit; you commit, then split if you want finer pieces. Divide by paths:
✓ Split chg:a3f7b2… into ready chg:phb97d… (1 path(s)) + remainder chg:a3f7b2… - undo with `tovio undo`
The matching files become a fresh ready sub-change that is landable on its own; the rest stays as
the remainder, which keeps the original Change ID and stacks on top (parent → ready → remainder). The
change must be a lane tip; omit the id to split the current change. --paths is repeatable.
This is also how you do a partial land: split the ready files into their own sub-change, then land just that one and keep the rest as work in progress. You never cherry-pick individual files out of a change.
Squash — combine a change into its parent¶
The CLI specification designs tovio squash <change-id> [--into <target>], where the surviving
change keeps its ID.
Not yet available
tovio squash is not implemented. Today the nearest tools are tovio change absorb (fold fixups
back into the changes that own them) and tovio commit --amend (fold working edits into the last
commit).
Absorb — distribute fixups automatically¶
Made a handful of small fixes that really belong to earlier changes in your stack? absorb routes each
file your current change touches into the single unlanded ancestor that last touched it, then
re-stacks the rest:
$ tovio change absorb --dry-run # preview the routing without rewriting anything
$ tovio change absorb
✓ Absorbed 1 file(s) into 1 change(s) (Change IDs unchanged); 0 kept in chg:a3f7b2… - undo with `tovio undo`
→ chg:phb97d… : src/integrations/cgm/dexcom.ts
No manual "fixup!" commits, no interactive rebase — TOVIO figures out where each edit belongs. It is
conservative: a file that no ancestor (or several ancestors) touched stays in your change, and when
nothing at all routes — every fixup was new code, or there is no unlanded stack forked off main —
absorb declines with TVO-OP-016 rather than guessing.
Reorder — change the order of a stack¶
The CLI specification designs tovio reorder <change-id> --before <change-id>, preserving Change IDs
across the reorder.
Not yet available
tovio reorder is not implemented.
Rebase — re-parent changes onto a new base¶
The top-level form reparents the current change and its stack onto another lane or change
(default main):
✓ Rebased chg:002… onto main (2 change(s) reparented, Change IDs unchanged) - undo with `tovio undo`
To name the change explicitly — or a linear range <start>..<tip> — use the change form:
rebase is the explicit re-parenting form. In everyday work you rarely need it directly, because
tovio land auto-rebases a stack for you when you land its base. Dependent lanes are
re-derived through the same path-scoped descendant cascade. Where content can't auto-merge, conflicts
are stored, not blocking — the summary reads N conflict(s) stored (resolve, then land) — see
Resolve conflicts. Rebasing onto a protected lane is the exception: it
refuses to leave unresolved conflicts there. A lane already based on the target reports
nothing to rebase.
Where these sit in the CLI
commit --amend sits with commit in everyday use; split and absorb live under the everyday
tovio change group; tovio rebase (and, once they ship, squash and reorder) sits one tier
deeper in tovio help --advanced — kept out of the default tovio help index so the everyday
surface stays small, but always runnable by name. They are documented here because they're the
heart of fearless history editing.
A note for teammates and agents¶
Because the Change ID is stable, rewriting your history doesn't break anyone who's tracking your change.
A teammate who pulled chg:a3f7b2 as a dependency keeps a valid reference after you amend it — TOVIO
notifies them with an impact pointer and a rebase suggestion rather than leaving them with a dangling
hash. That cross-developer flow lives in the collaboration guides.
Where to go next¶
- Reshaped a change and ready to ship it? → Land a change
- A rewrite produced a conflict? → Resolve conflicts
- Don't like the result? → Undo and redo recorded operations
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure