9

Does anybody know how to setup vim (the text editor) in such a way to make it possible to trace back all the changes done to a file within a day? I need it for the cases when I have accidentially modified a subroutine and would like to return it to it's initial state, as it was at the start of the day.

I usually use svn to keep the most recent version of my source code in a global repository. But sometimes I need to return to the state the code was in in between of two svn commits.

Update:

To enable persistent undo create the undo directory, e.g. ~/.vim/undodir, and place the following settings into the .vimrc file:

set undodir=~/.vim/undodir
set undofile
set undolevels=1000
set undoreload=10000
1
  • 1
    Could you explain what these lines do: set undolevels=1000 set undoreload=10000
    – Finn
    Nov 23, 2018 at 6:28

2 Answers 2

16

With a large enough value of 'undolevel', Vim should be able to undo the whole day's changes. If you quit Vim in between, you also need to enable persistent undo by setting the 'undofile' option.

Vim captures not just a sequential list of commands for undo, but actually a tree of all changes. It also has several commands around undo (cp. :help undo-branches); to go back to the state at the beginning of the day,

:earlier 12h

is a good candidate.

There are also plugins like Gundo and undotree.vim, which visualize the undo tree and allow to navigate it.

If navigating the undo tree sounds too cumbersome (e.g. because you make a lot of changes throughout the day), you can also add a lightweight version control system (in addition to Subversion), like my writebackup plugin, and explicitly create a backup at certain times.

0
3

For several years I've been using a script wrapper around vi that saves the files I'm editing. It does this at most once per day so that I don't end up with too many backup files.

This is a simpler version of the script I use; perhaps it's useful for you too. Instead of running vi, you would run vib (vi with backup):

vib() {
    local DATE=$(date +'%Y-%m-%d') FILE BACK
    for FILE in "$@"
    do
        BACK="$FILE.$DATE"
        test ! -f "$BACK" && cp -p "$FILE" "$BACK"
    done
    vi "$@"
    for FILE in "$@"
    do
        BACK="$FILE.$DATE"
        cmp -s "$FILE" "$BACK" && rm -f "$BACK"
    done
}

This can either be put into the .bash_profile or, with the function declaration removed, put into an executable file such as /usr/local/bin/vib

2
  • Does it make a difference if you write function vib() {...} or vib() {...}? I also changed the rm command to \rm because of trash-cli things. I also had to add export -f vib below the script.
    – Cadoiz
    Feb 15, 2023 at 7:25
  • 1
    @Cadoiz the function keyword is non-standard so you should aim to avoid using it. If you put this code in a script file in your $PATH you can have a new command that doesn't need to worry about aliases for rm, etc Feb 15, 2023 at 7:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .