Undo is why I experiment
This is one of the reasons I am comfortable being creative with jj.
If I make a mess, I usually do not clean it up by hand. I undo the operation.
jj undo
jj keeps an operation log: every commit, rebase, split, squash, bookmark move, and undo I asked it to do. jj undo steps back through that log.
It is not a time machine for the remote, but it is enough to make local experiments feel cheap.
If I undo too far, I can move forward again:
jj redo
When I reach for it
The simple case is after I run a command and immediately dislike the result:
jj squash
jj undo
This also pairs really well with agents.
If I ask an agent to resolve a conflict or reshape some code and the result is not going in the right direction, I do not need to manually reconstruct the old state. I can usually do:
jj undo
jj status
jj diff
Then I try again with a narrower prompt.
Why this changes behavior
Undo makes experimentation cheap. I can let an agent try something, inspect the diff, and back out quickly if the result is worse than the starting point.
When undo is not enough
If I need more context than “undo the last thing”, I look at the operation log:
jj op log
If I want to see what an operation changed:
jj op show -p
And if I want to restore a specific earlier operation:
jj op restore <operation-id>
Most of the time I only need the short version:
jj undo
That one command makes a lot of the other workflows feel less scary.