撤消尚未推送的Git合并

我不小心在我的本地主分支上运行了git merge some_other_branch。我没有将更改推送到原始主。我如何撤消合并?


合并后,git status表示:

# On branch master# Your branch is ahead of 'origin/master' by 5 commits.

如何撤消所有这些提交?

2966818 次浏览

您可以使用git重置命令。

git重置-将当前HEAD重置为

指定的状态。git重置[--混合|

--soft|--hard|--合并][-q][]git重置[-q][]

[--] … git重置

[] [--] […]

GIT重置

你应该重置到上一个提交。这应该可以:

git reset --hard HEAD^

或者甚至HEAD^^来恢复该恢复提交。如果您不确定应该后退多少步,您可以始终提供完整的SHA引用。

如果您遇到问题并且您的主分支没有任何本地更改,您可以重置为origin/master

使用git reflog检查在合并之前哪个提交是一个(git reflog将是比git log更好的选择)。然后您可以使用以下方法重置它:

git reset --hard commit_sha

还有另一种方式:

git reset --hard HEAD~1

它会让你回到一个承诺。

请注意,任何修改和未提交/未存储的文件都将重置为未修改的状态.要保持它们要么隐藏更改,要么请参阅下面的--merge选项。


正如@Velmont在下面的回答中建议的那样,在这个直接的情况下使用:

git reset --hard ORIG_HEAD

可能会产生更好的结果,因为它应该保留您的更改。ORIG_HEAD将在合并发生之前直接指向提交,因此您不必自己寻找它。


另一个提示是使用--merge开关而不是--hard,因为它不会不必要地重置文件:

git reset --merge ORIG_HEAD

#合并

重置索引并更新工作树中的文件,这些文件在<提交>和HEAD之间不同,但保留索引和工作树之间不同的文件(即具有未添加的更改)。

好吧,这里其他人给我的答案很接近,但没有用。我是这么做的。

做这个…

git reset --hard HEAD^git status

…给了我以下状态。

# On branch master# Your branch and 'origin/master' have diverged,# and have 3 and 3 different commit(s) each, respectively.

然后我不得不多次输入相同的git reset命令。每次我这样做时,消息都会更改一个,如下所示。

> git reset --hard HEAD^HEAD is now at [...truncated...]> git status# On branch master# Your branch and 'origin/master' have diverged,# and have 3 and 3 different commit(s) each, respectively.> git reset --hard HEAD^HEAD is now at [...truncated...]> git status# On branch master# Your branch and 'origin/master' have diverged,# and have 2 and 3 different commit(s) each, respectively.> git reset --hard HEAD^HEAD is now at [...truncated...]> git status# On branch master# Your branch and 'origin/master' have diverged,# and have 1 and 3 different commit(s) each, respectively.> git reset --hard HEAD^HEAD is now at [...truncated...]> git status# On branch master# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

此时,我看到状态消息发生了变化,所以我尝试执行git pull,这似乎有效:

> git pullUpdating 2df6af4..12bbd2fFast forwardapp/views/truncated |    9 ++++++---app/views/truncated |   13 +++++++++++++app/views/truncated |    2 +-3 files changed, 20 insertions(+), 4 deletions(-)> git status# On branch master

长话短说,我的命令归结为:

git reset --hard HEAD^git reset --hard HEAD^git reset --hard HEAD^git reset --hard HEAD^git pull

我认为你可以做git rebase -i [hash] [branch_name],其中[hash]是标识哈希,无论你想倒回多少次加一(或者无论你想倒回多少次提交),然后删除编辑器中你不想要的提交行。保存文件。退出。祈祷。它应该被倒回。你可能需要做git reset --hard,但现在应该很好。你也可以用它来从堆栈中提取特定的提交,如果你不想把它们保留在你的历史记录中,但这会让你的存储库处于一种你可能不想要的状态。

假设你的本地主人没有领先于原点/主人,你应该能够做到

git reset --hard origin/<branch-name>

因此,假设您在master上执行了此操作,那么您的本地master分支应该看起来与origin/master相同。

Git书中的第4章原文作者:Linus Torvalds

要撤消合并已经被推了

git revert -m 1 commit_hash

如果您再次提交分支,请务必恢复恢复,就像Linus所说的那样。

只是为了一个额外的选项,我主要遵循这里描述的分支模型:http://nvie.com/posts/a-successful-git-branching-model/,因此通常与--no-ff合并(没有快进)。

我刚刚阅读了这个页面,因为我不小心将一个测试分支而不是我的发布分支与master合并用于部署(网站,master是实时的)。测试分支有另外两个分支合并到它,总共大约有六个提交。

因此,要恢复整个提交,我只需要一个git reset --hard HEAD^,它就恢复了整个合并。由于合并没有快速转发,合并是一个块,退后一步是“分支未合并”。

如果您的合并和相应的提交尚未推送,您可以随时切换到另一个分支,删除原始分支并重新创建它。

例如,我不小心将一个开发分支合并到master中,并想撤消它。使用以下步骤:

git checkout developgit branch -D mastergit branch -t master origin/master

瞧!师父与起源处于同一阶段,你的错误合并状态被擦除。

如果你还没有提交,你只能使用

$ git checkout -f

它将撤消合并(以及您所做的一切)。

  1. 首先,确保你已经承诺了一切。

  2. 然后将您的存储库重置为以前的工作状态:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36

    或使用--hard这将删除所有本地的、未提交的更改!):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard

    使用错误合并提交之前的哈希。

  3. 检查您想在之前正确版本的顶部重新提交哪些提交:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    ...
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    ...
  4. Apply your right commits on the top of the right version of your repository by:

    • By using cherry-pick (the changes introduced by some existing commits)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
    • Or by cherry-picking the range of commits by:

      • First checking the right changes before merging them:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
      • First checking the right changes before merging them:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f

        其中这是您提交的正确提交的范围(不包括错误提交的合并)。

奇怪的是,最简单的命令不见了。大多数答案都有效,但撤销你刚刚做的合并,这是最简单安全的方法

git reset --merge ORIG_HEAD

refORIG_HEAD将指向合并之前的原始提交。

--merge选项与合并无关。它就像git reset --hard ORIG_HEAD,但更安全,因为它不涉及未提交的更改。)

对于较新的Git版本,如果您还没有提交合并就会出现合并冲突,您可以简单地执行:

git merge --abort

man git merge

[this]只能在合并导致冲突后运行。git merge --abort将中止合并过程并尝试重建预合并状态。

如果你想要一个命令行解决方案,我建议直接使用MBO的答案。

如果您是新手,您可能会喜欢图形方法:

  1. 启动gitk(从命令行,或在文件浏览器中右键单击,如果有)
  2. 您可以在那里轻松发现合并提交-顶部的第一个节点有两个父节点
  3. 按照第一个/左父级的链接(合并前当前分支上的那个,通常对我来说是红色的)
  4. 在选定的提交上,右键单击“重置分支到这里”,在那里选择硬重置

您可以使用git reflog来查找上一个结帐。有时这是您想返回的好状态。

具体而言,

$ git reflog$ git reset --hard HEAD@{0}

您只能使用两个命令来恢复合并或通过特定提交重新启动:

  1. git reset --hard commitHash(您应该使用要重新启动的提交,例如。44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force(将新的本地master分支发送到源/master)

祝你好运,继续前进!

最近,我一直在使用git reflog来帮助解决这个问题。这通常只有在合并刚刚发生并且它在您的机器上时才有效。

git reflog可能会返回如下内容:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch43b6032 HEAD@{1}: checkout: moving from master to my-branche3753a7 HEAD@{2}: rebase finished: returning to refs/heads/mastere3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830eb41ea52 HEAD@{4}: reset: moving to HEAD^8400a0f HEAD@{5}: rebase: aborting

第一行表示发生了合并。第二行是我的合并之前的时间。我只是git reset --hard 43b6032强制这个分支从合并之前开始跟踪,然后继续。

使用现代Git,您可以:

git merge --abort

旧语法:

git reset --merge

老派:

git reset --hard

但实际上,值得注意的是,给定MERGE_HEAD存在,git merge --abort仅等效于git reset --merge。这可以在Git帮助合并命令中读取。

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在日常工作中更强大和有用,所以这是我一直使用的。

策略:从一切正常的地方创建一个新分支。

理由:撤销合并是困难的。解决方案太多了,这取决于很多因素,例如你是否已经提交或推了合并,或者自合并以来是否有新的提交。此外,你仍然需要对git有比较深刻的理解来使这些解决方案适应你的情况。如果你盲目地按照一些说明进行操作,你可能会得到一个“空合并”,任何东西都不会合并,进一步的合并尝试会让Git告诉你“已经更新了”。

解决方案:

假设您想将dev合并为feature-1

  1. 找到要接收合并的版本:

    git log --oneline feature-1a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undoe5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
  2. Check it out (go back in time):

    git checkout e5f6g7h8
  3. Create a new branch from there and check it out:

    git checkout -b feature-1

Now you can restart your merge:

  1. Merge: git merge dev

  2. Fix your merge conflicts.

  3. Commit: git commit

  4. When you're satisfied with the results, delete the old branch: git branch --delete feature-1

如果你注意到你需要在合并后立即恢复,并且在合并尝试后你没有做任何其他事情,你可以发出这个命令:git reset --hard HEAD@{1}.

本质上,如果在合并之后没有提交任何其他内容,则合并sha将指向HEAD@{0},因此HEAD@{1}将是合并之前的前一个点。

最简单的机会,比这里所说的要简单得多:

删除您的本地分支(本地,而不是远程)并再次拉取它。这样您将撤消主分支上的更改,任何人都将受到您不想推送的更改的影响。重新开始。

如果您提交合并:

git reset HEAD~1# Make sure what you are reverting is in fact the merge filesgit add .git reset --hard

遇到这个问题也希望恢复到匹配原点(即,在原点之前没有提交)。进一步研究,发现有一个reset命令可以做到这一点:

git reset --hard @{u}

注意:@{u}origin/master的简写。(当然,您需要远程存储库才能正常工作。)

最简单的答案是奥迪尼奥-维尔蒙特给出的

首先git reset --merge ORIG_HEAD

对于那些希望在推送更改后重置的人,请这样做(因为这是任何git重置合并问题的第一篇文章)

git push origin HEAD --force

这将以一种您不会在拉取后再次获得合并更改的方式重置。

在这种情况下,您将希望使用git reset --hard <branch_name>重置您的分支。如果您想在重置之前保存更改,请务必创建一个新分支和git checkout <branch_name>

您也可以使用git reset --hard <commit_id>将状态重置为特定的提交。

如果已推送更改,则可以使用git revert <branch_name>代替。请务必查看如何在其他场景中使用git恢复和git签出

我能够用一个不涉及查找提交ID的命令来解决这个问题。

git reset --hard remotes/origin/HEAD

接受的答案对我不起作用,但这个命令达到了我想要的结果。

如果你是在中间的合并你可以随时中止它

git merge --abort
  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

这对我有用…!!

它可以通过多种方式完成。

1)中止合并

如果你在一个坏的合并之间(错误地完成了错误的分支),并且想避免合并回到最新的分支,如下所示:

git merge --abort

2)将HEAD重置为远程分支

如果您从远程开发分支工作,您可以将HEAD重置为远程分支的最后一次提交,如下所示:

git reset --hard origin/develop

3)删除当前分支,并从远程存储库再次签出

考虑到您正在本地仓库中开发分支,与远程/开发分支同步,您可以执行以下操作:

git checkout master##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :)
git branch -D developgit checkout -b develop origin/develop

你必须改变你的头,当然不是你的,而是git head。

所以在回答之前,让我们添加一些背景,解释一下这个HEAD是什么。

First of all what is HEAD?

HEAD只是对当前分支上当前提交(最新)的引用。
在任何给定时间只能有一个HEAD(不包括git worktree

HEAD的内容存储在.git/HEAD中,它包含当前提交的40字节SHA-1。


detached HEAD

如果您不在最新的提交上-这意味着HEAD指向历史上的先前提交,则称为#1

在此处输入图片描述

在命令行上,它看起来像this-SHA-1而不是分支名称,因为HEAD没有指向当前分支的尖端

在此处输入图片描述

在此处输入图片描述

关于如何从分离的HEAD恢复的几个选项:


git checkout

git checkout <commit_id>git checkout -b <new branch> <commit_id>git checkout HEAD~X // x is the number of commits t go back

这将签出指向所需提交的新分支。
此命令将签出到给定的提交。
此时,您可以创建一个分支并从此开始工作。

# Checkout a given commit.# Doing so will result in a `detached HEAD` which mean that the `HEAD`# is not pointing to the latest so you will need to checkout branch# in order to be able to update the code.git checkout <commit-id>
# create a new branch forked to the given commitgit checkout -b <branch name>

git reflog

您也可以随时使用reflog
git reflog将显示更新了HEAD的任何更改,并签出所需的reflg条目将HEAD设置回此提交。

每次修改HEAD时,reflog中都会有一个新条目

git refloggit checkout HEAD@{...}

这将让你回到你想要的承诺

在此处输入图片描述


git reset --hard <commit_id>

“移动”你的头回到想要的提交。

# This will destroy any local modifications.# Don't do it if you have uncommitted work you want to keep.git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:git stashgit reset --hard 0d1d7fc32git stash pop# This saves the modifications, then reapplies that patch after resetting.# You could get merge conflicts if you've modified things which were# changed since the commit you reset to.

git revert <sha-1>

"撤消"给定的提交或提交范围。
重置命令将“撤消”在给定提交中所做的任何更改。
将提交带有撤消补丁的新提交,而原始提交也将保留在历史记录中。

# add new commit with the undo of the original one.# the <sha-1> can be any commit(s) or commit rangegit revert <sha-1>

这个模式说明了哪个命令做什么。
如你所见,reset && checkout修改HEAD

在此处输入图片描述

只需要创建新的分支,然后挑选所需的提交。

它的保存器和简单,然后重置描述了许多答案以上

回答问题“ 撤消尚未推送的 Git 合并

你可以使用 git reset --hard HEAD~1

考虑以下情况,其中有2个分支 师父第一部:


$ git log --graph --oneline --all

进行 Git 合并

$ git merge feature-1

$ git log --graph --oneline --all

撤消 Git 合并

$ git reset --hard HEAD~1

$ git log --graph --oneline --all

如果分支被合并而没有被推动,那么下面给出的 git 复位命令将会撤消合并:

git reset --merge ORIG_HEAD

例如:

git reset --merge origin/master

如无冲突及合并完成,则:

  git reset --hard HEAD~1

如果在进行合并的过程中发生了冲突,那么终止将使您退出最近的合并更改:

git merge --abort

或者如果您想恢复到特定的提交 ID。

 git reset --hard <commit-id>

使用此命令中止合并:

Git 合并,取消