题 我遇到了合并冲突。我怎样才能中止合并?


我用了 git pull 合并冲突:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

我知道该文件的其他版本是好的,我的是坏的所以我的所有更改都应该放弃。我怎样才能做到这一点?


1913
2017-09-19 13:21


起源


我意识到这是一个超级老问题,但你想中止吗? 整个 合并,并保留您正在合并的分支,或者只是忽略这一个文件作为更大合并的一部分,让所有其他文件正常合并?对我来说,你的头衔暗示前者,你的问题机构需要后者。答案都做到了,没有说清楚。 - rjmunro
我在提交时遇到类似的情况,说自动合并失败;修复冲突,然后提交结果: [rejected] gh-pages -> gh-pages (non-fast-forward) - Chetabahana
Gwyn,在这里选择一个接受的答案可能会有用。最受欢迎的一个比一些更新的解决方案安全性稍差,所以我认为这将有助于突出其他人:) - Amicable


答案:


既然你的 pull 那是不成功的 HEAD (不 HEAD^)是您分支上的最后一次“有效”提交:

git reset --hard HEAD

你想要的另一件事就是让他们的改变超越你的改变。

较旧版本的git允许您使用“他们的”合并策略:

git pull --strategy=theirs remote_branch

但是,这已被删除,如中所述 Junio Hamano的这条消息 (Git维护者)。如中所述 链接相反,你会这样做:

git fetch origin
git reset --hard origin

1731
2017-09-19 14:33



您可以通过执行以下操作,将其置于更精细的级别,而不是进行硬重置: git fetch origin   - > git reset origin (soft reset, your changes are still present)   - > git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin)    我再也不用git pull了。因为在我的最新代码和原点之间的斗争中,原点应该总是赢,我总是 git fetch 和 git rebase origin。这实际上使我的合并和冲突寥寥无几。 - Kzqai
我同意。我也想先取,然后检查上游的变化(git log ..@{upstream} 要么 git diff ..@{upstream})。在那之后,和你一样,我会改变我的工作。 - Pat Notz
正如最新的回答中所述,从版本1.6.1开始,可以使用'git reset --merge' - Matt Ball
我用了 git merge -X theirs remote_branch 代替 git pull --strategy=theirs remote_branch 如 theirs 看起来像是一个选项 recursive - mlt
没有策略 theirs。 - srcspider


如果你的git版本是> = 1.6.1,你可以使用 git reset --merge

另外,正如@Michael Johnson所提到的,如果你的git版本> = 1.7.4,你也可以使用 git merge --abort

与往常一样,确保在开始合并之前没有未提交的更改。

来自 git合并手册页

git merge --abort 相当于 git reset --merge 什么时候 MERGE_HEAD 存在。

MERGE_HEAD 合并正在进行时存在。

此外,关于开始合并时未提交的更改:

如果你有改变,你不想在开始合并之前提交,只是 git stash 他们在合并之前 git stash pop 完成合并或中止后。


1592
2018-03-28 23:16



有趣 - 但手册吓到了我。什么时候适合使用?什么时候需要指定可选项 <commit>? #GitMoment:-o - conny
当您想从头开始重做合并时,通常会使用此选项。我从来没有必须自己指定可选的提交,所以默认(没有可选的<commit>)就好了。 - Carl
我希望这个答案有更多的选票!在这一点上,它似乎是许多情况下最相关的解决方案。 - Jay Taylor
由于git v1.7.4 git merge --abort也有效。 - Michael Johnson
即使有未完成的更改,git也能够在合并之前恢复状态。太好了! - T3rm1


git merge --abort

中止当前的冲突解决过程,并尝试重建   合并前的状态。

如果合并时存在未提交的工作树更改   开始, git merge --abort 在某些情况下会无法做到   重建这些变化。因此建议始终使用   在运行git merge之前提交或存储您的更改。

git merge --abort 相当于 git reset --merge 什么时候    MERGE_HEAD 存在。

http://www.git-scm.com/docs/git-merge


378
2017-11-12 21:40



自git v1.7.4开始提供此功能。它是git reset --merge的别名。 - Michael Johnson
不适用于章鱼合并冲突。 - ks1322


在这个特定的用例中,您并不想真正中止合并,只需以特定方式解决冲突。

也没有特别需要重置和执行与不同策略的合并。 git正确地突出了冲突,接受其他方面更改的要求仅适用于这一个文件。

对于冲突中的未合并文件,git使索引中的文件的公共基础,本地和远程版本可用。 (这是他们阅读的地方,用于3-way diff工具 git mergetool。) 您可以使用 git show 查看它们。

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

解决冲突以逐字使用远程版本的最简单方法是:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

或者,使用git> = 1.6.1:

git checkout --theirs _widget.html.erb

73
2017-09-20 10:41



谢谢你的提示。不过这不是一个糟糕的git用户界面吗? - Peter
@Peter:我不相信。使用一些简单选项的基本命令可以实现所需的结果。你会提出什么改进? - CB Bailey
我觉得 git 1.6.1 命令很有意义,而且很好。这正是我想要的。我认为1.6.1之前的解决方案不够优雅,需要了解应该与合并解析过程分离的git的其他部分。但新版本很棒! - Peter


我想这是 git reset 你需要。

要小心 git revert 意味着一些与众不同的东西,比方说 svn revert  - 在Subversion中,revert将丢弃您的(未提交的)更改,将文件从存储库返回到当前版本,而 git revert “撤消”提交。

git reset 应该做相当于 svn revert,也就是说,丢弃不需要的更改。


72
2017-09-19 13:25





由于评论表明 git reset --merge 是别名 git merge --abort,值得注意的是 git merge --abort 只相当于 git reset --merge鉴于一个 MERGE_HEAD 存在。这可以在git help for merge命令中读取。

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

合并失败后,什么时候没有 MERGE_HEAD,失败的合并可以撤消 git reset --merge 但不一定是 git merge --abort所以他们不仅是同一件事的新旧语法

我个人觉得 git reset --merge 对于类似于所描述的场景而言更加强大,并且通常会失败合并。


29
2018-04-02 12:16



这里的“合并失败”究竟是什么意思?合并冲突或其他什么?或者改写它:MERGE_HEAD何时不存在?我的后续问题是要了解更好地使用“git reset --merge”。 - Ewoks


自Git 1.6.1.3起 git checkout 已经能够从合并的任何一方结账:

git checkout --theirs _widget.html.erb

16
2017-07-17 01:29