How to undo in Codex, and what you can't get back
People ask for "undo" in Codex when they mean three different things: take back a message, put the files back, or reverse something that already happened outside the repository. Codex treats those separately. The command people remember, /undo, is not in the current documented command list. The desktop app and IDE extension have a narrower file undo. Pressing Esc twice moves the conversation and leaves the files where they are.
That split is the whole answer. Once you know which undo you need, the options are short.
Checked against Codex's documentation on 26 October 2026.
Status, 26 October 2026: /undo is still not a documented Codex command, and the request to bring it back is open (#9203, last activity 20 October 2026). A separate request for a checkpoint that restores both the conversation and Codex-applied code edits is open (#11626, last activity 20 October 2026). The IDE extension still has an open report that historical message actions show only Copy, with Edit, Fork, and Rewind missing (#41796, last activity 2 September 2026). Backtracking has an open report of resetting the context meter to 0% and triggering compaction (older turns replaced by a summary) (#9601, last activity 9 September 2026). If a native rewind ships in your version, the habits below still apply.
Three different undos#
| What you want | What it means | What Codex has |
|---|---|---|
| Take back a message | Remove a prompt and everything after it from the conversation, or branch from an earlier point | Esc twice in the CLI to branch from an earlier message; /fork copies the chat from its current end. The original chat is kept. |
| Put the files back | Restore the working tree to what it was before Codex edited or deleted something | git restore for tracked files; an Undo/Revert action in the app and IDE that depends on Git; no documented general CLI command |
| Undo what it did out in the world | Reverse a migration, an API call, a publish, an email, an install | Nothing built in; Git never saw it |
Most of the frustration comes from using one row's tool for another row's problem. Esc twice will not restore a file. git restore will not remove a bad instruction from the model's context. Neither one will un-send an email.
Take back a message: Esc twice is a fork#
In the CLI, press Esc twice with an empty composer. Codex opens the transcript (the saved conversation), lets you choose an earlier user message, and forks the chat from that point. The docs describe the shortcut as editing the previous user message and forking the chat. A fork is a copy of the conversation from that point; the original chat stays on disk.
/fork branches from the current end of the chat, not from an earlier message. It copies the current chat into a new chat; the transcript picker in Esc-twice is what lets you choose an earlier point. codex fork opens the session picker from the shell, and codex exec fork <session-id> does it for a saved session. The point of a fork is that you can try a different direction without destroying the path you already took.
Two limits matter.
First, this is conversation state, not file state. The open checkpoint request describes exactly this gap: Esc twice rewinds the conversation to a fork point, but edits made after that point remain in the working tree (#11626). If Codex broke a file, forking the chat gives you a cleaner conversation and the same broken file.
Second, backtracking can confuse the context accounting. An open report says the context indicator jumps to 0% left after a rollback and the next turn triggers auto-compaction, even when the remaining history should be well below the window (#9601). If that happens, the practical response is to treat the next turn as post-compaction: restate the current state and the next action, or start a fresh chat from a short handoff instead of fighting the meter. Context compaction covers what a summary keeps and drops.
In the IDE extension, /fork is available as a slash command, but the per-message Edit, Fork, and Rewind actions have been reported missing (#41796). If you need to branch from an earlier message, the CLI is the more predictable surface today.
Put the files back in the CLI#
There is no documented /undo or /rewind in the CLI. The command list includes /diff, /fork, /compact, /review, and the rest, but nothing that restores a working tree. The current answer is Git plus a habit.
Start by seeing what changed:
git status
git diff/diff inside Codex is also useful because it shows the Git diff including files Git is not tracking yet. That matters when Codex created a new file: git diff alone will not show it.
For a tracked file, git restore <path> puts the working copy back to the index (the staging area). git restore --staged <path> unstages it. If you want to throw away every unstaged change under the current directory, git restore. does that, but read the diff first; it also throws away changes you made yourself.
For an untracked file that Codex deleted and you never stashed, Git has nothing to restore. The file was never in the index, so there is no blob to recover. This is the case the /undo request keeps returning to: a file that was not committed, not stashed, and not backed up is gone. No documented Codex command brings it back.
The same applies to ignored files. Build output, local databases, .env files, and generated assets usually live outside Git's view. A restore command cannot recover what Git was told to ignore. If those files matter, they need a backup or a snapshot that is not Git.
A snapshot can be a hook. Codex's PreToolUse hook runs before a tool call and receives the tool input, so you can point it at a script that copies the workspace to a directory outside the repository before each risky action. That is a script you write and maintain, not a built-in checkpoint. The hooks guide covers where such a hook loads and how to prove it ran; the simpler version is to commit or stash before the run.
git stash push -u is the one-line version for untracked work: it saves tracked and untracked changes and returns the tree to the last commit. The catch is that you have to run it before Codex does the damage, not after.
Two more habits make the CLI recoverable:
- Commit at safe points. A commit is a checkpoint Git can actually restore.
- Keep risky exploration in a separate worktree, a second checkout of the same repository. Codex's worktree support is built for parallel chats; it also keeps a bad edit away from your main checkout. It does not make an untracked deletion recoverable inside that worktree.
Asking Codex to reverse its own patch can work, but treat it as a request, not a guarantee. Be explicit: "Show me the diff of the changes you made in the last turn, then revert only those files, and do not touch anything else." A model that has lost track of the turn can revert too much. Check the diff before you accept it.
The Undo button in the app and IDE#
The desktop app and the IDE extension show an Undo or Revert action on the changed-files card. The documentation for the review pane describes reverting at three levels: the entire diff, one file, or one hunk (a contiguous block of changed lines). That is a real file undo, and it is more convenient than typing Git commands.
It has two caveats.
It depends on Git. The open reports are explicit: outside a Git repository, the undo action reports that Git is required (#19205, open, last activity 21 August 2026; #34634, open, last activity 21 July 2026). If you use another version-control system, or no version control, the button is not a general-purpose undo.
It is not always reliable. There are open reports of the app showing "No changes reverted" and skipping a tracked file, of the review panel losing its diff list and the Undo button doing nothing, and of Undo failing in a recent extension build (#28506, open, last activity 16 June 2026; #10503, open, last activity 31 July 2026; #23326, open, last activity 18 May 2026). If the button fails, the files are still on disk. Run git diff and git restore in a terminal; do not click Undo twice and assume the second click worked.
The app's Cmd+Z or Ctrl+Z is labelled "Undo last app action" in the command reference. That is not the same as the file-change Undo, and it is not a substitute for Git.
What you can't undo#
These are the cases where the honest answer is "you can't, not with Codex alone":
- An untracked or ignored file that Codex deleted, with no backup.
- A command that changed something outside the repository: a database migration, an API call, a deploy, a publish, an email, a package install, a cloud resource.
- A file edit outside the workspace that succeeded before you noticed.
- A compaction summary. The conversation continues from generated text; the turns the summary replaced are not put back into the model's context by undoing a message. The original transcript may still be on disk, but the model is not reading it.
- A tool call that already ran.
PostToolUseruns after the tool and cannot undo it; the hooks docs say so directly.
The pattern is the same in every row: Git can restore what Git recorded, and Codex can fork a conversation. Everything else needs a backup, a snapshot, or a decision made before the action.
Where to go next#
This guide is part of Codex guides.
- Why Codex keeps asking for approval — read-only is a sandbox mode, not a promise.
- Codex hooks that don't fire — if you want a snapshot before each tool call.
- Context compaction — what a summary keeps and drops.
- Hand off work between Claude Code and Codex — when starting fresh is safer than rewinding.