How do I do redo (i.e. "undo undo") in Vim?
Categories:
Mastering Undo and Redo in Vim: The 'Undo Undo' Explained

Learn how to effectively navigate your edit history in Vim, including the crucial difference between 'redo' and 'undo undo' to recover lost changes.
Vim's powerful editing capabilities extend far beyond simple text manipulation, offering a sophisticated undo history that can sometimes be confusing. While u
(undo) is straightforward, understanding how to 'redo' or, more precisely, 'undo an undo' is key to efficient editing and recovering changes you thought were lost. This article will demystify Vim's undo tree and show you how to master your editing history.
The Basics: Undo (u
) and Redo (Ctrl-r
)
At its core, Vim provides two primary commands for navigating your edit history: u
for undo and Ctrl-r
for redo. When you make changes to a file, Vim records these changes as a sequence of operations. Each u
command moves you backward through this sequence, reverting the last change. Conversely, Ctrl-r
moves you forward, reapplying the changes that were undone.
iHello World
<Esc>
x
u
<C-r>
Basic undo and redo sequence in Vim.
In the example above, we insert 'Hello World', delete a character, then undo the deletion, and finally redo the deletion. This linear progression is simple enough, but Vim's undo history is not always a simple line; it's a tree.
Understanding Vim's Undo Tree
Unlike many other editors that maintain a linear undo history, Vim implements an 'undo tree'. This means that if you make some changes, then undo them, and then make new changes, Vim doesn't discard the undone branch. Instead, it creates a new branch in the undo tree. This is where the concept of 'undo undo' becomes critical.
flowchart TD A[Initial State] --> B{Edit 1} B --> C{Edit 2} C --> D{Edit 3} D -- u --> C C -- u --> B B -- New Edit --> E{Edit 4 (New Branch)} E -- <C-r> --> E E -- u --> B B -- <C-r> --> C C -- <C-r> --> D
Vim's undo tree illustrating branching history.
Consider the diagram: if you are at 'Edit 3', then press u
twice to go back to 'Edit 1', and then make a 'New Edit', you've created a new branch. If you then press u
again, you'll go back to 'Initial State'. If you want to get back to 'Edit 2' or 'Edit 3' from 'Initial State' (after making 'New Edit' and undoing it), Ctrl-r
will only take you back to 'New Edit', not the original 'Edit 2' or 'Edit 3' branch.
Ctrl-r
command only redoes changes on the current branch of the undo tree. If you've branched off, Ctrl-r
won't take you back to a previous, discarded branch.The 'Undo Undo' Mechanism: Navigating Branches
To truly 'undo an undo' and explore different branches of your edit history, Vim provides a more advanced mechanism: the undo history commands. These allow you to jump to specific points in your undo tree, effectively letting you recover changes from older branches.
:earlier 1m
:later 30s
:undolist
:undo 5
Commands for navigating Vim's undo history.
Here's what these commands do:
:earlier {N} {time}
: Jumps to a stateN
changes ortime
ago. For example,:earlier 10f
goes back 10 changes, and:earlier 5m
goes back to the state of the file 5 minutes ago.:later {N} {time}
: Jumps forward in time or changes. This is the true 'undo undo' for navigating branches.:undolist
: Shows a list of all saved undo points, including their change number and time. This is incredibly useful for understanding your undo tree.:undo {N}
: Jumps directly to undo point numberN
from the:undolist
output.
undofile
enabled in your .vimrc
. This means you can close Vim and reopen it, and your undo history will still be there!set undofile
set undodir=~/.vim/undodir
Enabling persistent undo in your .vimrc.
1. Make some initial edits
Open a file in Vim and type iThis is the first version.<Esc>
. Then, type oThis is the second version.<Esc>
.
2. Undo a change
Press u
to undo the second line. You are now back to 'This is the first version.'.
3. Create a new branch
Type oThis is a new branch.<Esc>
. You have now created a new undo branch.
4. View undo history
Type :undolist
and press Enter. Observe the different undo points and their numbers.
5. Navigate to an older branch
From the :undolist
output, identify the undo point that corresponds to 'This is the second version.' (it will likely be a lower number than your current state). Type :undo {N}
where {N}
is that undo point number. You should now see 'This is the second version.' again, effectively 'undoing an undo' from a different branch.