What happens when you type git diff? As with all interesting questions, the answer is “it depends…”
Here’s one thing you want git to do:
Vimdiff!
Step 1: add this to your .gitconfig
[diff]
external = git_diff_wrapper
[pager]
diff =
Step 2: create a file named git_diff_wrapper, put it somewhere in your $PATH
#!/bin/sh
vimdiff "$2" "$5"
I still have access to the default git diff behavior with the --no-ext-diff flag. Here’s a function I put in my bash configuration files:
function git_diff() {
git diff --no-ext-diff -w "$@" | vim -R –
}
- --no-ext-diff : to prevent using vimdiff
- -w : to ignore whitespace
- -R : to start vim in read-only mode
- – : to make vim act as a pager
When it comes to vimdiff, you can get started with this tutorial.
Wonderful, thanks! My team currently uses a “legacy” CVS (and we use “cvsvimdiff” – http://vim.sourceforge.net/scripts/script.php?script_id=1209 ) – but this will find from you will be a significant part of my plan to move to git.
Thanks!
Matt
[…] Git Diff with Vimdiff What happens when you type git diff? As with all interesting questions, the answer is “it […] […]
Thanks for -R in vim :). I’ve been using almost the same function in my bash here, but without -R you have to always remember to type :q! instead of :q. Now it’s gone, thank you one more time :).
[…] 24, 2009 by Jonathan Palardy I’ve talked casually about using Vim as a pager before. However, I’m still surprised to see how many people use Vim regularly and don’t know […]
Filanly! This is just what I was looking for.
Thanks for this entry, I found it useful.
Not being ready to go full speed into using vimdiff (i’m just new to it), I put the following in ‘gitvimdiff’. The result is that I can use vimdiff to look at git-diff by running ‘gitvimdiff ‘, but a normal invocation of ‘git-diff’ behaves as I’m used to.h
#!/bin/sh
if [ -n “${GIT_EXTERNAL_DIFF}” ]; then
[ “${GIT_EXTERNAL_DIFF}” = “${0}” ] ||
{ echo “GIT_EXTERNAL_DIFF set to unexpected value” 1>&2; exit 1; }
exec vimdiff “$2” “$5″
else
GIT_EXTERNAL_DIFF=”${0}” exec git –no-pager diff “$@”
fi
Thanks!
I will add that this script works if .gitconfig is NOT modified like above.
The above script is a small masterpiece, it does not mess with standard config so all tools expecting usual “git diff” still work fine.
Have been trying to do something like this for ages. Thanks a lot!
rockin thanks, this works great
I can’t seem to get this to work for the life of me! I just get a warning from vim that the output is not to a terminal. The following is my conifg:
[user]
name = Arthur Axel ‘fREW’ Schmidt
email = ellided@gmail.com
[color]
status = auto
branch = auto
ui = auto
[alias]
ci = commit
co = checkout
[diff]
external = git_diff_wrapper
[pager]
external =
Any ideas what I could be doing wrong?
I just compared with my config.
for the pager section, here’s what I have:
[pager]
diff =
it seems to be “diff” not “external”
let me know how that goes.
Just like you, I copied the git_diff snippet from this page and got the same error. The problem is that the dash at the end of the vim command is not the ASCII minus sign, which is used to tell vim that the input must be taken from the standard input. Instead, it’s a long dash symbol, which vim interprets as a file name to create and edit.
tl;dr version: replace the dash at the end of the pipe with a minus sign, like this: git diff –no-ext-diff -w “$@” | vim -R –
Thanks for the help. Works like a charm!
I have a question though: when one has more than 2 files in diff, vimdiff is launched twice. And this gets annoying if you have, say 100 files in diff. Any idea what to do then?
Yeah, this is a common problem. And it’s not Vim specific either.
I usually check how many files are affected with “git status”. Also, vimdiff git diff is _not_ my default choice: I use the “git_diff” alias mentioned at the end of the post.
If you still make that mistake … you can try to kill the git diff process.
Hi! Thanks for the reply. Unfortunately, I am too much in habit of using git diff. Script from Scott works fine then…
Unless you already use the Q key for anything, I suggest you add this line to your .vimrc file:
map Q :qa
This will allow you to quit vim anytime by simply pressing Q (of course, if you have unsaved changes you will be prompted first). If you have 10s of files in your ‘git diff’, you can just hold down the Q key to get out fairly quickly.
I really like this idea. I would have never come up with this on my own so I appreciate the work you put into it. I do, however, have some problems with the implementation. I would strongly suggest you not hork the standard behavior of git diff. I think you should create your git_diff_wrapper script. Don’t worry about putting a git_diff function in bash. Add the following to your ~/.gitconfig:
[alias]
vimdiff = “!GIT_PAGER=” GIT_EXTERNAL_DIFF=git_diff_wrapper git diff”
That’s it. Now you have:
git diff # normal behavior
git vimdiff # enhanced behavior
I also tried it but failed with the same error as Pete. The problem is in the extra quote, so I removed the quote in front of “!” , now I don’t get errors but don’t get any valueable results either. git vimdiff simply does not yeild anything.
Andrey – it didn’t work for me either, until I did one of the two following things:
1: Set the environment variable GIT_PAGER=””
2: Add an extra quote into the vimdiff alias in .gitconfig above:
vimdiff = “!GIT_PAGER=” GIT_EXTERNAL_DIFF=”git_diff_wrapper git diff”
I tried your method but
Expansion of alias ‘vimdiff’ failed; ‘“!GIT_PAGER=”’ is not a git command
is there anything wrong?
Much easier to use is vimdiff for git-difftool.
git config –global alias.vimdiff “difftool -y -t vimdiff”
Now just type
git vimdiff
Just note that this works per file instead of diff on the whole working directory.
re: git config –global alias.vimdiff “difftool -y -t vimdiff”
That is very handy! Is there anyway I can tell it to open in readonly mode?
Add a -R at the end, as such:
git config –global alias.vimdiff “difftool -y -t vimdiff -R”
Thanks. This is much nicer than using a wrapper script, or having vimdiff used by default for ‘git diff’.
[…] Git Diff with Vimdiff (tags: totag) […]
Very nice article.Thanks to the writer for sharing these stuffs that I believe will be helpful for me next time.
Jonathan,
Thank you. This article was very useful. There is one thing I’m wondering about. Because my main need for vimdiff in viewing git diffs is actually for reviewing code written by others, I’m wondering if there’s a way to do something similar with “git log -p”.
In general when I’m doing a “git diff” I’m just looking at code I’ve written over the last hour or so, but when it’s someone else’s code, that’s when viewing a regular diff patch is a little confusing.
Thank you.
John
Haha. Duh.
$ git diff HEAD~1
or more generally
$ git diff ..
Cheers.
I think your article is very useful for me. Thanks
I think this was only a problem with older versions of Git. Now I can do
git config –global diff.tool vimdiff
once, and then use `git difftool` whenever I want to carefully view the diff.
You’re right, that works out nicely.
[…] 下記のURLの設定方法をそのまま利用させてもらった。 https://technotales.wordpress.com/2009/05/17/git-diff-with-vimdiff/ […]
Dont forget to change the permissions on your git_diff_wrapper!
chmod +x git_diff_wrapper
[…] Git Diff with Vimdiff « Jonathan’s Techno-tales […]
[…] https://technotales.wordpress.com/2009/05/17/git-diff-with-vimdiff/ […]
[…] Git Diff with Vimdiff « Jonathan’s Techno-tales […]
Hi. First, thanks for the script; it’s been invaluable. Second, I’ve been able to improve it slightly.
The problem was if I did git diff (SHA1^1..SHA1) then I’d get a bunch of /tmp/* in the statusline which didn’t really help me.
So changing the vimdiff line to ..
vimdiff -c “set statusline=$1” “$2” “$5”
totally fixed it.
Thanks again.
Hello, i read your blog from time to time and i own a similar one and i was just curious if you get a lot of spam responses?
If so how do you prevent it, any plugin or anything you can
recommend? I get so much lately it’s driving me crazy so any help is very much appreciated.
I simply couldn’t leave your web site prior to suggesting that I extremely enjoyed the usual information a person provide on your guests? Is going to be again often in order to inspect new posts
Great article! That is the type of info that are
meant to be shared around the internet. Shame on Google for now not positioning this
post higher! Come on over and seek advice from my site .
Thank you =)
[…] have setup git diff to wrap into vimdiff (using this guide) and it’s working as expected unless there are many files with changes. When there are […]
Currently it looks like Expression Engine is the top blogging platform
out there right now. (from what I’ve read) Is that what you’re using on your blog?
Hi, i think that i saw you visited my website thus i
came to “return the favor”.I’m trying
to find things to enhance my website!I suppose its ok to use a few of your ideas!!
[…] have setup git diff to wrap into vimdiff (using this guide) and it’s working as expected unless there are many files with changes. When there are […]
hello there and thank you for your info – I’ve certainly picked up
something new from right here. I did however expertise several technical
issues using this site, since I experienced to reload the website lots
of times previous to I could get it to load correctly.
I had been wondering if your hosting is OK? Not that I’m complaining, but slow loading instances times will very
frequently affect your placement in google and could damage your high-quality score if advertising and marketing with Adwords.
Well I’m adding this RSS to my e-mail and can look out for a lot more of your respective
exciting content. Ensure that you update this again
very soon. youtube profile, real youtube views, have more Supporters upon youtube
Have more Site visitors simply by buy real youtube
views for ones Report useful means.
I’m really enjoying the design and layout of your website.
It’s a very easy on the eyes which makes it much more enjoyable for me to come here and visit
more often. Did you hire out a developer to create your theme?
Great work!
Hey! Someone in my Facebook group shared this website with us so I came
to check it out. I’m definitely enjoying the information.
I’m bookmarking and will be tweeting this to my followers!
Exceptional blog and superb design.
[…] of how to configure a diff tool on git versions prior to 1.6.3 (1.6.3 added difftool to git) this is a great concise […]
[…] of how to configure a diff tool on git versions prior to 1.6.3 (1.6.3 added difftool to git) this is a great concise […]
[…] of how to configure a diff tool on git versions prior to 1.6.3 (1.6.3 added difftool to git) this is a great concise […]
[…] have setup git diff to wrap into vimdiff, using “Git Diff with Vimdiff” as a guide, and it’s working as expected unless there are many files with changes. […]
Thank you, I’ve been enjoying this alot. But yesterday I found gvimdiff is better than vimdiff(We can slide the center bar left or right in gvimdiff). So I just tried changing my git_diff_wrapper #!/bin/sh and gvimdiff “$2” “$5” but it didn’t work. For some reason, it doesn’t open together, just in separate time. Will you please try it with gvim and let me know how to do it?
[…] have setup git diff to wrap into vimdiff, using “Git Diff with Vimdiff” as a guide, and it’s working as expected unless there are many files with changes. […]
[…] (下述步驟 參考此文: Git Diff with Vimdiff) […]
[…] diff设置为包装到vimdiff中,使用“Git Diff with Vimdiff”作为指导,并按预期工作,除非有许多文件有更改。 […]
[…] в vimdiff, используя " Git Diff with Vimdiff" в качестве […]
[…] ” Vimdiff와 함께 Git Diffgit diff “를 사용하여 vimdiff로 래핑하도록 설정 했으며 , 변경 사항이 […]
[…] También probé las instrucciones de este tutorial: https://technotales.wordpress.com/2009/05/17/git-diff-with-vimdiff/ […]
[…] setup git diff to wrap into vimdiff, using “Git Diff with Vimdiff” as a guide, and it’s working as expected unless there are many files with […]
[…] setup git diff to wrap into vimdiff, using “Git Diff with Vimdiff” as a guide, and it’s working as expected unless there are many files with […]