Take the 2-minute tour ×

Undo is nice to have in Vim. But sometimes, at a known good point, I want to erase my undo history - to be able to use u to undo individual changes, but only back to a certain point. (For instance, this might be when I last committed.)

One way to accomplish this would be to close and reopen the file - the undo history starts clean at that point. But that's a hassle.

In the past, I accomplished this with :edit!. But in Vim 7.3, that doesn't discard the undo history.

Is there another way to do this, apart from closing the file?

share|improve this question
so you actually just want to restore the state of the file as it was on your last commit? you want essentially just remap the 'u' key to something like git checkout -f file or hg rollback file? –  akira Nov 24 '10 at 18:34
@akira - no, I want to be able to use u to undo individual changes, but not past the point where I last committed. Exactly as if, every time I committed, I closed the file and re-opened it. Which is what :edit! used to do - it was like closing the file and reopening it. This doesn't HAVE to be tied to a commit point, that's just the time when I'd most frequently want it. –  Nathan Long Nov 24 '10 at 20:08
ah, that makes the problem much clearer. you should change your question a bit. –  akira Nov 24 '10 at 20:24
@akira - thanks, I updated it. –  Nathan Long Nov 24 '10 at 20:32
add comment

6 Answers

up vote 4 down vote accepted
:set undoreload=0 | edit

should do what you're asking for.

share|improve this answer
Ha! Just turn that feature off, eh? :) Not sure why it took me so long to notice this. –  Nathan Long Oct 21 '12 at 12:32
add comment


:let old_ul=&ul
:set ul=-1
:let &ul=old_ul
:unlet old_ul

('ul' is alias for 'undolevels').

share|improve this answer
This works! Now I'm trying to make a single command do that - preferably :edit!. As a start, I've made a function called ClearUndos() with the commands you listed, but calling it doesn't seem to do anything, whereas doing the commands individually does... –  Nathan Long Nov 24 '10 at 20:25
:command -nargs=0 Reset let old_ul=&ul | set ul=-1 | e! | let &ul = old_ul | unlet old_ul –  Benoit Nov 24 '10 at 21:38
is that meant to be the contents of the function? It's not working for me, but maybe I misunderstood. Also - maybe move this to its own answer? –  Nathan Long Nov 29 '10 at 13:32
Maybe you cannot put raw | in a command content. Then create a function that does what I told in my answer, and set the command to call thefunction(). –  Benoit Nov 29 '10 at 13:36
add comment

The old :edit! behaviour in a one-liner:

:exe "set ul=-1 | e! | set ul=" . &ul
share|improve this answer
That does work. Would you mind explaining it? –  Nathan Long Jun 7 '12 at 20:06
Concatenate the value of the undolevels setting on the end of the string of commands (so that it can be restored) and executes them. For more info see the documentation: :h :exe, :h :bar, :h :set-args, :h 'ul' and :h :edit!. –  Aldrik Jun 18 '12 at 17:07
add comment

Benoit's function didn't work for me, but I found something similar in the vim manual, here:


I slapped it into a function, added to my vimrc and it seems to be working fine on vim 7.3:

" A function to clear the undo history
function! <SID>ForgetUndo()
    let old_undolevels = &undolevels
    set undolevels=-1
    exe "normal a \<BS>\<Esc>"
    let &undolevels = old_undolevels
    unlet old_undolevels
command -nargs=0 ClearUndo call <SID>ForgetUndo()

This can be used with :ClearUndo.

share|improve this answer
Working normally with Gundo plugin and undo file reloading, this thing comes really handy for me. However, I changed two things: instead of the normal edit command (which itself leaves some edit history on 7.4 it seems), I simply use an edit! (and always write before erasing the undo history). It seems that some internal lists are not properly updated, so if you want to use this with Gundo plugin, doing an additional edit! at the functions end will prevent it from erroring out later. –  PlasmaHH Dec 20 '13 at 10:39
@PlasmaHH Could you please post the function for clearing undo history, because I did not understand what did you change... (you could maybe post it as an answer for those of us who use gundu). Thanks –  Ben Feb 25 at 12:10
add comment

In a script:

function! <SID>ForgetUndo
     let old_ul = &ul
     set ul=-1
     let &ul = old_ul
     unlet old_ul
command -nargs=0 Reset call <SID>ForgetUndo()

Then use :Reset to call it.

share|improve this answer
Your function definition line needs () at the end. –  Nathan Long Nov 29 '10 at 17:13
This is odd - running those commands individually works fine, and echoing the values throughout the function shows that they are set and unset appropriately. But running the function doesn't reset my undo history - afterwards, I can still undo multiple times. Maybe the set ul= command only affects a local variable until the script exits, and since we change it back before the script exits, it never affect the environment? Did you test this function and have it work - meaning, is there something odd about my setup? –  Nathan Long Nov 29 '10 at 17:15
add comment

" Clear undo history (:w to clear the undo file if presented)
command! -bar UndoClear exe "set ul=-1 | m-1 | let &ul=" . &ul

  • When you set 'undolevels' to -1 the undo information is not immediately cleared, this happens at the next change, i.e. m-1, which doesn't actually change your text.
  • When 'undofile' is on, :w to clear the undo file, or chain like UndoClear|w.
share|improve this answer
add comment

Your Answer


