【问题标题】:I ran into a merge conflict. How can I abort the merge?我遇到了合并冲突。如何中止合并?
【发布时间】:2010-09-11 05:35:43
【问题描述】:

我使用了git pull 并发生了合并冲突:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

我知道该文件的其他版本是好的,而我的是坏的,所以我的所有更改都应该被放弃。我该怎么做?

【问题讨论】:

  • 我知道这是一个非常老的问题,但是你想中止 whole 合并,让你正在合并的分支保持未合并,还是忽略这个文件作为更大合并的一部分,让所有其他文件正常合并?对我来说,你的标题暗示前者,你的问题主体想要后者。答案两者兼而有之,但没有说清楚。
  • 我在提交时遇到了类似的情况,说自动合并失败;修复冲突然后提交结果:[rejected] gh-pages -> gh-pages (non-fast-forward)
  • Gwyn,在这里选择一个接受的答案可能很有用。投票最多的解决方案比一些更新的解决方案安全性稍差,所以我认为这将有助于突出其他解决方案:)

标签: git version-control git-merge git-merge-conflict


【解决方案1】:

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

git reset --hard HEAD

您想要的另一部分是让他们的更改覆盖您的更改。

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

git pull --strategy=theirs remote_branch

但这已被删除,正如this message by Junio Hamano(Git 维护者)所述。正如the link 中所述,您可以这样做:

git fetch origin
git reset --hard origin

【讨论】:

  • 您可以通过执行以下操作将其提升到更精细的级别,而不是进行硬重置: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。这实际上使我的合并和冲突变得少之又少。
  • 我同意。我也喜欢先获取,然后检查上游更改(git log ..@{upstream}git diff ..@{upstream})。在那之后,和你一样,我会重新调整我的工作。
  • 如更新的答案中所述,从 1.6.1 版开始,可以使用 'git reset --merge'
  • 我使用了git merge -X theirs remote_branch 而不是git pull --strategy=theirs remote_branch,因为theirs 看起来像是recursive 的一个选项
  • git merge --abort 更可取。
【解决方案2】:

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

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

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

来自git merge man page

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

MERGE_HEAD 在合并进行时出现。

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

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

【讨论】:

  • 很有趣——但是手册吓到我了。究竟什么时候适合使用?什么时候必须指定可选的<commit>? #GitMoment :-o
  • 当您想从头开始重做合并时,通常会使用此选项。我从来不用自己指定可选的提交,所以默认的(没有可选的)就可以了。
  • 我希望这个答案有更多的选票!在这一点上,它似乎是许多情况下最相关的解决方案。
  • 即使有未提交的更改,git 也能够恢复合并前的状态。不错!
  • git merge --abort 只是git reset --merge 的同义词吗?这个名字当然更有意义,但它是否具有相同的功能?
【解决方案3】:
git merge --abort

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

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

git merge --abort 等价于git reset --mergeMERGE_HEAD 存在。

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

【讨论】:

  • 这从 git v1.7.4 开始可用。它是 git reset --merge 的别名。
【解决方案4】:

我想你需要的是git reset

注意git revertsvn revert 的含义非常不同——在Subversion 中,revert 将丢弃您的(未提交的)更改,将文件从存储库返回到当前版本,而git revert“撤消”提交。

git reset 应该与svn revert 等效,即丢弃不需要的更改。

【讨论】:

    【解决方案5】:

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

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

    对于冲突中的未合并文件,git 会在索引中提供文件的通用基础版本、本地版本和远程版本。 (这是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
    

    【讨论】:

    • 感谢您的提示。不过,这不是有点糟糕的 git 用户界面吗?
    • @Peter:我不相信。只需几个带有简单选项的基本命令即可获得所需的结果。您会提出哪些改进建议?
    • 我认为git 1.6.1 命令很有意义,而且很好。这正是我想要的。我认为 1.6.1 之前的解决方案不优雅,需要了解 git 的其他部分,这些部分应该与合并解析过程分开。但是新版本很棒!
    【解决方案6】:

    对于 git >= 1.6.1:

    git merge --abort
    

    对于旧版本的 git,这将完成这项工作:

    git reset --merge
    

    git reset --hard
    

    【讨论】:

      【解决方案7】:

      您可以中止合并步骤:

      git merge --abort
      

      否则你可以保留你的更改(你在哪个分支上)

      git checkout --ours file1 file2 ...
      

      否则你可以保留其他分支更改

      git checkout --theirs file1 file2 ...
      

      【讨论】:

        【解决方案8】:

        评论表明git reset --mergegit merge --abort 的别名。值得注意的是,git merge --abort 仅等效于 git reset --merge,因为存在 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 对于与所述场景类似的场景更强大,并且通常合并失败。

        【讨论】:

        • 这里的“合并失败”究竟是什么意思?合并冲突还是其他?或者换一种说法:MERGE_HEAD 什么时候不存在?我的后续问题是为了了解更好地使用“git reset --merge”。
        • @Ewoks git stash apply 对我造成了合并冲突,但 git merge --abort 没有帮助,而 git reset --merge 有帮助。
        • 不得不使用它来解决失败的合并,由于某种原因我没有 MERGE_HEAD 所以 git merge --abort 不起作用。
        • 提醒其他考虑这一点的人:由于stash pop 而发生合并时,MERGE_HEAD 不存在; reset --merge 将删除您未跟踪的文件。见stackoverflow.com/a/67099267/1623757
        • 从标签到主标签合并失败后我需要什么...
        【解决方案9】:

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

        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
        

        希望对你有帮助!!!

        【讨论】:

          【解决方案10】:

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

          git stash
          git merge --abort
          git stash pop
          

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

          【讨论】:

          • 当我不小心合并到一个处理不好的 git-svn 分支时,我发现这种方法很有用。使用 git-svn 跟踪分支时,壁球合并或樱桃选择更好。实际上,我的解决方案事后将合并变成了壁球合并。
          • 问题的最佳答案
          • 这与软重置有何不同?软重置还会将存储库重置为 head,但不会触及工作副本。
          • 是的,但是当您的目标是“如何中止合并?”时,是否会想到“git reset --soft someref”。你怎么知道 someref 用什么?因此,“git merge --abort”做了正确的事情并且显然被命名为对 Git 来说是令人耳目一新的。
          【解决方案11】:

          由于 Git 1.6.1.3 git checkout 已经能够从合并的任一侧检出:

          git checkout --theirs _widget.html.erb
          

          【讨论】:

            【解决方案12】:

            可能不是 OP 想要的,但对我来说,我试图将一个稳定的分支合并到一个功能分支,但冲突太多。 我没有设法重置更改,因为 HEAD 被许多提交更改,所以简单的解决方案是强制签出到一个稳定的分支。 然后您可以结帐到另一个分支,它将与合并前一样。

            git checkout -f master

            git checkout side-branch

            【讨论】:

              【解决方案13】:

              为了避免陷入这种麻烦,可以扩展git merge --abort 方法并创建一个单独的测试分支合并之前

              案例:您有一个主题分支,它没有被合并,因为您分心/出现了一些问题/您知道,但它已经(或已经)准备好了。

              现在是否可以将其合并到 master 中?

              test 分支中工作以估计/找到解决方案,然后放弃测试分支并在主题分支中应用解决方案。

              # Checkout the topic branch
              git checkout topic-branch-1
              
              # Create a _test_ branch on top of this
              git checkout -b test
              
              # Attempt to merge master
              git merge master
              
              # If it fails you can abandon the merge
              git merge --abort
              git checkout -
              git branch -D test  # we don't care about this branch really...
              

              努力解决冲突。

              # Checkout the topic branch
              git checkout topic-branch-1
              
              # Create a _test_ branch on top of this
              git checkout -b test
              
              # Attempt to merge master
              git merge master
              
              # resolve conflicts, run it through tests, etc
              # then
              git commit <conflict-resolving>
              
              # You *could* now even create a separate test branch on top of master
              # and see if you are able to merge
              git checkout master
              git checkout -b master-test
              git merge test
              

              最后再次检查主题分支,从测试分支应用修复并继续 PR。 最后删除 test 和 master-test。

              参与?是的,但在我做好准备之前,它不会影响我的主题或主分支。

              【讨论】:

                【解决方案14】:

                我发现以下内容对我有用(将单个文件恢复到合并前状态):

                git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
                

                【讨论】:

                  【解决方案15】:

                  源树

                  因为您没有提交合并,所以只需双击另一个分支(这意味着签出它),当 sourcetree 询问您是否放弃所有更改时,请同意。

                  注意

                  这个答案是针对那些使用 SourceTree 作为 git 客户端的人。

                  【讨论】:

                  • OP显然是在使用命令行。您的帖子的价值为零。
                  • 我同意这很明显 OP 使用命令行 - 但是不使用命令行但使用 sourcetree 并且有类似问题的人在谷歌的顶部发现了这个问题(就像我一样) - 所以对于这样的人这个答案很有价值——这就是我把它留在这里的原因:)
                  猜你喜欢
                  • 1970-01-01
                  • 2019-07-25
                  • 2019-10-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-29
                  • 2012-12-08
                  相关资源
                  最近更新 更多