Undo all changes since opening buffer in vim - vim

How can I undo all changes since opening a buffer? I imagine there may be some form of :earlier that does this.
UPDATE: Many are suggesting solutions for traversing to earlier file writes. This isn't what I asked for. I want to return to the original state the file was in when I originally loaded it into a buffer, no matter how many writes were made since then.

To revert the current buffer to the original state prior to the very
first change recorded in its undo list (see :help undo-tree), one
can use the following two consecutive invocations of the :undo
command:
:u1|u
The first command (:undo 1) reverts to the state of the buffer just
after the very first registered change, while the second command
(:undo) reverts that first change itself.
Starting with version 8.1 (see :helpg Patch 8.0.1441), Vim accepts
the change number 0 as a valid argument to the :undo command,
finally providing a way to refer to the state prior to any registered
changes. This makes it possible to achieve the same effect in
a single-command invocation:
:u0

You can use the
:edit!
command to get into the earliest saved state. See :help edit! for more information.
You can also check something like gundo.vim (can be found here), which displays the whole undo tree graphically, and you can easily jump between points. Then there is the histwin plugin which I did not used yet, but offers similar functionality.

In vim 8.1+ as well as in neovim, you can just use :u0

From the documentation
:u[ndo] {N} Jump to after change number {N}. See |undo-branches|
for the meaning of {N}. {not in Vi}
If you type
:u 1
it appears to go to after the first change; pressing u or typing :u will then go back to the change.
Otherwise, you can use a very large count to :earlier or g-
e.g.
:earlier 100000000 or 100000000g-
If you put this into a mapping/command, it could do any of these without too much trouble.
e.g.
:nnoremap <C-F12> :earlier 100000000<CR>

To access previously saved file status, I think the following work :
:earlier 1f
From the documentation :
:earlier {N}f Go to older text state {N} file writes before.
When changes were made since the last write
":earlier 1f" will revert the text to the state when
it was written. Otherwise it will go to the write
before that.
When at the state of the first file write, or when
the file was not written, ":earlier 1f" will go to
before the first change.

:earlier {N}m Go to older text state about {N} minutes before.
That should help... And even you have {N}h which is about {N} hours before.

A graphic solution:
The Gundo plugin allows visual comparison of changes in the undo history.
Open Gundo's "undo history pane", type G go to the last line, then we can back to the original file.

Related

Vim Undo command (the one with the with capital U)

I don't understand how the undo line command works.
The documentation says Undo all latest changes on one line.
What is the definition of all latest changes here?
One behaviour I have noticed is that sometimes U undoes all writes after the very first write on a line. But this is not consistent. For example, when I open a new file and edit the first line, writing multiple times, the U command undoes every single change.
I haven't been able to find anything concrete from my google searches either.
In my understanding all latest changes means going back the change history until a change in a different line is encountered, and stop there. So if you start with an empty buffer and edit only one line (repeatedly), all additions will be wiped by U.
Vim generally merges near changes occurring in the same line; these appear as a single entry in :changes.
U: return the last line which was modified to its original state (reverse all changes in last modified line)
http://vim.wikia.com/wiki/Undo_and_Redo

How to undo up to last write in vim?

Let me pose the question this way. I open a new file in vim, (version 1)
#include<stdio.h>
main()
{
...blah
}
and then use <Esc>:w<Enter> to write the file. Then made changes (version 2)
#include<stdio.h>
main()
{
...blah
... edit1
... edit2 //and large number of changes here and there in code
}
then I save changes using <Esc>:w<Enter>.
Is there a way to undo changes to version 1 directly (Since it was a last save) i.e., without constantly pressing u for undoing
From Vim's help:
:earlier {N}f Go to older text state {N} file writes before.
When changes were made since the last write
":earlier 1f" will revert the text to the state when
it was written. Otherwise it will go to the write
before that.
When at the state of the first file write, or when
the file was not written, ":earlier 1f" will go to
before the first change.
So, if you didn't make changes after the second save, you can do what you want with:
:earlier 1f
On the other hand, if you did unsaved changes after the second save, then:
:earlier 2f
will solve your problem.
See :help :earlier, :help :undolist.
You can get all the way back to when you first opened the file pretty easily. Just type a number before u.
10000u, will undo 10000 times. If that's not enough try 1000000u :)
If you want to undo bit by bit, you can do it in any increment, try 5u.
If you just want to reload the file from disk use :e.
Put this into your .vimrc.
In normal mode shift u will undo till previous save. Pressing again it will undo till the save before that. You can still go back to original point with a lot of <C-R> if you dint made any changes.
nnoremap U :ea 1f<CR>

How to use the :undolist feature in vim?

After making a couple of changes in an xml file opened in Vim I pressed :undolist and got the following output. Is there any way I can see the actual changes? Also what is the difference between number and changes columns? I see the numbers are always the same.
number changes time
2 2 10 seconds ago
if you :h undolist, difference between number and changes is explained. in short, number is a sequence number, changes are how many changes were made on that leaf.
If you want to go back to a earlier state, you could check :h earlier
I recommend a very nice undo plugin: https://github.com/sjl/gundo.vim with this you could view the states in history, without really applying them, until you find the right state.

Use vimdiff to replace entire file?

I'm using vimdiff for a git merge. Is there a quick way to select 1 file to use, right now i'm just selecting everything from one buffer, replacing the $MERGE with that, and then saving. I guess I can macro that, but was wondering if there is a better way.
Thanks!
Several ways:
:%diffput
to do 'put' all changes from the current buffer to the 'other' buffer. This makes it easy with three-way diffs:
:%diffput OURS
The 'OURS' pattern will match uniquely on buffernames participating in the current diff
All the above can be done in reverse, substituting do or :diffget
You should take a look at Tim Pope's Fugitive plugin. It's a really usefull plugin.
When you run Gdiff in a conflicted file, 3 files are opened - target, merged and working copy. You would switch to the file you want to save, and execute Gwrite! to save that file.
There is a whole Vimcast explaining how to resolve merge conflicts with this plugin(And other 5 vimcasts explaining more about Fugitive.vim).
I think :%diffget LO or :%diffget RE is what you need.
Note: you need to run it in the MERGED part of vim windows. You can move cursor around the windows using Ctrl+w;←/↑/→/↓
Make sure that all participating buffers are in diff mode (see :h start-vimdiff on how to start diff mode)
Do v for VISUAL MODE in the Base
Select the whole file (press Page Down all the way)
Write : then diffget <buffer number/name> (: ls will list all buffers, generally in vimdiff they are from right to left 1-3 or 4 if 3 way diff)
Afterwards just : wqa and you are done
Alternatively, after step 0., one could do :%diffget <buffer number> to get all changes from the specified buffer as :diffget also accepts ranges. (See :% and :diffget.)
The reverse would also work: :%diffput <buffer> will send all changes to buffer number, making the two buffers have the same content.

How is the undo tree used in Vim?

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?
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.
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.
This page explains everything you need to know:
http://vimdoc.sourceforge.net/htmldoc/usr_32.html
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
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
A lot of this is summed up here:
http://vim.wikia.com/wiki/Using_undo_branches
Besides using gundo.vim I like to mention g+ and g-
The package undotree is written in pure vimscript so no requirement.
And add this to your vimrc before it is too late:
set nobackup
set noswapfile
set nowritebackup
set undolevels=10000 " use many levels of undo
set history=10000 " After nocompatible
if has('persistent_undo')
set undodir=$HOME/.vim/undo
set undofile
endif

Resources