880

我正在合并一个可能有很多冲突的远程分支。我怎么知道它是否会发生冲突?

我没有看到类似--dry-runon的东西git-merge

4

20 回答 20

989

如前所述,传入--no-commit标志,但为了避免快进提交,还要传入--no-ff,如下所示:

$ git merge --no-commit --no-ff $BRANCH

要检查分阶段的更改:

$ git diff --cached

即使是快进合并,您也可以撤消合并:

$ git merge --abort
于 2009-02-01T19:57:26.980 回答
273

我只需要实现一个自动发现存储库与其远程之间冲突的方法。该解决方案在内存中进行合并,因此它不会触及索引,也不会触及工作树。我认为这是解决此问题的最安全的方法。以下是它的工作原理:

  1. 获取远程到您的存储库。例如: git fetch origin master
  2. 运行 git 合并基础:git merge-base FETCH_HEAD master
  3. 运行git merge-tree:git merge-tree mergebase master FETCH_HEADmergebase是上一步merge-base打印的十六进制id)

现在假设您要将远程 master 与本地 master 合并,但您可以使用任何分支。git merge-tree将在内存中执行合并并将结果打印到标准输出。用于模式的 Grep<<>>. 或者您可以将输出打印到文件并检查。如果您找到以“两者都已更改”开头的行,那么很可能会发生冲突。

于 2011-06-08T19:04:09.967 回答
114

我假设您只是想在实际尝试合并之前找出自己遇到了多少麻烦......并且在合并失败后重置到最后一次提交相对容易,所以如果那样我不会感到惊讶是预期的方法。

也就是说,如果您真的不想修改工作树中的现有文件 - 您可以创建一个补丁并针对目标分支对其进行测试。这还具有准确显示对哪些文件进行了哪些更改的好处 - 只需在文本编辑器中打开补丁文件即可。

git checkout -b mycrazybranch
[change some stuff...]
git add .
git commit -m "changed some stuff"
git format-patch master --stdout > crazy.patch
git checkout master
git apply crazy.patch --check
[all good! cleanup...]
rm crazy.patch

如您所见,这将创建一个补丁文件,然后您可以使用 --check 对其进行测试,看看是否有任何错误,然后删除补丁文件。

于 2011-06-14T06:29:18.293 回答
83

你可以git merge --abort在看到有冲突之后再做。

于 2011-06-13T20:30:44.293 回答
70

作为现有答案的总结,有两种方法可以检查是否存在合并冲突

git format-patch $(git merge-base branch1 branch2)..branch2 --stdout | git apply --3way --check -

注意,你当前的分支应该是branch1当你运行上面的命令时

其他方式:

git merge --no-commit branch2
# check the return code here
git merge --abort
于 2012-09-10T04:13:34.077 回答
61

我对此的简单暴力解决方案是:

  1. 创建一个“pre-master”分支(当然来自 master)

  2. 将您想要的所有东西合并到这个预主中。
    然后你可以在不接触 master 的情况下看到合并是如何发生的。

    • 将 pre-master 合并到 master 或
    • 将所有想要发布的分支合并到 master

无论如何,我会听从@orange80 的建议。

于 2011-05-16T16:29:30.183 回答
50

我为此做了一个别名,就像一个魅力,我这样做:

 git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '

现在我只是打电话

git mergetest <branchname>

找出是否有任何冲突。

于 2014-04-18T06:10:08.940 回答
49

撤消与 git 的合并非常容易,您甚至不必担心空运行:

$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world

编辑:如以下评论中所述,如果您的工作目录或暂存区有更改,您可能希望在执行上述操作之前将它们隐藏起来(否则它们将在git reset上述操作后消失)

于 2009-02-01T21:24:46.180 回答
29

只需将您当前的分支与远程分支进行比较,这将告诉您在执行拉取/合并时会发生什么变化。

#see diff between current master and remote branch
git diff master origin/master
于 2010-12-10T03:31:39.977 回答
24

不完全一样。但是您可以使用 --no-commit 选项,因此它不会在合并后自动提交结果。通过这种方式,您可以检查并在需要时撤消合并,而不会弄乱提交树。

于 2011-06-13T20:15:46.867 回答
23

我使用request-pull git 命令来执行此操作。它允许您查看合并时会发生的所有更改,但无需对本地或远程存储库执行任何操作

例如,假设您想将一个名为“feature-x”的分支合并到您的主分支中

git request-pull master origin feature-x

将向您展示将要发生的事情的摘要(不做任何事情):

The following changes since commit fc01dde318:
    Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
    http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
    Adding some layout
    Refactoring
ioserver.js            |   8 +++---
package.json           |   7 +++++-
server.js              |   4 +--
layout/ldkdsd.js       | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js

如果添加-p参数,您还将获得完整的补丁文本,就像您对每个更改的文件执行 git diff 一样。

于 2015-06-26T10:24:45.997 回答
23

我很惊讶还没有人建议使用补丁。

假设您想测试从your_branchinto的合并master(我假设您已经master签出):

$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch

这应该够了吧。

如果您收到类似的错误

error: patch failed: test.txt:1
error: test.txt: patch does not apply

这意味着补丁不成功,合并会产生冲突。没有输出意味着补丁是干净的,您可以轻松合并分支


请注意,这实际上不会更改您的工作树(当然,除了创建补丁文件,但之后您可以安全地删除它)。从 git-apply 文档:

--check
    Instead of applying the patch, see if the patch is applicable to the
    current working tree and/or the index file and detects errors. Turns
    off "apply".

任何比我更聪明/更有经验的 git 的人请注意:如果我在这里错了,请告诉我,这种方法确实显示出与常规合并不同的行为。奇怪的是,在这个问题存在 8 年多的时间里,没有人会提出这个看似显而易见的解决方案。

于 2017-09-14T06:32:59.093 回答
15

Git 在合并时引入了一个 --ff-only 选项。

来自: http: //git-scm.com/docs/git-merge


--ff-only

拒绝合并并以非零状态退出,除非当前 HEAD 已经是最新的或者可以将合并解析为快进。

这样做将尝试合并和快进,如果不能,它会中止并提示您无法执行快进,但不会影响您的工作分支。如果它可以快进,那么它将在您的工作分支上执行合并。此选项在 上也可用git pull。因此,您可以执行以下操作:

git pull --ff-only origin branchA #See if you can pull down and merge branchA

git merge --ff-only branchA branchB #See if you can merge branchA into branchB
于 2015-06-11T20:10:41.890 回答
10

这可能很有趣:从文档中:

如果您尝试了导致复杂冲突的合并并想要重新开始,您可以使用git merge --abort恢复。

但你也可以用幼稚(但很慢)的方式来做:

rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)

(注意:仅克隆到 /tmp 是行不通的,您需要一份副本,以确保未提交的更改不会发生冲突)。

于 2013-12-17T03:00:21.627 回答
9

我使用 git log 查看来自 master 分支的功能分支发生了什么变化

git log does_this_branch..contain_this_branch_changes

例如 - 查看已合并/未合并到 master 的功能分支中的提交:

git log master..feature_branch
于 2013-07-02T23:20:07.897 回答
5

我的解决方案是向后合并。

不要将您的分支合并到远程“目标”分支中,而是将该分支合并到您的分支中。

git checkout my-branch
git merge origin/target-branch

您将查看是否存在任何冲突,并可以计划如何解决它们。

之后,您可以通过 git 中止合并merge --abort,或者(如果没有任何冲突并且发生了合并)通过回滚到先前的提交git reset --hard HEAD~1

于 2019-12-19T06:25:50.713 回答
3

如果你想从 B 快进到 A,那么你必须确保 git log B..A 什么都没有显示,即 A 没有 B 没有的任何东西。但是即使 B..A 有一些东西,你仍然可以在没有冲突的情况下合并,所以上面显示了两件事:会有一个快进,因此你不会发生冲突。

于 2011-02-06T18:01:12.453 回答
2

我只想查看冲突(在 GitHub 中还看不到它们)diff3充分利用上面的这个答案,我想出了这个:

git merge --no-commit --no-ff @{upstream}
git grep -l '<<<<<<< HEAD' | xargs -I % sh -c "echo -e '\n\e[93m%\n---\e[0m' && cat %"
git merge --abort

对我来说,这是为了检查我的 PR。您可以@{upstream}用任何分支替换。

我希望这对某人有帮助。

于 2021-12-16T21:54:23.890 回答
1

我知道这在理论上是题外话,但对于从谷歌搜索到这里的人来说,这实际上是非常切题的。

如有疑问,您始终可以使用 Github 界面创建拉取请求并检查它是否表明可以进行干净的合并。

于 2021-02-22T13:32:33.477 回答
-1

制作工作副本的临时副本,然后合并到该副本中,并区分两者。

于 2015-01-05T17:23:27.877 回答