欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

撤消尚未推送的Git合并

程序员文章站 2022-05-04 11:01:17
...

在我的master分支中,我在本地进行了git merge some-other-branch ,但从未将更改推送到原始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.

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


#1楼

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

例如,我无意中将一个开发分支合并到master中,并希望撤消该操作。 使用以下步骤:

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

瞧! 母版与原点处于同一阶段,并且您误合并的状态将被清除。


#2楼

如果您尚未提交,则只能使用

$ git checkout -f

它将撤消合并(以及您所做的所有操作)。


#3楼

  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 

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


#4楼

最简单的命令丢失了很奇怪。 大多数答案都有效,但是撤消您刚才所做的合并, 这是简单安全的方法

git reset --merge ORIG_HEAD

引用ORIG_HEAD将指向合并之前的原始提交。

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


#5楼

使用较新的Git版本,如果您尚未提交合并,但是发生合并冲突 ,则可以执行以下操作:

git merge --abort

来自man git merge

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


#6楼

如果您需要命令行解决方案,我建议您只听MBO的回答。

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

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

#7楼

您可以使用git reflog查找先前的结帐。 有时候,这是您想要返回的良好状态。

具体来说,

$ git reflog
$ git reset --hard aaa@qq.com{0}

#8楼

您应该重置为上一次提交。 这应该工作:

git reset --hard HEAD^

甚至HEAD^^可以还原该还原提交。 如果您不确定应该返回多少步骤,可以始终提供完整的SHA参考。

万一遇到问题,而master分支没有任何本地更改,则可以重置为origin/master


#9楼

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

git reset --hard commit_sha

还有另一种方法:

git reset --hard HEAD~1

它将使您退回1次提交。

请注意,任何已修改和未提交/未破坏的文件都将重置为其未修改状态 。 要保留它们,可以--merge更改,或参见下面的--merge选项。


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

git reset --hard ORIG_HEAD

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


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

git reset --merge ORIG_HEAD

- 合并

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


#10楼

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

这样做...

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

#11楼

我认为您可以执行git rebase -i [hash] [branch_name] ,其中[hash]是要倒带的git rebase -i [hash] [branch_name]加上一个(或想倒回的提交数)的标识性哈希,然后删除以下行在编辑器中提交您不再想要的内容。 保存文件。 出口。 祈祷。 应该倒退。 您可能必须执行git reset --hard ,但此时应该很好。 如果您不想将特定的提交保留在历史记录中,则还可以使用它从堆栈中拉出特定的提交,但这会使您的存储库处于您可能不希望的状态。


#12楼

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

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

祝你好运,继续前进!


#13楼

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

git reflog可能返回类似以下内容:

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

第一行表示发生了合并。 第二行是我合并之前的时间。 我只是git reset --hard 43b6032强制该分支从合并和随身携带之前跟踪。


#14楼

使用现代Git,您可以:

git merge --abort

较旧的语法:

git reset --merge

老套:

git reset --hard

但实际上,值得注意的是, MERGE_HEAD存在git reset --mergegit 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 reset --merge起来更强大,更有用,所以我一直使用它。


#15楼

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

理由:恢复合并非常困难。 解决方案太多,取决于许多因素,例如您是否已提交或推送了合并,或者自合并以来是否有新的提交。 同样,您仍然需要对git有相对深入的了解,以使这些解决方案适合您的情况。 如果您盲目地遵循一些说明,则可以得到“空合并”,其中什么都不会合并,并且进一步的合并尝试将使Git告诉您“已经是最新的”。

解:

假设您要将dev合并到feature-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


#16楼

如果您发现您需要在合并后立即还原,并且在合并尝试之后没有执行任何其他操作,则可以发出以下命令: git reset --hard aaa@qq.com{1}

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


#17楼

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

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


#18楼

如果您提交了合并:

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

#19楼

遇到此问题时,也希望还原为匹配原点(即,在原点之前没有提交)。 进一步研究,发现有一个确切的reset命令:

git reset --hard @{u}

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


#20楼

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

首先做git reset --merge ORIG_HEAD

对于那些希望在更改后重新设置的人,请执行此操作(因为这是所有git reset merge问题看到的第一篇文章)

git push origin HEAD --force

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


#21楼

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

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

如果更改已被推送,则可以改用git revert <branch_name> 。 一定要检查出在其他情况下如何使用git revert和git checkout


#22楼

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

git reset --hard remotes/origin/HEAD

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


#23楼

假设您的本地主人不在原产地/主人之前,那么您应该能够

git reset --hard origin/master

然后,您的本地master分支应该看起来与origin/master相同。


#24楼

如果您正在合并中,则可以随时中止git merge --abort


#25楼

  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

这对我有用.. !!


#26楼

可以通过多种方式完成。

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

#27楼

您必须更改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

撤消尚未推送的Git合并

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

撤消尚未推送的Git合并

撤消尚未推送的Git合并

有关如何从分离的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 aaa@qq.com{...}

这将使您回到所需的提交

撤消尚未推送的Git合并


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 2.7起
    您也可以使用git rebase --no-autostash

git revert <sha-1>

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

# 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

撤消尚未推送的Git合并


#28楼

只需创建新分支,然后选择所需的提交即可。

它的保护程序和重置操作更加简单,如上文许多答案所述


#29楼

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

撤消已经推送的合并:

git revert -m 1 commit_hash

如果您再次提交分支,请确保还原还原,如Linus所说。


#30楼

只是为了查看其他选项,我主要遵循此处描述的分支模型: http//nvie.com/posts/a-successful-git-branching-model/ ,因此,它与--no-ff通常--no-ff (不快进)。

我刚读完此页面,是因为我不小心将测试分支而不是发布分支与master合并以进行部署(网站,master是实时的)。 测试分支还有另外两个分支与之合并,总计约六次提交。

因此,要还原整个提交,我只需要一个git reset --hard HEAD^还原整个合并。 由于合并不快进,因此合并是一个块,而后退一步是“分支未合并”。