如何找出哪些Git提交引起了冲突?

27

我正在将上游的更改合并到我的项目中,最近有很多提交导致了许多合并冲突。一次性尝试解决所有合并冲突是没有意义的。

如何找出哪些提交引起了冲突?以下任何一种都可以接受:

  • 一种方法是使Git在发现冲突时停止合并
  • 一种方法是使Git按时间顺序列出所有发生冲突的提交
  • 其他任何方式都可以让我按照时间顺序逐个解决冲突,而不需要一次合并几个提交以便于发现冲突

2
Git与svn有所不同。它试图一次性合并所有提交。您可以尝试交互式变基,它逐个应用提交,并在发现冲突时立即失败。 - madhead
4个回答

19
你可以试试git imerge:它会逐个应用你的提交,让你有机会进行增量式的变基(意味着你可以开始一个变基,中断它,稍后继续!)。
你可以在这里看到增量合并 vs. 直接合并 vs. 变基的比较。

git imerge 绝对是有用的。 - John Szakmeister
谢谢!这也是一个不错的解决方案,但是git-mergemate默认情况下正好符合我的想法。git-imerge也不错,但对我的需求有点过度。 - Davis Sorenson
1
不必使用像 git imerge 这样的外部工具,您也可以尝试使用 cherry-picking 来查看一系列修订版本中的冲突,一次一个(这基本上就像是 rebase)。 - user456814

7
Michael Haggerty还有一个工具叫做git-mergemate,其中包含一个find-conflict命令:

git-mergemate find-conflict BRANCH1..BRANCH2

使用二分法确定在将BRANCH2合并到BRANCH1时最早引起冲突的提交。不保留任何合并。

git-mergemate find-conflict BRANCH1...BRANCH2

使用二分法找到一对最早的提交(每个分支一个),它们不能干净地合并。不保留任何合并。

git imerge可以用于增量合并并解决冲突,但它没有git-mergematefind-conflicts的等效功能。


3
根据链接,似乎 git-mergemate 实际上只是 VonC 在下面回答中建议的 git imerge 的旧版本。你应该编辑这个答案,直接指向 imerge。 - Mark Amery

3
你可以使用 git log --merge 命令来查看在将另一个分支合并到当前分支时所有冲突的提交记录。
# find all conflicted files
git merge --no-commit --no-ff other_branch | grep "CONFLICT"

# find all commits from 'other_branch' that causes the conflicts
git log --merge | grep commit

# abort "--no-commit" command above, because we only want to test and see
git merge --abort

它将产生类似以下的内容:
commit bb713a4f01e4e55a2b297f7facf962090c11687f
commit 280d44bd8a569108319080633714fa8398eab3c4
commit 3a99961983f5d3ef4508d2a8457309f779650f68
commit 87239c7fef291206063e2c840270298556ee0ef4
commit f4e27e2d5753a9eaf375da66bc8a3d589a22ba23
commit c4365a21bb85a43f227047ecdda789320aa12918
commit 78572542cf08eb8d61a40b20c12cf11357eeb3df
commit cfbc6ffe334ed5748bd3988d3b48ab42a48eeb6a
commit 88a273099afb49b968ebf4c0c3602a334ef0b2d8

若未启动合并 (git merge),执行git log --merge将产生以下错误:

fatal: --merge without MERGE_HEAD?

此命令仅可在合并过程中执行。


1

你为什么不想使用 rebase(非交互式)来与上游分支同步变更呢?如果每次提交时出现冲突,它会停止,然后在解决冲突后可以恢复重启。这就像增量合并,而且它已经内置在 Git 中了,无需外部插件/工具:

git fetch <remote>
git rebase <remote>/<upstream-branch>
# Conflict on commit X, resolve conflict, then continue the rebase
git rebase --continue

关于强制推送重写的提交的警告

请注意,重新基于您的本地分支将更改其提交的 sha ID。如果您已经将要重新基于的提交推送到远程,则需要强制推送新的提交以覆盖旧的提交,这可能会带来潜在问题,尤其是当您与他人共享分支时。您可以在以下链接中了解更多有关这些问题的信息:


Rebase 是可以的,但通常你不会想要将其 rebase 到已经推送到上游的分支中(而且强制提交可能不是一个选项)。 - ideasman42
@ideasman42,我不明白你所说的“force commit”是什么意思。Git中没有这样的命令或选项。你是指强制推送吗? - user456814
抱歉,我指的是“强制推送”。 - ideasman42
@ideasman42,此外,原帖作者正在尝试将上游更改合并到他的本地分支中。我的答案不会将上游变基,而是将未推送的本地分支变基到上游之上。使用我的答案无需强制推送,因为它不会变基已经推送的提交。 - user456814
@ideasman42,我是否误解了您的第一条评论?“将基础分支合并到”分支是什么意思?问题中也没有提到原帖作者是否已经将本地更改推送到远程存储库。 - user456814
显示剩余2条评论

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