How to work with files from the recent git commits

Personal Use-cases

I like to be able to edit only the files that involve in the last few commits with Vim.

Solution

How to do it

#!/bin/bash
## file: ~/bin/vim-git.sh
EXPECTED_ARGS=1
if [ $# -ne $EXPECTED_ARGS ]
then
  ## Open any non-binary files in the last N commits
  vim `file $(git diff --name-only HEAD~$1) | grep -i ASCII | cut -d: -f1`
else
  ## Open any non-binary files in the last commit otherwise
  vim `file $(git diff --name-only HEAD~1) | grep -i ASCII | cut -d: -f1`
fi

This make it easy to work with the the files from the last few commits.

My workflow:

nnoremap <Leader>gw :!git add . && git commit -m "WIP"<CR>
vim-git

Or if I know that I care only about the files in the last 3 commits then I just type

vim-git 3

And once inside Vim, I can use [ - b, or ] - b to navigate using the mappings from vim-repeat

And if i want to see the list of file, i just type :ls from Vim

Useful Unix aliases

As a bonus to make this even more awesome, I have the following aliases that use the result of Git command with Vim.

## Skip non-ascii files
alias gn1=' file $(git diff --name-only HEAD~1)  | grep -i ASCII | cut -d: -f1'
alias gn2=' file $(git diff --name-only HEAD~2)  | grep -i ASCII | cut -d: -f1'
alias gn3=' file $(git diff --name-only HEAD~3)  | grep -i ASCII | cut -d: -f1'
alias gn4=' file $(git diff --name-only HEAD~4)  | grep -i ASCII | cut -d: -f1'
alias gn5=' file $(git diff --name-only HEAD~5)  | grep -i ASCII | cut -d: -f1'
alias gn6=' file $(git diff --name-only HEAD~6)  | grep -i ASCII | cut -d: -f1'
alias gn7=' file $(git diff --name-only HEAD~7)  | grep -i ASCII | cut -d: -f1'
alias gn8=' file $(git diff --name-only HEAD~8)  | grep -i ASCII | cut -d: -f1'
alias gn9=' file $(git diff --name-only HEAD~9)  | grep -i ASCII | cut -d: -f1'
alias gn10='file $(git diff --name-only HEAD~10) | grep -i ASCII | cut -d: -f1'

## Skip non-ascii files
alias vd1=' vim `file $(git diff --name-only HEAD~1)  | grep -i ASCII | cut -d: -f1`'
alias vd2=' vim `file $(git diff --name-only HEAD~2)  | grep -i ASCII | cut -d: -f1`'
alias vd3=' vim `file $(git diff --name-only HEAD~3)  | grep -i ASCII | cut -d: -f1`'
alias vd4=' vim `file $(git diff --name-only HEAD~4)  | grep -i ASCII | cut -d: -f1`'
alias vd5=' vim `file $(git diff --name-only HEAD~5)  | grep -i ASCII | cut -d: -f1`'
alias vd6=' vim `file $(git diff --name-only HEAD~6)  | grep -i ASCII | cut -d: -f1`'
alias vd7=' vim `file $(git diff --name-only HEAD~7)  | grep -i ASCII | cut -d: -f1`'
alias vd8=' vim `file $(git diff --name-only HEAD~8)  | grep -i ASCII | cut -d: -f1`'
alias vd9=' vim `file $(git diff --name-only HEAD~9)  | grep -i ASCII | cut -d: -f1`'
alias vd10='vim `file $(git diff --name-only HEAD~10) | grep -i ASCII | cut -d: -f1`'

## Git rebase the last N commits
alias gr1=' git rebase -i HEAD~1'
alias gr2=' git rebase -i HEAD~2'
alias gr3=' git rebase -i HEAD~3'
alias gr4=' git rebase -i HEAD~4'
alias gr5=' git rebase -i HEAD~5'
alias gr6=' git rebase -i HEAD~6'
alias gr7=' git rebase -i HEAD~7'
alias gr8=' git rebase -i HEAD~8'
alias gr9=' git rebase -i HEAD~9'
alias gr10='git rebase -i HEAD~10'
comments powered by Disqus