我正在合并一个可能有很多冲突的远程分支。我怎么知道它是否会发生冲突?
我没有看到类似--dry-run
on的东西git-merge
。
如前所述,传入--no-commit
标志,但为了避免快进提交,还要传入--no-ff
,如下所示:
$ git merge --no-commit --no-ff $BRANCH
要检查分阶段的更改:
$ git diff --cached
即使是快进合并,您也可以撤消合并:
$ git merge --abort
我只需要实现一个自动发现存储库与其远程之间冲突的方法。该解决方案在内存中进行合并,因此它不会触及索引,也不会触及工作树。我认为这是解决此问题的最安全的方法。以下是它的工作原理:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
(mergebase是上一步merge-base打印的十六进制id)现在假设您要将远程 master 与本地 master 合并,但您可以使用任何分支。git merge-tree
将在内存中执行合并并将结果打印到标准输出。用于模式的 Grep<<
或>>
. 或者您可以将输出打印到文件并检查。如果您找到以“两者都已更改”开头的行,那么很可能会发生冲突。
我假设您只是想在实际尝试合并之前找出自己遇到了多少麻烦......并且在合并失败后重置到最后一次提交相对容易,所以如果那样我不会感到惊讶是预期的方法。
也就是说,如果您真的不想修改工作树中的现有文件 - 您可以创建一个补丁并针对目标分支对其进行测试。这还具有准确显示对哪些文件进行了哪些更改的好处 - 只需在文本编辑器中打开补丁文件即可。
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 对其进行测试,看看是否有任何错误,然后删除补丁文件。
你可以git merge --abort
在看到有冲突之后再做。
作为现有答案的总结,有两种方法可以检查是否存在合并冲突
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
我对此的简单暴力解决方案是:
创建一个“pre-master”分支(当然来自 master)
将您想要的所有东西合并到这个预主中。
然后你可以在不接触 master 的情况下看到合并是如何发生的。
无论如何,我会听从@orange80 的建议。
我为此做了一个别名,就像一个魅力,我这样做:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
现在我只是打电话
git mergetest <branchname>
找出是否有任何冲突。
撤消与 git 的合并非常容易,您甚至不必担心空运行:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
编辑:如以下评论中所述,如果您的工作目录或暂存区有更改,您可能希望在执行上述操作之前将它们隐藏起来(否则它们将在git reset
上述操作后消失)
只需将您当前的分支与远程分支进行比较,这将告诉您在执行拉取/合并时会发生什么变化。
#see diff between current master and remote branch
git diff master origin/master
不完全一样。但是您可以使用 --no-commit 选项,因此它不会在合并后自动提交结果。通过这种方式,您可以检查并在需要时撤消合并,而不会弄乱提交树。
我使用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 一样。
我很惊讶还没有人建议使用补丁。
假设您想测试从your_branch
into的合并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 年多的时间里,没有人会提出这个看似显而易见的解决方案。
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
这可能很有趣:从文档中:
如果您尝试了导致复杂冲突的合并并想要重新开始,您可以使用git merge --abort恢复。
但你也可以用幼稚(但很慢)的方式来做:
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(注意:仅克隆到 /tmp 是行不通的,您需要一份副本,以确保未提交的更改不会发生冲突)。
我使用 git log 查看来自 master 分支的功能分支发生了什么变化
git log does_this_branch..contain_this_branch_changes
例如 - 查看已合并/未合并到 master 的功能分支中的提交:
git log master..feature_branch
我的解决方案是向后合并。
不要将您的分支合并到远程“目标”分支中,而是将该分支合并到您的分支中。
git checkout my-branch
git merge origin/target-branch
您将查看是否存在任何冲突,并可以计划如何解决它们。
之后,您可以通过 git 中止合并merge --abort
,或者(如果没有任何冲突并且发生了合并)通过回滚到先前的提交git reset --hard HEAD~1
如果你想从 B 快进到 A,那么你必须确保 git log B..A 什么都没有显示,即 A 没有 B 没有的任何东西。但是即使 B..A 有一些东西,你仍然可以在没有冲突的情况下合并,所以上面显示了两件事:会有一个快进,因此你不会发生冲突。
我只想查看冲突(在 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}
用任何分支替换。
我希望这对某人有帮助。
我知道这在理论上是题外话,但对于从谷歌搜索到这里的人来说,这实际上是非常切题的。
如有疑问,您始终可以使用 Github 界面创建拉取请求并检查它是否表明可以进行干净的合并。
制作工作副本的临时副本,然后合并到该副本中,并区分两者。