撤消尚未推送的Git合并
在我的主分支中,我做了一个git merge some-other-branch
在本地git merge some-other-branch
,但从未将更改推送到原始主。 我不是想要合并,所以我想撤销它。 当我合并后做一个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.
我不希望我的分支在任何次数的提交之前。 我该如何回到这一点?
用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
,它不会不必要地重置文件:
– 合并
重置索引并更新工作树中<commit>和HEAD之间不同的文件,但保留索引和工作树之间不同的文件(即没有添加更改的文件)。
假设你的本地主人没有超过出身/主人,你应该可以做到
git reset --hard origin/master
那么你的本地master
分支应该看起来相同的origin/master
。
请参阅Git书中的第4章和 Linus Torvalds的原始文章 。
要撤消已经推送的合并:
git revert -m 1 commit_hash
像Linus说的那样,如果你再次投入分支,一定要恢复回复。
奇怪的是最简单的命令丢失了。 大多数答案都可以工作,但是取消刚才的合并, 这是一个简单而安全的方法 :
git reset --merge ORIG_HEAD
参考ORIG_HEAD
将指向合并之前的原始提交。
( --merge
选项与merge没有任何关系,就像git reset --hard ORIG_HEAD
,但更安全,因为它不会触及未提交的更改。)
使用更新的Git版本,如果您尚未提交合并, 并且发生合并冲突 ,则可以简单地执行以下操作:
git merge --abort
从man git merge
:
只有在合并导致冲突后才能运行。
git merge --abort
将中止合并过程,并尝试重build合并前的状态。
你应该重置到以前的提交。 这应该工作:
git reset --hard HEAD^
甚至HEAD^^
恢复恢复提交。 如果您不确定您应该采取多less步骤,则可以始终提供完整的SHA参考。
如果遇到问题并且主分支没有任何本地更改,则可以重置为origin/master
。
最近,我一直在使用git reflog
来解决这个问题。 这大多只适用于合并JUST发生,并且它在您的机器上。
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
强制这个分支从合并之前跟踪,并且继续。
用现代的Git,你可以:
git merge --abort
较老的语法:
git reset --merge
老套:
git reset --hard
但实际上,值得注意的是, git merge --abort
只相当于git reset --merge
因为MERGE_HEAD
存在。 这可以在合并命令的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 --hard HEAD^ git status
给我以下状态
# On branch master # Your branch and 'origin/master' have diverged, # and have 3 and 3 different commit(s) each, respectively.
然后,我不得不再次input相同的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
您可以使用git reflog
来查找以前的结帐。 有时候,这是一个你想要返回的好状态。
具体而言,
$ git reflog $ git reset --hard HEAD@{0}
如果你还没有提交,你只能使用
$ git checkout -f
这将撤消合并(以及你所做的一切)。
只是为了一个额外的选项来看,我一直在主要遵循这里描述的分支模型: http : //nvie.com/posts/a-successful-git-branching-model/ ,因此已经合并--no-ff
(通常不会快进)。
我刚刚阅读这个页面,因为我不小心合并了一个testing分支,而不是我的发布分支与主人部署(网站,主人是什么是生活)。 testing分支还有两个分支合并在一起,总计大概有六个提交。
所以要恢复整个提交,我只需要一个git reset --hard HEAD^
并且它恢复了整个合并。 由于合并不是快速转发合并是一个块,退一步是“分支不合并”。
您只能使用两个命令来恢复合并或通过特定的提交重新启动:
-
git reset --hard commitHash
(你应该使用你想重启的提交,例如44a587491e32eafa1638aca7738) -
git push origin HEAD --force
(将新的本地主分支发送到origin / master)
祝你好运,继续前进!
有这个问题也希望恢复到匹配的原点(即NO提交原点之前)。 进一步研究,发现有一个reset
命令完全是这样的:
git reset --hard @{u}
注意: @{u}
是origin/master
简写。 (当然,你需要这个远程仓库才能工作。)
如果您的合并和相应的提交没有被推送,您可以随时切换到另一个分支,删除原来的并重新创build它。
例如,我不小心将一个开发分支合并到了master中,并想撤销这个分支。 使用以下步骤:
git checkout develop git branch -D master git branch -t master origin/master
瞧! 师父与起源同一个阶段,你的错误合并的状态被抹去了。
如果你想要一个命令行的解决scheme,我build议去MBO的答案。
如果你是一个新手,你可能会喜欢graphics方法:
- 启动
gitk
(从命令行,或右键单击文件浏览器,如果你有) - 您可以很容易地发现合并提交 – 第一个与父母的顶部节点
- 按照链接到第一个/左父母(合并前的当前分支上的一个,通常是红色的)
- 在所选提交上,右键单击“重置分支到这里”,select那里的硬重置
策略:从一切都很好的地方创build一个新的分支。
理由:恢复合并很困难。 有太多的解决scheme,取决于许多因素,如您是否已经承诺或推动您的合并,或自合并以来是否有新的提交。 你还需要对git有相当深入的理解,才能将这些解决scheme应用于你的案例。 如果你盲目地遵循一些指示,你可能会得到一个“空的合并”,没有任何合并,进一步的合并尝试将使Git告诉你“已经最新”。
解:
假设你想把dev
合并到feature-1
。
-
find您想要接收合并的修订:
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
-
从那里创build一个新的分支,并检查出来:
git checkout -b feature-1
现在你可以重新开始你的合并:
-
合并:
git merge dev
-
修复你的合并冲突。
-
提交:
git commit
-
当你对结果满意时,删除旧的分支:
git branch --delete feature-1
我知道这不是对这个问题的直接回应,但是考虑到这个问题对于存储库的历史有多复杂,我想分享我的经验,并让每个人都知道在合并之前从上次提交创build一个新的分支是一个很好的select,主要是当合并已经推动。
我认为你可以做git rebase -i [hash] [branch_name]
其中[hash]
是标识哈希值,然后你想要回退再加上一个(或者不pipe多less提交你想要的),然后删除行在编辑器中的提交,你不想再想了。 保存文件。 出口。 祈祷。 它应该被倒回。 你可能不得不做一个git reset --hard
,但是在这一点上应该很好。 如果你不想把它们保存在你的历史logging中,你也可以使用它来将特定的提交拉出堆栈,但是这会使你的存储库处于你可能不想要的状态。
-
首先,确保你所做的一切。
-
然后重置您的存储库到以前的工作状态:
$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
或使用
--hard
( 这将删除所有本地,没有承诺的变化! ):$ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
使用错误合并提交之前的散列。
-
通过以下方式检查您想要在以前的正确版本的顶部重新提交哪些提交:
$ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f ... commit 16b373a96b0a353f7454b141f7aa6f548c979d0a ...
-
通过以下方式在正确的版本库顶部应用您的正确提交:
-
通过使用樱桃挑选(一些现有的提交引入的变化)
git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
-
或者通过以下途径挑选承诺的范围:
-
在合并前先检查正确的更改:
git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
-
在合并前先检查正确的更改:
git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
这是你所提交的正确提交的范围(不包括错误承诺的合并)。
-
-
如果你注意到你需要在合并之后立即恢复,而在合并尝试之后你还没有做任何其他的事情,你可以发出这个命令: git reset --hard HEAD@{1}
。
从本质上讲,如果在合并之后没有其他提交,你的merge sha
将指向HEAD@{0}
,因此HEAD@{1}
将是合并之前的前一个点。
最简单的机会,比这里所说的更简单:
删除本地分支(本地,不是远程),然后再次拔出。 通过这种方式,您将撤销主分支上的更改,任何人都将受到您不想推送的更改的影响。 重新开始
如果你犯了合并:
git reset HEAD~1 # Make sure what you are reverting is in fact the merge files git add . git reset --hard
最简单的答案就是odinho – Velmont给出的答案
首先做git reset --merge ORIG_HEAD
对于那些希望在更改推后重置,这样做(因为这是任何git重置合并问题看到的第一个post)
git push origin HEAD --force
这将重置一个方式,你将不会得到合并的变化后,再次拉。
你可以使用git-reset命令。
git-reset – 将当前HEAD重置为
指定状态。 git reset [–mixed |
–soft | –hard | –merge] [-q] [] git reset [-q] []
[ – ] … git reset –patch
[] [ – ] […]
GIT复位