我遇到了合并冲突。如何中止合并?


2536

我使用git pull了合并冲突:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

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


30
我意识到这是一个非常老的问题,但是您是否要中止整个合并,并保留要合并的分支,或者只是忽略该文件作为较大合并的一部分,让所有其他文件合并为正常?对我而言,您的头衔暗示着前者,您的问题主体想要后者。答案都做到了,而没有弄清楚。
rjmunro

我在提交时遇到类似的情况,说自动合并失败;解决冲突,然后提交结果:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana '16

4
Gwyn,在此处选择一个可接受的答案可能会很有用。票数最高的解决方案要比一些最新的解决方案安全一些,因此,我认为这将有助于凸显其他解决方案:)
Amicable

Answers:


2218

由于您pull不成功,因此HEAD(not HEAD^)是分支上的最后一个“有效”提交:

git reset --hard HEAD

您想要的另一件事情是让他们的更改优先于您的更改。

较早版本的git允许您使用“其”合并策略:

git pull --strategy=theirs remote_branch

但这已被删除,正如Junio Hamano(Git维护者)在此消息中所述。如链接所述,您可以这样做:

git fetch origin
git reset --hard origin

49
除了执行硬重置之外,您还可以通过以下方式将其提升到更精细的级别: 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 fetchgit rebase origin。这实际上使我之间的合并和冲突变得越来越少。
卡扎伊2010年

7
我同意。我还喜欢先获取,然后检查上游更改(git log ..@{upstream}git diff ..@{upstream})。之后,像您一样,我将重新整理工作。
Pat Notz 2010年

162
如最近的回答所述,从1.6.1版开始,可以使用'git reset --merge'–
Matt Ball,

5
我用git merge -X theirs remote_branch,而不是git pull --strategy=theirs remote_branch作为theirs看起来像一个的选项recursive
MLT

14
git merge --abort是更可取的。
丹尼尔·卡西迪

1955

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

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

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

git merge手册页

git merge --abort等同于git reset --merge何时MERGE_HEAD存在。

MERGE_HEAD 进行合并时出现。

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

如果您有更改,则不想在开始合并之前提交,只需git stash在合并之前,git stash pop完成合并或中止之后再提交即可。


3
有趣-但是手册使我恐惧。什么时候才合适?什么时候需要指定可选的<commit>?#GitMoment:-o
conny

1
当您要从头开始重做合并时,通常会使用它。我从来没有自己指定可选的提交,因此默认值(没有可选的<commit>)就可以了。
卡尔,

44
我希望这个答案有更多票!此时,在许多情况下,这似乎是最相关的解决方案。
杰伊·泰勒

1
即使进行了未提交的更改,git也能够在合并之前恢复状态。真好!
T3rm1 2014年

2
是否git merge --abort只是一个代名词git reset --merge?这个名字当然更有意义,但是它具有相同的功能吗?
Tikhon Jelvis,2014年

517
git merge --abort

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

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

git merge --abort等同于git reset --merge何时 MERGE_HEAD存在。

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


16
自git v1.7.4起提供。这是git reset --merge的别名。
迈克尔·约翰逊

162

它是如此简单。

git merge --abort

当您遇到此类故障并运行git status命令时,Git本身会向您显示解决方案。

git status

希望这对人们有帮助。


97

我认为这是git reset您需要的。

请注意,这git revert意味着与svn revert- 非常不同的东西-在Subversion中,还原将放弃您(未提交的)更改,将文件从存储库返回到当前版本,而git revert“撤消”提交。

git reset应该做等同于svn revert,也就是说,放弃不必要的更改。


76

在这种特定的用例中,您实际上并不想中止合并,而只是以特定的方式解决冲突。

也不特别需要重置并执行具有不同策略的合并。git已经正确地突出显示了冲突,并且接受其他方面的更改的要求仅适用于此文件。

对于冲突中的未合并文件,git会在索引中提供文件的通用基本版本,本地版本和远程版本。(这是读取它们的位置,以便在3向差异工具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

5
谢谢你的提示。但是,这难道不是差劲的git用户界面吗?
彼得

@Peter:我不相信。用一些带有简单选项的基本命令就可以实现预期的结果。您会建议什么改进?
CB Bailey 2010年

10
我认为该git 1.6.1命令很有意义,而且很好。那正是我想要的。我认为1.6.1之前的解决方案不完善,并且需要有关git其他部分的知识,这些知识应与合并解析过程分开。但是新版本很棒!
彼得

67

对于类似的情况,我做了git fetchgit pull,然后意识到上游分支不是主分支,这导致了不必要的冲突。

git reset --merge 

还原后无需重置我的本地更改。


45

注释表明这git reset --merge是的别名git merge --abort。值得注意的是,git merge --abort它仅等同于存在git reset --mergea的MERGE_HEAD情况。可以在git help for merge命令中阅读。

当存在MERGE_HEAD时,git merge --abort等效于git reset --merge。

合并失败后,如果MERGE_HEAD没有合并失败,则可以使用git reset --merge(但不一定使用)撤消失败的合并git merge --abort它们不仅是同一事物的新旧语法

就个人而言,我发现git reset --merge在与上述情况相似的情况下功能更强大,并且合并通常失败。


2
“合并失败”实际上是什么意思?合并冲突或其他?或改写一下:什么时候不出现MERGE_HEAD?我的后续问题是在那里更好地理解“ git reset --merge”的用法。
Ewoks

@Ewoks git stash apply对我造成了合并冲突,但git merge --abort没有帮助git reset --merge
尼特尔

27

如果您最终遇到合并冲突并且没有任何要提交的内容,但是仍然显示合并错误。应用下面提到的所有命令后,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

请删除

.git \ index.lock

归档文件(将其剪切粘贴到其他位置,以备恢复),然后根据需要的版本输入以下任何命令。

git reset --hard HEAD
git reset --hard origin

希望有帮助!!!


19

保留工作副本状态的另一种方法是:

git stash
git merge --abort
git stash pop

我通常不建议这样做,因为它实际上就像在Subversion中合并一样,因为它在接下来的提交中丢弃了分支关系。


当我不小心合并到一个git-svn分支时,发现这种方法很有用,但它不能很好地处理该分支。当使用git-svn跟踪分支时,壁球合并或樱桃采摘更好。实际上,我的解决方案在事实发生之后将合并变为壁球合并。
阿兰·奥德

对该问题的最佳答案
Fouad Boukredine


3

我发现以下对我有用(将单个文件还原为合并前的状态):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

-5

源树

因为您没有提交合并,所以只需双击另一个分支(这意味着将其签出),然后当sourcetree询问您有关放弃所有更改的信息时,请同意:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.