32

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

$ git diff some-file

或者

$ git difftool some-file

我得到了终端差异显示。我认为这不应该发生,因为我已经设置了一个外部差异工具,如以下输出所示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调用融合?

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

diff.tool = meld

或者

diff.external = usr/bin/meld

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

相关但不等价的 SO 问题:

  1. git diff和 和有什么不一样git difftool
  2. 无法使 git diff 使用 diff.external 作为外部 diff 工具
4

3 回答 3

22

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

是的,它应该: diff.external用于“终端差异显示”。

(来自git config手册页

diff.external

如果设置了此配置变量,则不会使用内部差异机制执行差异生成,而是使用给定的命令
可以用GIT_EXTERNAL_DIFF环境变量覆盖。
该命令使用 git(1) 中“git Diffs”中描述的参数调用。注意:如果您只想在文件的子集上使用外部差异程序,您可能需要使用gitattributes(5)代替。

您链接的问题解释了为什么meld不能扮演“外部差异”的角色。

使用另一个工具直观地查看差异是通过以下方式完成的:

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

meld可以在 Windows 上配置为 difftool:请参阅“ Windows 上的 Git Diff 和 Meld ”。


如果您想为 git diff 配置 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 diff一个有变化的 Git 项目时,Meld 将启动,向你展示一个拆分窗格的差异查看器。
请注意,在打开下一个差异查看器之前,您需要关闭打开的 meld 实例。


将在评论中注明:

该包装脚本在我的 Ubuntu 系统上运行良好。

我确实发现了一个问题:我这样分离了meld命令:

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

一直无法打开$2文件(临时文件)。
怎么了?好吧,一旦包装器退出就git删除。 我的建议是,如果您想分离文件,请自己调用和删除文件。$2
tmpmeldtmp

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

#!/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"
于 2014-07-26T03:45:21.273 回答
14

似乎git diff(至少,从gitversion1.7.12.4开始)不会在处于“都已修改”状态的文件上运行除内部的、仅限控制台的差异之外的任何东西。git mergetool不过,适用于此类文件。

于 2014-11-07T17:29:11.590 回答
2

我通常只想检查我即将签入的更改是否正确。所以我按照这里建议的程序(类似于 VonC 指出的程序)。但是,运行git difftool仍然没有打开融合。然后我创建了一个别名:

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

将此保存在您的 .bashrc 或 .zshrc 或您的 shell 的相应配置中。这实质上是将分支的状态与分支上的先前提交进行比较。

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

于 2016-02-09T15:51:07.127 回答