4513

在我的 master 分支中,我在git merge some-other-branch本地做了一个,但从未将更改推送到 origin master。我不是要合并,所以我想撤消它。在git status合并后进行操作时,我收到了以下消息:

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

根据我找到的一些说明,我尝试运行

git revert HEAD -m 1

但现在我收到这条消息git status

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

我不希望我的分支领先于任何数量的提交。我如何回到那个点?

4

33 回答 33

5161

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

git reset --hard commit_sha

还有另一种方式:

git reset --hard HEAD~1

它会让你回到 1 次提交。

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


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

git reset --hard ORIG_HEAD

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


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

git reset --merge ORIG_HEAD

- 合并

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

于 2010-03-05T19:34:01.440 回答
1604

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

git reset --hard origin/master

然后您的本地master分支应该看起来与origin/master.

于 2011-03-17T18:06:06.707 回答
1223

请参阅Git 书籍的第 4 章和Linus Torvalds 的原始帖子

要撤消已推送的合并:

git revert -m 1 commit_hash

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

于 2011-06-02T16:31:43.723 回答
1087

奇怪的是缺少最简单的命令。大多数答案都有效,但撤消您刚刚所做的合并,这是一种简单而安全的方法

git reset --merge ORIG_HEAD

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

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

于 2013-01-29T15:46:35.217 回答
444

对于较新的 Git 版本,如果您尚未提交合并并且您有合并冲突,您可以简单地执行以下操作:

git merge --abort

来自man git merge

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

于 2013-02-12T02:13:29.667 回答
155

您应该重置为之前的提交。这应该有效:

git reset --hard HEAD^

甚至HEAD^^可以还原该还原提交。如果您不确定应该退后多少步,您可以随时提供完整的 SHA 参考。

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

于 2010-03-05T19:31:35.517 回答
97

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

git reflog可能会返回类似:

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

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

于 2014-12-19T17:51:41.017 回答
60

如果您正在合并,您可以随时中止它

git merge --abort
于 2018-12-13T14:05:05.817 回答
57

使用现代 Git,您可以:

git merge --abort

旧语法:

git reset --merge

老套:

git reset --hard

但实际上,值得注意的是,thatgit merge --abort仅相当于git reset --mergegiven that MERGE_HEADis present。这可以在合并命令的 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在日常工作中更加强大和有用,所以这是我一直使用的。

于 2015-05-08T19:13:44.067 回答
40

好的,这里其他人给我的答案很接近,但它不起作用。这就是我所做的。

这样做...

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 pull
Updating 2df6af4..12bbd2f
Fast forward
 app/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
于 2010-03-05T19:54:06.280 回答
40

如果分支被合并而不被推送,那么下面给出的 git reset 命令将用于撤消合并:

git reset --merge ORIG_HEAD

例子:

git reset --merge origin/master
于 2020-10-09T05:41:29.367 回答
35

你必须改变你的 HEAD,当然不是你的,而是 git HEAD....

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

First of all what is HEAD?

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

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


detached HEAD

如果您不在最新提交上 - 意思HEAD是指向历史上的先前提交,则称为detached HEAD.

在此处输入图像描述

在命令行上,它看起来像这样 - 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 commit
git checkout -b <branch name>

git reflog

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

每次修改 HEAD 都会在reflog

git reflog
git checkout HEAD@{...}

这将使您回到所需的提交

在此处输入图像描述


git reset --hard <commit_id>

将您的 HEAD “移动”回所需的提交。

# 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 stash
git reset --hard 0d1d7fc32
git 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 range
git revert <sha-1>

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

在此处输入图像描述

于 2019-07-31T15:38:02.270 回答
25

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

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 develop
git checkout -b develop origin/develop
于 2019-07-25T15:06:40.740 回答
23

您可以使用git reflog查找以前的结帐。有时那是你想要回到的一个很好的状态。

具体来说,

$ git reflog
$ git reset --hard HEAD@{0}
于 2014-01-17T22:36:18.347 回答
20

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

git reset --hard remotes/origin/HEAD

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

于 2018-07-25T09:55:26.373 回答
15

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

$ git checkout -f

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

于 2013-01-18T15:25:37.117 回答
15

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

git reset --hard @{u}

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

于 2017-02-16T21:54:41.200 回答
12

最简单的答案是 odinho - Velmont 给出的答案

先做git reset --merge ORIG_HEAD

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

git push origin HEAD --force

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

于 2017-11-02T23:22:26.397 回答
11

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

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

祝你好运,继续前进!

于 2014-12-12T23:16:56.883 回答
10

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

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

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

于 2011-06-09T00:54:52.290 回答
10

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

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

考虑以下情况,其中有 2 个分支masterfeature-1


$ 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

于 2020-08-18T07:12:50.207 回答
8

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

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

git checkout develop
git branch -D master
git branch -t master origin/master

瞧!Master与origin处于同一阶段,并且您的错误合并状态被擦除。

于 2012-06-26T11:15:48.300 回答
5

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

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

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

策略:创建一个新的分支,一切都很好。

理由:恢复合并很难。有太多的解决方案,这取决于许多因素,例如您是否已提交或推送您的合并,或者自合并后是否有新的提交。此外,您仍然需要对 git 有比较深入的了解才能使这些解决方案适应您的情况。如果你盲目地遵循一些说明,你最终可能会得到一个“空合并”,其中不会合并任何内容,进一步的合并尝试会让 Git 告诉你“已经是最新的”。

解决方案:

假设您要合并devfeature-1.

  1. 找到要接收合并的修订:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. 检查一下(及时返回):

    git checkout e5f6g7h8
    
  3. 从那里创建一个新分支并检查它:

    git checkout -b feature-1
    

现在您可以重新开始合并:

  1. 合并:git merge dev

  2. 修复合并冲突。

  3. 犯罪:git commit

  4. 当您对结果感到满意时,删除旧分支:git branch --delete feature-1

于 2015-06-11T15:42:41.007 回答
5

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

它的保护程序和简单的然后重置在上面的许多答案中描述

于 2019-08-15T13:41:11.220 回答
3

我认为您可以在git rebase -i [hash] [branch_name] 哪里[hash]确定您想要倒退的距离加上一个(或者您想要返回多少次提交)的识别哈希,然后在编辑器中删除您不再想要的提交的行. 保存文件。出口。祈祷。它应该被重绕。你可能需要做 a git reset --hard,但在这一点上应该很好。如果您不想将它们保留在历史记录中,您也可以使用它从堆栈中提取特定提交,但这可能会使您的存储库处于您可能不想要的状态。

于 2010-03-08T02:55:58.307 回答
1
  1. 首先,确保你已经承诺了一切。

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

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

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

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

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

  3. 通过以下方式检查您想在先前正确版本的顶部重新提交哪些提交:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. 通过以下方式将正确的提交应用到存储库的正确版本的顶部:

    • 通过使用cherry-pick(一些现有提交引入的更改)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • 或者通过以下方式挑选提交范围:

      • 在合并它们之前首先检查正确的更改:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • 在合并它们之前首先检查正确的更改:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

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

于 2013-01-29T15:09:00.540 回答
1

如果您提交了合并:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard
于 2016-11-10T15:57:30.533 回答
1
  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

这对我有用..!!

于 2019-03-15T05:53:26.793 回答
0

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

本质上,您的合并sha将指向合并HEAD@{0}后是否未提交任何其他内容,因此HEAD@{1}将是合并前的前一点。

于 2016-04-26T18:52:23.803 回答
0

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

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

于 2016-07-15T14:16:03.377 回答
0

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

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

如果更改已被推送,您可以使用git revert <branch_name>。请务必查看如何在其他场景中使用git revert 和 git checkout 。

于 2018-05-29T10:21:05.840 回答
-14

您可以使用 git-reset 命令。

git-reset - 将当前 HEAD 重置为

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

--软 | --硬 | --merge] [-q] [] git 重置 [-q] []

[--] ... git reset --patch

[] [--] […]

GIT-重置

于 2010-03-05T19:28:19.723 回答