# Fix Vim Undo Tree File Not Removed When Buffer Closes
You notice your project directories filling up with .un~ files -- Vim's persistent undo tree files. These files are supposed to enable undo history across Vim sessions, but they are not being cleaned up when you delete the original file, and they accumulate over time.
Alternatively, you may find that the undo tree file is not being created at all, meaning your undo history is lost every time you close a buffer.
Understanding Persistent Undo
Vim's undo tree normally exists only in memory. When you close a file, the undo history is lost. Persistent undo saves the undo tree to disk so you can undo changes even after closing and reopening a file.
Enable persistent undo in your .vimrc:
set undofile
set undodir=~/.vim/undo//The double trailing slash tells Vim to encode the full file path in the undo filename, preventing collisions.
The Cleanup Problem
When you delete the original file, the undo tree file remains:
rm myfile.txt
# .un~ file still exists:
# ~/.vim/undo/%home%user%project%myfile.txtThis is by design -- Vim does not track file deletions to clean up undo files. Over time, these orphaned undo files accumulate.
Finding Orphaned Undo Files
Find undo files whose original files no longer exist:
find ~/.vim/undo -type f | while read undo_file; do
# Decode the path (Vim replaces / with %)
original=$(echo "$undo_file" | sed 's|%|%25|g; s|%\(.\)|/\1|g')
# Check if original exists
if [ ! -f "$original" ]; then
echo "Orphaned: $undo_file (original: $original)"
fi
doneCleaning Up Orphaned Undo Files
Remove all orphaned undo files:
```bash #!/bin/bash # clean-undo.sh undo_dir=~/.vim/undo count=0
for undo_file in "$undo_dir"/*; do [ -f "$undo_file" ] || continue
# Decode the Vim-encoded path original=$(echo "$undo_file" | sed 's|%|%25|g; s|%\(.\)|/\1|g')
if [ ! -f "$original" ]; then rm "$undo_file" count=$((count + 1)) fi done
echo "Removed $count orphaned undo files" ```
Run this periodically via cron:
0 3 * * 0 /usr/local/bin/clean-undo.shAlternative: Use File-Specific Undo Files
If you prefer undo files to live next to the original files (easier to clean up), use:
set undofile
" No undodir set = undo files created next to originalThis creates .filename.un~ files in the same directory. When you delete the original file, you can clean up with:
find . -name "*.un~" -deleteOr add it to your .gitignore:
*.un~Undo File Not Being Created
If set undofile is in your .vimrc but no undo files appear, check:
- 1.Directory permissions:
ls -la ~/.vim/undo/
mkdir -p ~/.vim/undo
chmod 700 ~/.vim/undo- 1.Filesystem is read-only or full:
df -h ~/.vim/undo- 1.Overridden by filetype plugin:
:verbose set undofile?This shows where undofile was last set and whether another script is overriding it.
Undo Tree Navigation
With persistent undo enabled, you can navigate the full undo tree:
g- " Older state (navigates undo tree, not just linear undo)
g+ " Newer state
:earlier 5m " Go to state 5 minutes ago
:earlier 1d " Go to state 1 day ago
:later 10s " Go forward 10 seconds
:undolist " Show all undo branchesThe :undolist command shows:
number changes time
16 52 04/08/2026 10:30:15
17 54 04/08/2026 10:31:22
18 58 04/08/2026 11:00:05Each number represents a branch point in the undo tree. Use u 16 to jump to state 16, even if it is not the most recent state.
Memory and Performance
Persistent undo files can grow large for files with extensive editing history. Check file sizes:
du -sh ~/.vim/undo/
du -sh ~/.vim/undo/* | sort -rh | head -10If individual undo files exceed 1MB, consider increasing undolevels only for specific filetypes:
autocmd FileType python setlocal undolevels=1000
autocmd FileType markdown setlocal undolevels=500The default is 1000, which is sufficient for most use cases.