git difftool,立即打开所有的差异文件,而不是一个一个地打开。

285
默认的git diff行为是串行地打开每个差异文件(在打开下一个文件之前等待上一个文件关闭)。
我正在寻找一种同时打开所有文件的方法 - 在BeyondCompare中,例如,这将在同一BC窗口中的选项卡中打开所有文件。
这将使审核复杂的变更集更加容易;在差异文件之间快速切换并忽略不重要的文件。

"git diff" 还是 "git difftool"?您可能希望在(为所有人开放,并且具有各种网络界面)git邮件列表上发布请求:git@vger.kernel.org - Jakub Narębski
我正在使用“git difftool”来触发外部差异应用程序。感谢邮件列表的建议。 - Seba Illingworth
知道平台将会很有帮助。在基于Unix的平台上,我会编写一个脚本执行差异操作并指示git使用该脚本。在脚本中,我会在后台运行差异操作,然后让脚本结束。 - Chris Cleeland
Windows平台,但感谢Chris的建议。 - Seba Illingworth
1
对于mergetool:http://stackoverflow.com/questions/39259116/how-do-i-make-gvimdiff-opened-by-git-mergetool-open-all-files-in-tabs - Ciro Santilli OurBigBook.com
13个回答

254

git v1.7.11开始,你可以使用git difftool --dir-diff进行目录比较。

例如,此功能可与Meld 3.14.2很好地配合使用,并让您浏览所有修改过的文件:

git difftool --dir-diff --tool=meld HEAD~ HEAD

这是一个方便的 Bash 函数:

git-diff-meld() (
  git difftool --dir-diff --tool=meld "${1:-HEAD~}" "${2:-HEAD}"
)
以下回答适用于早于Git v1.7.11的版本安装。
此前有人在git邮件列表上问了同样的问题。我基于该电子邮件线程编写了一个Shell脚本,可以在任意提交之间执行目录差异。
从Git v1.7.10开始,git-diffall脚本已包含在标准Git安装的contrib中。
对于v1.7.10之前的版本,您可以从git-diffall项目在GitHub中进行安装。以下是该项目的描述:

git-diffall脚本为Git提供了基于目录的差异机制。 该脚本依赖于diff.tool配置选项来确定使用哪个差异查看器。

该脚本与用于指定要差异化的修订范围的所有形式兼容:

1)git diffall:显示工作树和暂存更改之间的差异
2)git diffall --cached [<commit>]:显示暂存更改和HEAD(或其他命名提交)之间的差异
3)git diffall <commit>:显示工作树和命名提交之间的差异
4)git diffall <commit> <commit>:显示两个已命名的提交之间的差异
5)git diffall <commit>..<commit>:与上述相同
6)git diffall <commit>...<commit>:显示包含并到第二个提交的分支上的更改,从它们俩的公共祖先开始

注意:所有形式都可以附加路径限制器[--] [<path>]

此脚本基于Git列表上Thomas Rast提供的示例


5
我非常感激你的脚本。坦白地说,我无法理解为什么Git在这方面表现得不正确(Mercurial可以,并且多年来一直如此),也无法理解Git社区缺乏兴趣的原因。 - Douglas
8
关于git difftool --dir-diff和Beyond Compare的更新:我联系了Beyond Compare的作者Scooter Software,他们表示bcompare.exe并不是一个受支持的解决方案,并且如果同时打开多个diff,则可能会导致问题。他们计划在将来的版本中为bcomp.exe添加对文件夹diff的支持(与此同时,我将继续使用bcompare.exe作为不受支持的解决方法)。 - Peter Rust
5
@coin 我刚刚用Beyond Compare 4进行了测试,--dir-diff似乎可以与支持的bcomp.exe一起使用。 - Peter Rust
我在BC4和git difftool --dir-diff方面没有成功,但https://github.com/thenigan/git-diffall与BC4集成得很好。FYI,我在Mac OS上。 - Tim D
5
评论一下,使用 --dir-diff 命令可以与 Meld 完美配合。然后,它将允许您选择和查看单个文件的差异。 - mkasberg
显示剩余7条评论

70

这是我最终采用的方案...

将以下代码复制到一个名为git-diffall(无扩展名)的文件中:

#!/bin/sh
git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename" &
done

将文件放置在你的Git安装目录下的cmd文件夹中(例如C:\Program Files (x86)\Git\cmd

使用方法与git diff相同:

git diffall
git diffall HEAD
git diffall --cached 
git diffall rev1..rev2
etc...

说明:关键在于 & 参数,它告诉外部diff命令在后台任务中运行,以便立即处理文件。在BeyondCompare中,这将为每个文件打开一个带有自己选项卡的屏幕。


3
在Linux上使用Git 2.x时,我需要进行轻微修改:将"$filename"改为"../$filename"。然后就可以与Beyond Compare完美配合了。 - Dave C
1
@DaveC,在原始线程中,它说“将文件存储在git安装的cmd文件夹中”,并提供了一个Windows示例。你在Linux中把“git-diffall”文件存储在哪里了? - m4l490n
2
在将git-diffall文件添加到C:\ Program Files \ Git \ cmd文件夹后,我们需要重新启动Windows吗?我按照指示进行了操作,但执行以下命令时出现错误:`$ git diffall git: 'diffall' is not a git command. See 'git --help'.Did you mean this? difftool` - nesdis
很有可能 C:\Program Files (x86)\Git\cmd 不在路径中。这种情况下,git-diffall文件需要放置在路径中的文件夹中。例如:C:\SPB_Data\bin。在我的情况下,git实际上在路径 /mingw64/bin/git 中。 - nesdis
1
我希望能够在代码库的任何地方运行此命令,因此我在开头添加了以下行来计算代码库的根目录:GIT_ROOT=$(git rev-parse --show-toplevel),然后更改了difftool行,以便文件名以根目录为前缀:git difftool "$@" --no-prompt "$GIT_ROOT/$filename" & - SteveDonie
显示剩余7条评论

24

meld有一个不错的特性,如果你给它一个受版本控制的目录(Git、Mercurial、Subversion、Bazaar和可能还有其他),它将自动列出所有已更改的文件,并且你可以双击查看各个文件之间的差异。

我认为只需键入meld .让它自行确定版本控制系统,比配置版本控制系统来启动meld要容易得多。而且,您可以使用相同的命令,无论您的项目使用的是哪种版本控制系统,这对于经常在不同的版本控制系统之间切换的人来说非常方便。

唯一的缺点是,与从git/hg/svn传递更改相比,meld扫描更改的速度较慢,但是否足够慢以成为问题将取决于您如何使用它。


4
对我来说,主要的缺点是 Meld(出于某种原因)在新窗口而不是新选项卡中打开差异,并且在关闭差异后,工作目录中的文件会在一个新选项卡中打开,并伴有一个烦人的弹出消息。 - kynan
不错的工具,但是在2012年初安装在Windows上非常糟糕。 - Wernight
@kynan 如果不是那个烦人的双窗口弹出框,这似乎是VCS不可知的差异化的完美解决方案。真遗憾。 :( - PKKid
Meld 的一个很棒的特性是它的 diff 过滤器:忽略注释中的更改或添加/删除空行等,这是 git diff 不提供的。 - kynan
1
我已经使用这种方法一年左右了;对于较小的项目来说,它运行良好,但是一旦你有一个大型项目(即许多文件),它会变得非常慢,因为它需要手动“扫描”git diffs(不确定为什么采用这种方法,当git明显可以直接提供文件列表时...) - namuol
我用它来比较两个分支。我切换到branch1,然后使用gitk导航到branch2并执行“mixed reset”。然后,我可以使用meld查看从branch1branch2更改的文件。 - koppor

3
以下内容适用于meld和kdiff3。
git difftool --dir-diff origin/branch1..origin/branch2

打开所有文件,方便浏览的窗口。可以在origin/branch-name的位置使用changesets。

例如:git difftool --dir-diff origin/master..24604fb72f7e16ed44115fbd88b447779cc74bb1


3
我找到了这种方法(GitDiff.bat和GitDiff.rb),它将文件复制到旧/新的临时目录中,然后对它们进行文件夹比较。但我更愿意直接查看工作目录中的工作文件,因为BeyondCompare有一个方便的功能,可以在差异窗口中编辑文件,非常适合快速清理。
编辑:在git邮件列表中回答我的问题时,提供了类似的方法

3

非常好!作为额外的奖励,它的工作方式与hg meld完全相同。谢谢! - PKKid

2
我在这里注意到Araxis Merge有一个“-nowait”命令选项:(点击此处)
-mowait可以防止比较等待比较关闭。也许这会返回一个立即退出代码并且有效,但是有没有人尝试过呢?对于BeyondCompare我没找到类似的选项...

2
Diffuse还具有VCS集成功能。它可以与许多其他版本控制系统(VCS)相互操作,包括SVN、Mercurial、Bazaar等。对于Git,如果某些但不是所有更改都已暂存,它甚至会显示三个窗格。在冲突的情况下,甚至会有四个窗格。

Screenshot of diffuse with staged and unstaged edits

用以下方式调用
diffuse -m

在你的Git工作副本中。
如果你问我,这是我见过的最好的视觉差异工具之一。(我也试过meld。)

你能告诉我你喜欢《漫反射》的哪个部分,特别是优于《融合》的哪个部分吗? - musiphil
@musiphil:我喜欢它的简洁性——它似乎具备了解决任务所需的确切功能集,既不多也不少。(例如差异重新对齐和制表符大小宽度。)我不记得为什么从meld转换过来,自那以后我也没有再使用meld,所以现在无法进行比较。 - krlmlr
1
Diffuse可以在没有任何配置的情况下与git一起使用。使用Diffuse -m命令可以在单个窗口中打开不同标签页中的git差异;而其他工具需要太多的配置才能开始使用。 - mosh

1

对于那些想在Mac OS X上使用Araxis的git-diffall的人,我在github上fork了git-diffall项目,并添加了一个AppleScript来包装Araxis Merge命令。注意:这是Araxis Merge for Mac OS X附带的araxisgitdiff文件的略微修改的克隆版本。

https://github.com/sorens/git-diffall


1
我编写了一个PowerShell脚本,可以复制两个工作树并使用DiffMerge进行比较。因此,您可以执行以下操作:
GitNdiff master~3 .

例如,要比较三次提交前的主分支与当前工作树。

它非常亮和新,但可能充满了错误。一个缺点是还未添加到您的工作树中的文件会复制到两个工作树中。这也可能会很慢。

http://github.com/fschwiet/GitNdiff


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接