Undo almost anything

tovio undo and redo, over the local op-log.

Written By Dustin

Last updated 29 minutes ago

tovio undotovio redo

Reverses the last operation, and re-applies it. Not just commits — any operation recorded in the op-log, including a land, a lane switch, a tovio mv, a conflict resolution, or a lane delete. Each op-log entry is a full state snapshot, so applying one is a correct restore rather than a replayed inverse.

Rewinding further

tovio undo --to <op-id>

Rewinds to before that operation — undoing every step back to and including it — instead of stepping back one at a time. --to is the only flag undo defines; redo has none.

Finding an op-id

tovio explain undo             # the last 20 operations, the head, and what undo would restoretovio explain undo --limit 50tovio explain undo --to <op-id>   # preview that restore before running it

Op-ids also appear in the --json results, though the two commands report different fields. undo --json gives undone, undone_count, undone_op_id, now_at_op_id, redo_command and rotation_reverted. redo --json gives only redone and now_at_op_id — do not write a script that reads the other four off a redo.

Read those two ids carefully. undone_op_id is the operation that was just reversed; now_at_op_id is the one you are standing on. Because --to rewinds to before the operation you name, feeding now_at_op_id straight back rewinds one step further than where you are — name the earliest operation you want gone, not the one you want to keep. Preview it first with tovio explain undo --to <op-id>.

An op-id that is unknown, or already ahead of the current position, is TVO-CLI-018 (exit 2). An empty or fully-rewound op-log is TVO-OP-002 (“Nothing to undo / redo”, exit 19).

Why this replaces several Git commands

Git spreads this across reset, revert, checkout and reflog, with different recovery stories and different levels of danger. TOVIO records operations in one log and walks it in both directions. Undone operations stay in the log, so everything you undo remains redoable.

What undo does not do

  • It is local. Undoing something you already pushed does not retract it from a remote — sync the result.
  • It does not recover uncommitted edits. Those were never an operation, so they are not in the log; see the article on tovio restore.
  • It does not un-run tovio obliterate. Obliteration is permanent by design, requires the exact confirmation phrase obliterate <object-hash> (a generic --yes is rejected with TVO-CLI-002), and leaves a signed tombstone.
  • It does not reverse a landed change for everyone else — that is tovio revert <rev>, which writes a new inverting change.

Undoing a key rotation

Undoing across an access revoke is allowed but warns loudly: HEAD rolls back to a version still sealed to the revoked recipient while the roster stays revoked. Commit again, or re-run tovio access revoke, to re-rotate. The --json result flags this as rotation_reverted.

Garbage collection is undo-safe

tovio gc removes an object only when it is reachable from no ref, no tag, and no op-log entry — so it never collects something undo still needs.