我正在寻找像Visual SourceSafe(VSS)或Team Foundation Server(TFS)中的“比较”功能。 Git是否支持这种功能?
从git-diff
手册中得知:
git diff [--options] <commit> <commit> [--] [<path>...]
例如,要查看文件“main.c”在现在和两个提交之前的差异,以下是三个等效的命令:
$ git diff HEAD^^ HEAD main.c
$ git diff HEAD^^..HEAD -- main.c
$ git diff HEAD~2 HEAD -- main.c
..
并不是必需的,但如果使用它也可以(除了一些相对老的版本可能不支持)。如果两个提交之间的距离很远,你也可以使用 git log
或 gitk
找到要使用的 SHA1 值。gitk
的上下文菜单中还有一个 "diff selected -> this" 和 "diff this -> selected" 选项,可以进行差异比较。 - Cascabel--
在有文件名为 -p
的情况下非常有用,尤其是在脚本中使用,实践中只在极少数情况下需要使用。 - Palecgit diff <revision_1>:<file_1> <revision_2>:<file_2>
<file_1>
和<file_2>
在当前目录中,而不是在顶级Git管理的目录中,则需要在Unix系统上加上./
前缀:<revision_1>:./filename_1
。 - Andre Holznergit diff HEAD..HEAD~1
和git diff HEAD~1
之间的差异类似。 - Gregory Kuhn如果你已经配置了"difftool",你可以使用
git difftool revision_1:file_1 revision_2:file_2
示例:比较同一分支上文件的最后一次提交和上一次提交:
假设您在项目根目录中
$git difftool HEAD:src/main/java/com.xyz.test/MyApp.java HEAD^:src/main/java/com.xyz.test/MyApp.java
你的 ~/.gitconfig 或者 project/.git/config 文件中应该包含以下条目。安装p4merge。
[merge]
tool = p4merge
keepBackup = false
[diff]
tool = p4merge
keepBackup = false
[difftool "p4merge"]
path = C:/Program Files (x86)/Perforce/p4merge.exe
[mergetool]
keepBackup = false
[difftool]
keepBackup = false
[mergetool "p4merge"]
path = C:/Program Files (x86)/Perforce/p4merge.exe
cmd = p4merge.exe \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
注意:如果你使用的是Intellij企业版或社区版,它有一个很好的工具可以在合并/变基时进行三方合并。
对于简单的差异比较,您可以右键单击->Git->与修订版本比较
选择您感兴趣的修订版本。
Intellij将显示差异。
检查$ git log
, 复制两个不同提交的SHA-1 ID,并使用这些ID运行git diff
命令。例如:
$ git diff (sha-id-one) (sha-id-two)
git diff (sha-id-one) (sha-id-two) -- filename.ext
如果不加文件名,它将列出这两个提交中所有文件的差异。 - SherylHohmangit log -u $start_commit..$end_commit -- path/to/file
以下是一个Perl脚本,它可以根据Git log命令中给定的文件打印出Git diff命令。
例如:
git log pom.xml | perl gldiff.pl 3 pom.xml
生成:
git diff 5cc287:pom.xml e8e420:pom.xml
git diff 3aa914:pom.xml 7476e1:pom.xml
git diff 422bfd:pom.xml f92ad8:pom.xml
然后可以将其剪切并粘贴到shell窗口会话中,或者通过管道传输到/bin/sh
。
注:
代码:
# gldiff.pl
use strict;
my $max = shift;
my $file = shift;
die "not a number" unless $max =~ m/\d+/;
die "not a file" unless -f $file;
my $count;
my @lines;
while (<>) {
chomp;
next unless s/^commit\s+(.*)//;
my $commit = $1;
push @lines, sprintf "%s:%s", substr($commit,0,6),$file;
if (@lines == 2) {
printf "git diff %s %s\n", @lines;
@lines = ();
}
last if ++$count >= $max *2;
}
如果你有多个文件或目录,并且想要比较非连续的提交,可以按照以下步骤操作:
创建一个临时分支(在此示例中称为"revision")
git checkout -b revision
回溯到第一个提交目标
git reset --hard <commit_target>
只挑选那些有兴趣的提交记录。
git cherry-pick <commit_interested> ...
应用差异
git diff <commit-target>^
当你完成时
git branch -D revision
如果您想使用 @mipadi 指定的方法对多个文件进行差异比较:
例如,在 HEAD
和您的 master
之间查找所有 .coffee
文件:
git diff master..HEAD -- `find your_search_folder/ -name '*.coffee'`
这将递归搜索您的 your_search_folder/
中的所有 .coffee
文件,并对它们和它们的 master
版本进行差异比较。
只是另一种使用Git强大功能的方式...
git difftool HEAD HEAD@{N} /PATH/FILE.ext
difftool-file = "!git difftool HEAD@{\"$2\"} HEAD \"$1\" #"
- blueogive其他的回答更为完整,所以请给它们点赞。 这个回答只是提醒你可以避免了解最近提交的id。通常,我会将自己设置在要进行比较的分支上,并运行diff工具,知道旧的提交uid(您也可以使用其他标识符):
git checkout master
git difftool 6f8bba my/file/relative/path.py
另外,查看这里的其他响应,设置您想要比较文件的git工具: 使用.gitconfig配置差异工具 要了解有关差异工具的更多信息,请转到difftool文档