撤消尚未推送的Git合并
在我的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楼
首先,请确保您已完成所有工作。
-
然后将您的存储库重置为先前的工作状态:
$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
或使用
--hard
( 这将删除所有本地未提交的更改! ):$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
使用错误合并的提交之前的哈希值。
-
通过以下方法在先前的正确版本上检查您要重新提交的提交:
$ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f ... commit 16b373a96b0a353f7454b141f7aa6f548c979d0a ...
-
通过以下方式将正确的提交应用于正确版本的存储库顶部:
-
通过使用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的回答。
如果您是新手,则可能会喜欢图形方法:
- 启动
gitk
(从命令行启动,或者在文件浏览器中右键单击) - 您可以轻松地在此处发现合并提交-顶部有两个父节点的第一个节点
- 单击链接到第一个/左父级(合并之前您当前分支中的那个,对我来说通常是红色的)
- 在选定的提交上,右键单击“将分支重置到此处”,在此处选择硬重置
#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 reflog
比git 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楼
您只能使用两个命令来还原合并或通过特定的提交重新启动:
-
git reset --hard commitHash
(您应该使用要重新启动的提交,例如44a587491e32eafa1638aca7738) -
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 --merge
, 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 reset --merge
起来更强大,更有用,所以我一直使用它。
#15楼
策略:从一切都很好的地方创建一个新分支。
理由:恢复合并非常困难。 解决方案太多,取决于许多因素,例如您是否已提交或推送了合并,或者自合并以来是否有新的提交。 同样,您仍然需要对git有相对深入的了解,以使这些解决方案适合您的情况。 如果您盲目地遵循一些说明,则可以得到“空合并”,其中什么都不会合并,并且进一步的合并尝试将使Git告诉您“已经是最新的”。
解:
假设您要将dev
合并到feature-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
-
签出(回到过去):
git checkout e5f6g7h8
-
从那里创建一个新分支并签出:
git checkout -b feature-1
现在,您可以重新启动合并:
合并:
git merge dev
解决您的合并冲突。
提交:
git commit
对结果满意后,请删除旧分支:
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楼
-
git stash
-
git branch -d the_local_branch
-
git checkout -t <name of remote>
-
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
。
在命令行上,它看起来像这样-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 aaa@qq.com{...}
这将使您回到所需的提交
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
。
#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^
还原整个合并。 由于合并不快进,因此合并是一个块,而后退一步是“分支未合并”。