How is the undo tree used in Vim?

28,955

Solution 1

See also :h undo-redo, which lists all the commands and their usage.

There are two ways to traverse the undo tree. One is to go "back in time". g+ and g- will traverse all of the nodes in the tree in chronological or reverse-chronological order (which can be a bit confusing, because it can jump arbitrarily between undo branches, but if you do g- long enough you'll always get where you need to go eventually). :earlier and :later take a time descriptor like 7m or 1h; again this can jump you arbitrarily between undo branches.

The other way is to jump to specific nodes in the tree using :undo n where n is a number of an action. (All actions, i.e. text additions, deletions, replacements, are numbered sequentially as you do them.) You can look up the number of the actions on the leaves of the undo tree via :undolist. This will let you jump between branches easily. You can then use u and Ctrl-R to move up and down that branch.

There are some good examples in the Vim help. The best way to figure out how this works is to play with it a bit.

Solution 2

I'm a bit late to the party,
but I figured I'd mention that I wrote an undo tree visualization plugin for Vim :
https://github.com/sjl/gundo.vim

Personally I found that graphing the tree like this was the only way I could make sense of it.

Solution 3

This page explains everything you need to know:

http://vimdoc.sourceforge.net/htmldoc/usr_32.html

Solution 4

If you're using vim, you can navigate through the undo tree using:

  • u: (undo) move back in the undo tree
  • Ctrl+R: (redo) move forward in the undo tree

Other ways of bringing document back or forward in time:

  • :earlier 15m: move back in time 15 minutes
  • :later 15m: move front in time 15 minutes

Solution 5

I'm aware this question has been answered, but I thought I'd add an example.

Create a new file and type:

this is a line

undol will display the undo tree. At this point you haven't undone anything

:undol

number changes  when               saved
     1       1  14:50:36

now press ESC and modify the line to:

this is a old line

switch to normal mode and press u (undo), this should remove "old". If you check undol, at this point you still have only one branch.

now modify the line so it says:

this is a new line

Now :undol shows:

number changes  when               saved
     2       2  87 seconds ago
     3       2  3 seconds ago

You can switch to the first branch by typing

:u 2

this will move you to the end of the branch associated with number 2. You can move along this branch with g+ and g-. At this point g+ will do nothing (you are at the leaf). If you press g- “old" will be removed (you are traversing the first undo tree). That is if you remove “old” with g- and press g+ again, “old" will be redone.

If you type

:u 3

You will jump to the leaf of the second undo branch and it will read:

this is a new line
Share:
28,955
Nathan Fellman
Author by

Nathan Fellman

SOreadytohelp

Updated on December 26, 2020

Comments

  • Nathan Fellman
    Nathan Fellman over 3 years

    This answer says:

    Vim's undo/redo system is unbeatable. Type something, undo, type something else, and you can still get back the first thing you typed because Vim uses an undo tree rather than a stack. In almost every other program, the history of the first thing you typed is lost in this circumstance.

    This is the first I hear of this. How can I backtrack along the tree?

    • Aaron Miller
      Aaron Miller over 10 years
      Jealous Emacs users may wish to know about undo-tree-mode.
  • he_the_great
    he_the_great about 14 years
    Can you merge branches? (I'm kidding)
  • Pod
    Pod about 13 years
    Kinda of. Look up :h undojoin
  • andyortlieb
    andyortlieb over 12 years
    Vim is so awesome that it even implements ways we joke about how awesome it is!
  • ndvo
    ndvo over 11 years
    I didn't know how to use this undo-tree, but I knew it would save my life someday. Well, the day has come. Thanks!!
  • Kyle Strand
    Kyle Strand over 10 years
    @Pod It looks like undojoin has nothing to do with branches; in fact, the very next help section starts by saying "Above we only discussed one line of undo/redo. But it is also possible to branch off." Is there some way to use undojoin with branches that I'm just not seeing?
  • Jonathan Hartley
    Jonathan Hartley over 7 years
    This answer only explains how to move forwards and backward on one branch. Not how to move between branches.
  • Holloway
    Holloway about 7 years
    This will move across all branches sorting all points by time order. See @BrianCarper 's answer.
  • alpha_989
    alpha_989 over 6 years
    @JonathanHartley, if you are using earlier and later it is not moving across branches. I would expect that most people dont really care or remember the various branches they created. But just want to go back in time. If you want to create branches and name them perhaps git or a version control system is a better option.
  • alpha_989
    alpha_989 over 6 years
    persistent-undo is amazing.
  • Jonathan Hartley
    Jonathan Hartley about 6 years
    @alpha_989 Your comments about version control don't make sense. Version control is for the state of named files on disk. We're talking about Vim's undo tree, which is just data structures in memory. They both use the word 'branch', but it doesn't mean the same thing.
  • Jonathan Hartley
    Jonathan Hartley about 6 years
    Thanks to everyone pointing out earlier/later DO move across branches!
  • alpha_989
    alpha_989 about 6 years
    @JonathanHartley.. you are right.. When you are using earlier/later you are moving across the persistent-undo branches. I was using branch in the context of git. in my limited opinion, the persistent-undo is a kind of version control, because you can create a certain branch and keep working on that branch of that file. You can then create a new branch, and work on that which will kindof simulate git branches. What I was stating is that you shouldnt use vim branches as a replacement for git-branches.
  • alpha_989
    alpha_989 about 6 years
    If you define undodir, persistent-undo saves the undobranches on disk. Its not just in-memory.
  • Jonathan Hartley
    Jonathan Hartley about 6 years
    Thanks for explaining your thoughts.
  • elig
    elig about 5 years
    There's no sense in joining undo branches because they can be composed of contradicting changes. undojoin can help join a series of upcoming changes into one undo block so they can be undone with one undo later on in the file.
  • elig
    elig about 5 years
    u and Ctrl-r don't move in the undo tree but in the undo "stack". g+ and g- move in the tree through branches as well.
  • ewen-lbh
    ewen-lbh almost 4 years
    A more up-to-date git repository exists at github.com/sjl/gundo.vim. With vim-plug, the plugin can be installed with Plug 'sjl/gundo.vim' and then nnoremap <F5> :GundoToggle<CR> (replacing <F5> by whatever key sequence you want to bind)