展示git中两个提交的非合并差异

22

我有两个提交记录,其中一个是另一个的祖先。 (它们恰好是分支的起点和终点。我不认为这很重要,但如果确实如此,我会包括它)。

我想查看两个提交之间的差异,但是 排除 在这两个提交之间进行的合并提交(也就是说,所有具有多个父级的提交)。 (基本上,我想要任何在分支上进行的“真正”的提交,不包括合并提交。)

这可能吗? 如果可以,您如何完成此操作?

如有必要,假设在合并提交期间没有解决冲突...但是能够优雅地处理冲突的解决方案会获得额外的加分。


请澄清一下:您是想为每个不是合并提交的提交生成单独的差异,还是您期望其他内容? - Jeff Ferland
@Autocracy:我已经编辑过了,希望能够澄清我所寻找的内容。如果还是不清楚,请告诉我。 - Craig Walker
5个回答

19

您的问题有点含糊,但我认为您想要这个。

git log --no-merges -p branch-start..branch-end

3
你可能更喜欢使用 --first-parent - Ryan C. Thompson
2
-p是一张票,当与--no-merges结合使用时。谢谢! - Craig Walker
很遗憾,你不能对缓存/当前(未提交)执行此操作(创建范围)... 你可以使用 git diff $(git merge-base branchA currentbranch) 获取整个差异。 唉! - Andy Hayden
另外见:git:限制提交的累积差异 - TachyonVortex
这个命令行也遇到了我的问题... 顺便问一下,我们怎么使用GitHub的pull request视图代替这个命令行呢? - Haven Lin

6
如果你的所有合并请求都来自同一个分支(比如说master),或者都包含在另一个分支中,你可以使用这个问题解决方案
假设你有以下树形结构:
         x---y-+-z-+-branch
        /     /   /
---a---b---c-+-d-+-e---master

如果您想比较的两个提交是 bbranch。那么,不要直接比较这两个提交,运行

git diff master...branch

该命令将显示分支(x,y,z)上所有更改,但排除了与主分支(master)相同的内容(合并的c,d,e)。请注意,这也会忽略尚未合并到分支中的主分支更改。

根据文档:

git diff [--options] commit...commit [--] […​]

此形式用于查看包含第二个提交和之前所有提交的分支上的更改,起点是两个提交的共同祖先。 "git diff A...B" 等同于 "git diff $(git-merge-base A B) B"。


3

我不知道 --no-merges -o 选项,但这里有另一种解决方案(假设合并已从主分支进行):

git checkout -b temp
git rebase --onto master branch-start branch-end
git diff master

支持此解决方案,因为它似乎不太容易出错。虽然 --first-parent 可以帮助排除从目标分支拉取到特性分支的所有提交,当中有一些合并时,而 --no-merges 则允许排除合并提交本身,但这些标志是应用于 git log 而不是 git diff,所以我们必须逐步审查每个提交。此外,对我来说更重要的是,从审查中排除合并提交可能是危险的,因为它们可能包含重要的更新。此解决方案允许查看确切的差异,而不会丢失任何内容。 - Andrei K.

2

以下是我如何将我的检出分支与主分支进行比较,但排除合并提交期间所做的更改。我喜欢使用Meld的目录模式。

# if you've never setup Meld as your difftool
sudo apt install meld
git config --global diff.tool meld

# the command to see the differences
git difftool -d --no-merges master

1
我想找一种方法来显示单个差异视图(两次提交之间的所有非合并更改),而不是使用git log中的每个提交补丁视图。我基于这个问题的被接受答案提供的解决方案得出了一个解决方案。
它作为一个shell函数包装起来,以便多次使用开始/结束提交参数。
function review() {
  start_commit="$1"
  end_commit="$2"
  git log --pretty=format: --no-merges --first-parent --name-only $start_commit...$end_commit | grep -v '^$' | sort | uniq | xargs git difftool -d $start_commit...$end_commit --
}

这个方法基本上使用git log来获取两个提交之间已更改文件的列表,排除合并操作,对列表进行去重和清理,然后将该列表传递给相同两个提交之间的git diff

这种解决方案的一个不可取的副作用是在diff中包含了上游分支中发生的更改,而这些更改也恰好是在分支中只有两个提交之间更改过的文件集合中的。但是,在许多情况下,这种“单一diff”视图仍然对我很有用。

事实上,GitHub也支持这种方式,如果你的分支有一个关联的拉取请求(它会自动在其diff视图中排除来自上游的合并):

https://github.com/[user]/[repo]/pull/[number]/files/[commit1]..[commit2]


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