Lesson 6 of 32
Checkpoints and Undo
How file snapshots let you rewind a session, the difference between restoring code, conversation or both, and the two gaps that make git still necessary.
The previous lesson was about deciding what happens. This one is about undoing what did. Together they are why you can let an agent work on your project without watching every keystroke.
There is also a limit in here that people discover the hard way, so the honest version is in this lesson rather than a footnote.
Stopping, first
Before undoing anything: you can stop.
Press Esc and Claude halts immediately. The tool call in progress is cancelled
and it waits for you. Work already done is kept — this is an interruption, not a
reset. If a dialog such as a permission prompt is open, Esc closes that
instead.
Interrupting early is the cheapest correction available, and new users are strangely reluctant to use it. If you can see a session heading somewhere wrong, you do not need to wait politely for it to arrive.
How checkpoints work
As you work, Claude Code captures the state of your code before each prompt you send. That is the unit: a checkpoint per message, not per edit.
Snapshots are kept for the hundred most recent checkpoints in a session, and they are saved alongside the conversation itself — so if you close the terminal and resume the session tomorrow, rewinding still works. They are eventually cleaned up with the session, after thirty days by default.
Underneath, your conversation is a plaintext file. Each message, tool call and
result is written to a JSONL file under ~/.claude/projects/, which is what makes
rewinding, resuming and forking a session possible at all. That directory is worth
knowing exists; a later lesson goes through it properly.
Rewinding
Open the rewind menu with /rewind, or by pressing Esc twice when the prompt
box is empty.
That last condition matters. If there is text in the prompt, a double Esc clears
it instead — and the cleared text goes to your input history, so Up brings it
back. If the shortcut seems not to work, you had a draft.
The menu lists the prompts you sent during the session. Pick one, and then pick what to do with it:
- Restore code and conversation — go back to that point entirely
- Restore conversation — rewind the discussion, keep the current code
- Restore code — revert the files, keep the discussion
- Summarize from here — compress everything after that point into a summary, freeing space in the context window
- Summarize up to here — compress everything before it, keeping the recent messages intact
- Never mind — back out
The two code options only appear when the checkpoint you selected actually has tracked file changes to revert. If Claude only read and explained things after that point, there is nothing to restore, and the menu says so by omission.
One nice touch: after restoring the conversation, the prompt from the message you selected is put back in your input box. So the natural move — go back to where it went wrong, rephrase, try again — takes no retyping.
Three different rescues
Being able to move code and conversation independently sounds fussy until you need it. The three combinations solve genuinely different problems.
Restore code and conversation is the clean reset. The approach was wrong from the start; go back to before it and describe the task differently.
Restore code, keep the conversation is for when the understanding is right and the implementation is not. Claude spent ten minutes learning how your auth module works, and you would rather not throw that away — you just want the files back and a second attempt.
Restore conversation, keep the code is the least obvious and often the most useful. A long debugging session produced twenty messages of dead ends and one good fix. The fix is on disk. The twenty messages are now filling the context window with wrong theories that will keep influencing what comes next. Rewind the conversation, keep the code, carry on with a clean head.
The summarise options serve the same instinct without discarding anything: compress a verbose stretch into a summary while your original instructions stay intact.
Watching it work — and not work
You typed: Convert the settings page from class components to hooks.
Claude ran: Read app/settings/page.tsx
Claude ran: Edit app/settings/page.tsx
Claude ran: Edit app/settings/tabs.tsx
Claude ran: Run: npm test settings
Output: FAIL 4 of 11 tests failedClaude replied: The conversion changed when state updates flush, so four tests that relied on the old timing now fail. I could adjust the tests, or restructure the effects to preserve the original ordering.
WhyNeither of those is obviously right, and the second is a bigger change than you asked for. This is the moment to go back rather than to keep going.
You typed: /rewind
Output: Select a point: 1 Convert the settings page from class components to hooks Action: > Restore code and conversation Restore conversation Restore code Summarize from hereWhyRestoring both, because the plan itself was too coarse. The two edited files go back to their pre-prompt contents.
You typed: Convert only tabs.tsx to hooks, keep the state update timing identical, and run the settings tests before you touch anything else.
Claude ran: Run: npm test settings
Output: PASS 11 testsClaude ran: Edit app/settings/tabs.tsx
Claude ran: Run: npm test settings
Output: PASS 11 testsClaude replied: tabs.tsx now uses hooks. Timing preserved, all eleven tests still pass.
WhyThe second attempt succeeded because the rewind made a second attempt free. Without one, the tempting move is to let Claude edit the failing tests, which loses you the only thing that was telling you the truth.
What checkpoints do not cover
Here is the part to actually remember.
This is not an edge case. Deleting a file, renaming a directory, running a formatter across the project, applying a migration, running a code generator — all shell work, all invisible to rewind. A session can feel completely reversible right up until the one action that was not.
Three smaller gaps, worth knowing:
Subagent edits are usually not restored. Work delegated to a subagent generally does not land in your session's checkpoints, so use git to revert it.
External changes are not tracked. Files you edited yourself in your editor, or another session edited concurrently, are outside what this session snapshotted.
Symlinked and hard-linked paths are skipped. A restore that encounters one leaves it alone and warns you that it skipped some files. Config that a dotfile manager symlinks into your project falls into this category, as do files some package managers hard-link into place.
So: git
Checkpoints are designed for quick session-level recovery. For permanent history, branches and anything you want to share or return to next week, you use version control, exactly as you did before.
Which turns into one habit worth building now, before you have a reason to regret not having it: start with a clean tree. Commit or stash what you have before you set an agent working. It costs five seconds and it gives you a floor that does not care whether the change came from a file edit, a shell command, a subagent or a formatter you forgot was configured.
A commit is also what makes git diff useful, and git diff is how you review an
agent's work at any real size. Reading changes as they scroll past is not review;
reading the diff afterwards is. Accept-edits mode plus a clean starting commit plus
git diff is a genuinely good way to work, and it depends entirely on the commit.
What to take away
Claude Code snapshots your files before each prompt you send, keeps those
snapshots with the conversation so they survive resuming, and exposes them through
/rewind or a double Esc on an empty prompt. You can restore code and
conversation together or move either one alone, which covers three different kinds
of mistake — wrong plan, wrong implementation, and a conversation cluttered with
dead ends. Esc on its own stops Claude mid-action while keeping what it has
done. The limit that matters is that only edits made by Claude's file tools are
tracked: shell commands, subagent work and your own edits are not, and no
checkpoint is a substitute for a commit.
Next: putting all six lessons together on a real task, start to finish, with the reasoning at each step made explicit.
Check yourself
5 questions · pass 4/5 to unlock Your First Real Task
1.When is a checkpoint created?
2.Claude ran a shell command that moved a file, and you want to undo it. Will rewinding restore it?
3.You want to keep the code Claude just wrote but drop the last twenty messages of debugging discussion. Which option does that?
4.What happens if you press Esc twice while your prompt box has text in it?
5.Why are checkpoints not a replacement for version control?
5 left to answer