Skip to content

Instantly share code, notes, and snippets.

@aroben
Last active November 10, 2024 13:23
Show Gist options
  • Save aroben/d54d002269d9c39f0d5c89d910f7307e to your computer and use it in GitHub Desktop.
Save aroben/d54d002269d9c39f0d5c89d910f7307e to your computer and use it in GitHub Desktop.
Vim script to show git commit diff in vertical split while writing commit messages
" Put this in your .vimrc and whenever you `git commit` you'll see the diff of your commit next to your commit message.
" For the most accurate diffs, use `git config --global commit.verbose true`
" BufRead seems more appropriate here but for some reason the final `wincmd p` doesn't work if we do that.
autocmd VimEnter COMMIT_EDITMSG call OpenCommitMessageDiff()
function OpenCommitMessageDiff()
" Save the contents of the z register
let old_z = getreg("z")
let old_z_type = getregtype("z")
try
call cursor(1, 0)
let diff_start = search("^diff --git")
if diff_start == 0
" There's no diff in the commit message; generate our own.
let @z = system("git diff --cached -M -C")
else
" Yank diff from the bottom of the commit message into the z register
:.,$yank z
call cursor(1, 0)
endif
" Paste into a new buffer
vnew
normal! V"zP
finally
" Restore the z register
call setreg("z", old_z, old_z_type)
endtry
" Configure the buffer
set filetype=diff noswapfile nomodified readonly
silent file [Changes\ to\ be\ committed]
" Get back to the commit message
wincmd p
endfunction
@Konfekt
Copy link

Konfekt commented Nov 10, 2024

@dstar4138 This works great, though I found the diff dispensable if it is already included in the commit message as happens with commit.verbose > 0:

function! <SID>GitCommitSplitDiff() abort
  " do not show diff if already shown below commit message
  silent let verbose = systemlist('git config commit.verbose')
  if !v:shell_error && (verbose[0] ==# 'true' || str2nr(verbose[0]) > 0)
      return
  endif
  try
    rightbelow vert Git diff --cached
    setlocal filetype=diff noswapfile nomodified readonly
    silent file [COMMIT_DIFF]
  endtry
  " Get back to the commit message
  wincmd p
endfunction
augroup vimrcFugitiveSplitDiff
  au!
  autocmd VimEnter COMMIT_EDITMSG call <SID>GitCommitSplitDiff()
  autocmd QuitPre  COMMIT_EDITMSG silent! bwipeout! COMMIT_DIFF
augroup END
silent doautoall vimrcFugitiveSplitDiff VimEnter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment