Skip to content

Undo and redo recorded operations

tovio undo is broader than commit rollback: it reverses the latest supported mutation retained in the repository's local op-log. Recorded commits, amends, lands (with their cascade), switches, rebases, splits, absorbs, lane creates and deletes, moves, tags, and conflict resolutions are all reversible entries.

The boundary matters. Undo does not recall objects or ref observations already received by a peer, reverse effects in an external service, restore entries removed by retention, or reverse explicit permanent maintenance such as authenticated obliteration. A sync is not an op-log entry at all.

Undo the last operation

$ tovio undo
✓ Undid: Add Dexcom G7 sync handler
  Redo with: `tovio redo`

Every undo tells you two things: what local entry it reversed (the entry's description — for a commit, its message) and how to redo it. Your working tree and repository pointers are returned to the state before that operation; the entry moves to local redo history while it remains retained.

Short alias

The CLI specification reserves tovio u as the short alias for tovio undo; it is not in the shipped binary yet, so use the full name.

Supported local entries

The op-log is broader than Git's reflog. The implemented reversible entries include:

You did this tovio undo does this
tovio commit / commit --amend Reverses the commit (or the amend), restores the pre-commit tree
tovio land (and its cascade) Reverses the land and every descendant rebase, as one step
tovio switch Returns you to the previous lane or change, with the exact materialized tree
tovio lane <name> / tovio lane -d <name> Removes the created lane / restores the deleted lane
tovio rebase, change rebase, change split, change absorb Reverses the rewrite; Change IDs are unaffected
tovio resolve Reopens the conflict the resolution closed
tovio mv Reverses the recorded move, including the working-copy rename

A landing with a full rebase cascade undoes in a single tovio undo — you don't unwind it descendant by descendant.

Two designed rows are not there yet

The CLI specification also lists tovio merge and tovio sync among undoable operations. There is no standalone tovio merge verb (integration is tovio land), and tovio sync does not record an op-log entry today — undo will not rewind a sync. See Resolve conflicts and Rewrite history for the status of the rewrite commands.

Redo what you undid

Changed your mind? Replay the undone operation:

$ tovio redo
✓ Redid: Add Dexcom G7 sync handler
  Reverse with: `tovio undo`

undo and redo are symmetric. As long as you haven't started new work over the top, you can step back and forth freely.

Undo several operations at once

To rewind to just before a specific op-log entry — undoing everything since, all moved to redo history — use --to:

$ tovio undo --to op:7a1b2c3d4e5f6a7b
✓ Undid 3 operations, back through: switch to feature
  Redo with: `tovio redo`

--to needs the full operation id (op: plus 16 hex digits). Get one from the --json result of undo (undone_op_id, now_at_op_id) and redo (now_at_op_id), or from tovio explain undo --json (each detail.entries[].id) — pass now_at_op_id to undo --to to rewind to that point again. The human tovio explain undo view below abbreviates ids to op:xxxxx… for scanning; that abbreviation is enough for its own --to preview, which accepts a prefix, but not for tovio undo --to.

Two targeting flags are still ahead

Plain tovio undo, tovio redo, and tovio undo --to <op-id> are implemented in the current source tree. The other targeting flags in the CLI specification — -n <count> and --op <op-id> — are not implemented yet; without --to, undo and redo step one operation at a time. No generally available package has been published.

See the operation log

The op-log is the local, timestamped history behind undo/redo. The shipped viewer is the undo lens of tovio explain: it lists the most recent operations newest first with their ids, marks where you are in the log, and previews exactly what the next undo (or undo --to) would restore — read-only:

$ tovio explain undo
$ tovio explain undo --to op:7a1b2c3d4e5f6a7b   # preview the rewind before doing it
Op-log trace
  local operation history — what `undo`/`redo` would do (not synced)
  …

  Verdict: head at op:70b5a… (resolve) · 9 operation(s), 0 redoable

── Stage 1 · Operations (newest first) ───────────────────
  ✓ op:70b5a…  resolve                 resolve shared.txt (ours)  ← undo reverses this
  · op:5029a…  land                    land feature into main (materialized conflicts)
  · op:2fac2…  commit                  Main edits shared

── Stage 2 · What `undo` restores (next step) ────
  ⚠ lane main                          e9176f9d24… → 5aaa2def7f…
  · current change                     chg:248v7vcx… → chg:pcf4f8cs…

The op-log is local and is not synced.

redo is advanced-tier; oplog is specification-only

tovio undo lives front and center in the everyday surface; tovio redo sits one tier deeper (tovio help --advanced) but is always runnable by name. The dedicated tovio oplog viewer in the CLI specification is not implemented — tovio explain undo is the way to read the log today.

When there's nothing to undo

If the undo stack is empty, TOVIO says so plainly — a benign, catalogued error (TVO-OP-002) rather than a cryptic one:

✗ Nothing to undo

  The operation log has no further undoable operations on this repository.

  Inspect the operation log:
    tovio log

  [TVO-OP-002]  https://tovio.dev/errors/TVO-OP-002

(redo behaves the same way when the redo stack is empty: ✗ Nothing to redo, same code.)

Where to go next

Last reviewed September 9, 2026

Suggest an improvement to this page Not for security reports — see disclosure