# Vim Undo History Not Persisting

You make changes, undo some, close Vim, and when you reopen the file, the undo history is gone. Vim's undo history by default only exists for the current session. Here's how to make it persist.

Enable Persistent Undo

Vim 7.3+ supports persistent undo:

vim
set undofile

This creates undo files (.file.un~) that store undo history.

Configure Undo Directory

Like backup files, undo files can clutter directories. Move them:

vim
set undodir=~/.vim/undo//
set undofile

Create the directory:

bash
mkdir -p ~/.vim/undo
chmod 700 ~/.vim/undo  " Secure: undo files may contain sensitive data

The // suffix uses the full path to prevent collisions.

Neovim Configuration

```lua vim.opt.undofile = true vim.opt.undodir = vim.fn.expand('~/.local/share/nvim/undo//')

-- Create directory if needed vim.fn.mkdir(vim.fn.expand('~/.local/share/nvim/undo'), 'p') ```

Check Undo Settings

vim
:set undofile?
:set undodir?

If undofile is empty or noundofile, persistent undo is disabled.

Undo History Not Working

If undo doesn't work at all:

Check Undo Levels

vim
:set undolevels?

Default is 1000. If set to 0 or very low, undo history is limited:

vim
set undolevels=1000

Undo File Permissions

Check if undo files are readable:

bash
ls -la ~/.vim/undo/

You should own these files. Fix permissions:

bash
chmod 700 ~/.vim/undo
chmod 600 ~/.vim/undo/*

Undodir Not Writable

Vim silently fails if it can't write undo files:

```bash # Check directory exists ls -d ~/.vim/undo

# Check you can write touch ~/.vim/undo/test && rm ~/.vim/undo/test ```

Clear Undo History

To start fresh:

vim
:clearundo
" Or older Vim versions
:let &undolevels = -1

Or delete undo files:

bash
rm ~/.vim/undo/*

Undo Branches

Vim stores undo as a tree, not linear history. Navigate branches:

```vim g- " Go to previous state in tree g+ " Go to next state in tree

:earlier 5m " Go to state 5 minutes ago :later 5m " Go forward 5 minutes

:undo 5 " Undo to change number 5 ```

View undo tree:

vim
:undolist

Undo Persistence Plugin

For visual undo tree:

vim
Plug 'mbbill/undotree'
nnoremap <F5> :UndotreeToggle<CR>

This shows a graphical undo tree with branches.

Per-File Undo Settings

Override for specific files:

vim
autocmd BufWritePre /tmp/* setlocal noundofile
autocmd BufWritePre *.log setlocal noundofile

Maximum Undo Size

Limit undo file size:

vim
" Limit to 100KB per file
let g:undofile_max_size = 100000

Not built-in, but you can implement:

vim
function! LimitUndoSize()
    let undo_file = &undodir . '/' . substitute(expand('%:p'), '/', '%', 'g') . '.un~'
    if filereadable(undo_file) && getfsize(undo_file) > 100000
        setlocal noundofile
    endif
endfunction
autocmd BufReadPost * call LimitUndoSize()

Undo Not Working After Recovery

If you recover from swap file, undo might not work:

vim
:recover filename
" Then enable undo
:set undofile

The recovery process doesn't preserve undo history.

Undo with Encryption

Vim's encryption doesn't encrypt undo files. This is a security concern:

vim
" Don't store undo for encrypted files
if &encrypt
    set noundofile
endif

Add to your config:

vim
autocmd BufReadPost * if &cryptmethod != '' | set noundofile | endif

Remote Files

Undo doesn't work well with remote files (netrw, scp):

vim
" Skip undo for remote files
autocmd BufReadCmd scp://*,http://*,ftp://* setlocal noundofile

Merge Undo Files

When merging changes, undo files don't merge. You get one history per file version.

Debug Undo Issues

```vim " Show undo file location :echo &undodir . '/' . substitute(expand('%:p'), '/', '%', 'g') . '.un~'

" Check if undofile exists :echo filereadable(expand(&undodir) . '/' . substitute(expand('%:p'), '/', '%', 'g') . '.un~') ```

Neovim Shada

Neovim uses shada (shared data) instead of viminfo:

lua
vim.opt.shada = '!,'100,<50,s10,h'
  • ! - Save global variables
  • '100 - Marks for 100 files
  • <50 - 50 lines per register
  • s10 - Skip items > 10KB
  • h - Don't save hlsearch

Complete Undo Configuration

```vim " Enable persistent undo set undofile set undolevels=1000

" Central undo directory set undodir=~/.vim/undo//

" Create directory if !isdirectory(&undodir) call mkdir(&undodir, 'p', 0700) endif

" Skip undo for certain files set noundofile " Default autocmd BufReadPost ~/.vimrc,*.vim,*.py,*.js setlocal undofile autocmd BufReadPost /tmp/*,*.log,*.tmp setlocal noundofile ```

Troubleshooting Checklist

  1. 1.Enable undofile: set undofile
  2. 2.Check undodir exists: ls -d ~/.vim/undo
  3. 3.Verify permissions: chmod 700 ~/.vim/undo
  4. 4.Check undolevels: :set undolevels?
  5. 5.Verify undofile created: ls ~/.vim/undo/
  6. 6.Check for encrypted files (undo not encrypted)
  7. 7.Verify Vim version (7.3+ for persistent undo)

Quick Reference

```vim " Enable persistent undo set undofile set undodir=~/.vim/undo// set undolevels=1000

" Check settings :set undofile? undodir?

" Clear history :clearundo

" Navigate undo tree g- " Previous state g+ " Next state :earlier 5m :later 5m

" Visual undo tree :UndotreeToggle ```

Persistent undo is one of Vim's most powerful features. Enable it, configure a clean directory, and you'll never lose edit history again.