为什么"git diff"不调用外部差异工具?



在我的存储库中,如果我键入

$ git diff some-file

$ git difftool some-file

我得到了终端差异显示。我认为这不应该发生,因为我已经设置了一个外部diff工具,如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

diff.external行中引用的git-diff文件看起来像这个

#!/bin/bash
meld $2 $5

为什么git diff不调用meld?

如果我设置git config -l有以下行,我会得到相同的行为:

diff.tool = meld

diff.external = usr/bin/meld

注意:我机器上的其他存储库没有这个问题。

相关但不等价的SO问题:

  1. git diffgit difftool之间有什么区别
  2. 无法使git diff使用diff.external作为外部diff工具

我得到了终端差异显示。我这不应该发生,因为我已经设置了一个外部差异工具

是的,它应该是:diff.external是";在终端差异显示中";。

(来自git config手册页(

diff.external

如果设置了此配置变量,则不会使用内部diff机制执行diff生成,而是使用给定的命令
可以使用GIT_EXTERNAL_DIFF环境变量重写
该命令是用参数调用的;git-Diffs";单位为git(1(。注意:如果你只想在文件的一个子集上使用外部diff程序,你可能需要使用gitattributes(5(。

你链接的问题解释了为什么CCD_;外部差异";。

用另一个工具直观地查看差异是用完成的

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

CCD_ 10可以在Windows上配置为difftool:;Git Diff和Meld on Windows";。


如果你想为gitdiff配置meld,你可以(在Ubuntu上(使用diff.external,但需要一个包装脚本:

使用以下内容创建一个名为git-diff.sh的文件:

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

将其保存到/usr/local/bin等位置,赋予其可执行权限:

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

最后一步是打开$HOME/.gitconfig文件并添加以下几行:

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

下次在Git项目中键入git diff并进行更改时,Meld将启动,向您显示一个分窗格差异查看器
请注意,在打开下一个diff查看器之前,您需要关闭meld的打开实例。


将在评论中注明:

这个包装器脚本在我的Ubuntu系统上运行得很好。

我确实发现了一个gottcha:我按如下方式分离了meld命令:

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

始终无法打开$2文件(临时文件(
会发生什么?好吧,一旦包装器退出,git就会删除$2
我的建议是,如果您希望分离复制tmp文件,请调用meld并自己删除tmp文件。

将使用meld --newtab提出gist-register.bash,如下所示:

#!/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"

git diff(至少从git版本1.7.12.4开始(似乎不会在处于"both modified"状态的文件上运行除内部、仅限控制台的diff之外的任何其他操作。不过,git mergetool可以处理这样的文件。

我通常只想检查即将签入的更改是否正确。所以我遵循了这里建议的程序(类似于VonC提到的程序(。然而,运行git difftool仍然没有打开meld。然后我创建了一个别名:

alias git-diff='git difftool $(git rev-parse HEAD)'

将其保存在.bashrc或.zshrc或shell的相应配置中。这本质上是将分支的状态与分支上的上一次提交进行比较。

执行git-diff以查看每个文件的更改,或执行git-diff --dir以查看目录视图中的所有更改。

最新更新