When I type git diff
, I want to view the output with my visual diff tool of choice (SourceGear \"diffmerge\" on Windows). How do I configure git to do this?
Install meld
# apt-get install meld
Then choose that as difftool
$ git config --global diff.tool meld
If tou want to run it on console type:
$ git difftool
If you want to use graphic mode type:
$ git mergetool
And the output would be:
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse
diffmerge ecmerge p4merge araxis bc3 codecompare emerge vimdiff
Merging:
www/css/style.css
www/js/controllers.js
Normal merge conflict for 'www/css/style.css':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (meld):
So just press enter to use meld(default), this would open graphic mode, make the magic save and press that that resolve the merge. That's all
I tried the fancy stuff here (with tkdiff) and nothing worked for me. So I wrote the following script, tkgitdiff. It does what I need it to do.
$ cat tkgitdiff
#!/bin/sh
#
# tkdiff for git.
# Gives you the diff between HEAD and the current state of your file.
#
newfile=$1
git diff HEAD -- $newfile > /tmp/patch.dat
cp $newfile /tmp
savedPWD=$PWD
cd /tmp
patch -R $newfile < patch.dat
cd $savedPWD
tkdiff /tmp/$newfile $newfile
To complete my previous "diff.external" config answer above:
As mentioned by Jakub, Git1.6.3 introduced git difftool, originally proposed in September 2008:
USAGE='[--tool=tool] [--commit=ref] [--start=ref --end=ref] [--no-prompt] [file to merge]'
(See --extcmd
in the last part of this answer)
$LOCAL
contains the contents of the file from the starting revision and $REMOTE
contains the contents of the file in the ending revision.
$BASE
contains the contents of the file in the wor
It's basically
git-mergetool
modified to operate on the git index/worktree.The usual use case for this script is when you have either staged or unstaged changes and you'd like to see the changes in a side-by-side diff viewer (e.g.
xxdiff
,tkdiff
, etc).
git difftool [<filename>*]
Another use case is when you'd like to see the same information but are comparing arbitrary commits (this is the part where the revarg parsing could be better)
git difftool --start=HEAD^ --end=HEAD [-- <filename>*]
The last use case is when you'd like to compare your current worktree to something other than HEAD (e.g. a tag)
git difftool --commit=v1.0.0 [-- <filename>*]
Note: since Git 2.5, git config diff.tool winmerge
is enough!
See "git mergetool winmerge"
And since Git 1.7.11, you have the option --dir-diff
, in order to to spawn external diff tools that can compare two directory hierarchies at a time after populating two temporary directories, instead of running an instance of the external tool once per a file pair.
Before Git 2.5:
Practical case for configuring difftool
with your custom diff tool:
C:\myGitRepo>git config --global diff.tool winmerge
C:\myGitRepo>git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --global difftool.prompt false
With winmerge.sh stored in a directory part of your PATH:
#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"C:/Program Files/WinMerge/WinMergeU.exe" -u -e "$1" "$2" -dl "Local" -dr "Remote"
If you have another tool (kdiff3, P4Diff, ...), create another shell script, and the appropriate difftool.myDiffTool.cmd
config directive.
Then you can easily switch tools with the diff.tool
config.
You have also this blog entry by Dave to add other details.
(Or this question for the winmergeu
options)
The interest with this setting is the winmerge.sh
script: you can customize it to take into account special cases.
See for instance David Marble's answer below for an example which deals with:
As Kem Mason mentions in his answer, you can also avoid any wrapper by using the --extcmd
option:
--extcmd=<command>
Specify a custom command for viewing diffs.
git-difftool
ignores the configured defaults and runs$command $LOCAL $REMOTE
when this option is specified.
For instance, this is how gitk is able to run/use any diff tool.
If you happen to already have a diff tool associated with filetypes (say, because you installed TortoiseSVN which comes with a diff viewer) you could just pipe the regular git diff
output to a "temp" file, then just open that file directly without needing to know anything about the viewer:
git diff > "~/temp.diff" && start "~/temp.diff"
Setting it as a global alias works even better: git what
[alias]
what = "!f() { git diff > "~/temp.diff" && start "~/temp.diff"; }; f"
If you're not one for the command line then if you install tortoise git you can right click on a file to get a tortoisegit submenu with the "Diff later" option.
When you select this on the first file you can then right click on the second file, go to the tortoisegit submenu and select "Diff with ==yourfilehere==" This will give the tortoisegitmerge gui for the result.
Building on VonC's answer to deal with file removals and additions, use the following commands and scripts:
> git config --global diff.tool winmerge
> git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\" \"$BASE\""
> git config --global difftool.prompt false
Which is the same as putting this in your global .gitconfig
:
[diff]
tool = winmerge
[difftool "winmerge"]
cmd = winmerge.bat "$LOCAL" "$REMOTE" "$BASE"
[difftool]
prompt = false
Then put the following in winmerge.sh
which must be on your path:
#!/bin/sh
NULL="/dev/null"
if [ "$2" = "$NULL" ] ; then
echo "removed: $3"
elif [ "$1" = "$NULL" ] ; then
echo "added: $3"
else
echo "changed: $3"
"C:/Program Files (x86)/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$1" "$2"
fi