Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't `git diff` invoke external diff tool?

Tags:

git

diff

meld

In my repository, if I type

$ git diff some-file 

or

$ git difftool some-file 

I get the in-terminal diff display. I think this should not happen, because I have set up an external diff tool, as shown by the output of git config -l:

$ git config -l user.name=blah blah user.email=blah blah http.sslverify=true diff.external=/home/daniel/bin/git-diff  <--This is the important line push.default=simple core.filemode=false core.editor=gedit alias.tree=log --all --graph --decorate=short --color --format=format:'%C(bold blue)%h%C(reset) %C(auto)%d%C(reset)          %C(black)[%cr]%C(reset)  %x09%C(black)%an: %s %C(reset)' core.repositoryformatversion=0 core.filemode=false core.bare=false core.logallrefupdates=true core.ignorecase=true remote.origin.url=https://daniel@skynet/git/pyle.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* branch.master.remote=origin branch.master.merge=refs/heads/master branch.daniel.remote=origin branch.daniel.merge=refs/heads/daniel 

The git-diff file referenced in the diff.external line looks like this

#!/bin/bash  meld $2 $5 

Why doesn't git diff invoke meld?

I get the same behaviour if I set things up so that git config -l has the following line:

diff.tool = meld 

or

diff.external = usr/bin/meld 

Note: Other repositories on my machine don't have this problem.

Related, but not equivalent, SO questions:

  1. What is the difference between git diff and git difftool?
  2. Cannot make git diff use diff.external for external diff tool
like image 783
DanielSank Avatar asked Jul 26 '14 00:07

DanielSank


People also ask

How do I open git diff tool?

Go to your repository in Git Bash. Type git config diff. tool winmerge . Verify it worked by typing git difftool .

What diff tool does git use?

git difftool is a Git command that allows you to compare and edit files between revisions using common diff tools. git difftool is a frontend to git diff and accepts the same options and arguments.

How does git diff work internally?

Diffing is a function that takes two input data sets and outputs the changes between them. git diff is a multi-use Git command that when executed runs a diff function on Git data sources. These data sources can be commits, branches, files and more.

Can you git diff a specific file?

The git diff command returns a list of all the changes in all the files between our last commit and our current repository. If you want to retrieve the changes made to a specific file in a repository, you can specify that file as a third parameter.


1 Answers

I get the in-terminal diff display. I this should not happen, because I have set up an external diff tool

Yes, it should: diff.external is for "in-terminal diff display".

(from git config man page)

diff.external 

If this config variable is set, diff generation is not performed using the internal diff machinery, but using the given command.
Can be overridden with the GIT_EXTERNAL_DIFF environment variable.
The command is called with parameters as described under "git Diffs" in git(1). Note: if you want to use an external diff program only on a subset of your files, you might want to use gitattributes(5) instead.

The question you link explains why meld wouldn't be able to play the role of an "external diff".

Viewing a diff visually with another tool is done with:

git difftool --dir-diff shaOfHisCheckIn^! git difftool --tool=meld --dir-diff shaOfHisCheckIn^! git difftool -t meld -d shaOfHisCheckIn^! 

meld can be configured on Windows as a difftool: see "Git Diff and Meld on Windows".


If you wanted to configure meld for git diff, you could (on Ubuntu) use the diff.external, but with a wrapper script:

create a file called git-diff.sh, using the following content:

#!/bin/bash meld "$2" "$5" > /dev/null 2>&1 

Save this to a location such as /usr/local/bin, giving it executable rights:

$ sudo mv git-diff.sh /usr/local/bin/ $ sudo chmod +x /usr/local/bin/git-diff.sh 

The final step is to open your $HOME/.gitconfig file and add the following few lines:

[diff]         external = /usr/local/bin/git-diff.sh 

The next time you type git diff in a Git project with changes, Meld will be launched showing you a split-pane diff viewer.
Note that you are required to close the open instance of meld before the next diff viewer is opened.


will notes in the comments:

That wrapper script works great on my Ubuntu system.

I did discover a gottcha: I detached the meld command as so:

meld "$2" "$5" > /dev/null 2>&1 & 

Kept failing to open the $2 file (tempory file).
What happens? Well, git removes $2 once the wrapper exits.
My suggestion, if you wish to detach copy the tmp file, invoke meld and remove tmp file yourself.

will proposes the gist gist-meld.bash, using meld --newtab, as seen here:

#!/bin/bash #  * expects meld to be on your default PATH # function detach_meld() {     local f1="/tmp/mld1-$(basename "$1")"     local f2="/tmp/mld2-$(basename "$2")"      ##  echo "f1 = ${f1}" ##  echo "f2 = ${f2}"      cp "$1" "${f1}"     cp "$2" "${f2}" #     (meld  --newtab  "${f1}" "${f2}" ; rm  "${f1}"  "${f2}" ) > /dev/null 2>&1  &     }  detach_meld  "$2"  "$5" 
like image 130
VonC Avatar answered Sep 21 '22 10:09

VonC