7

合并分支后,发现合并错了分支。
master上还没有提交任何东西,想取消这次合并,让分支回到位,肿么办?

好在现在还没commit另外的内容,如果不小心commit了,那又该怎么办啊?

小哥 412
2012-11-14 提问
9 个回答
14

已采纳

git 到底是个多么奇葩的管理工具,一个问题能有这么多解释,一眼还不出来那个是对的。
http://git-scm.com/blog/2010/03/02/undoing-merges.html 这是官方的解答,待我看完,在此翻译一下。

======================简单翻译开始====================

由于太多人问怎么撤销 merge 了,于是 git 官方出了这份教程,表示在 git 现有的思想体系下怎么达到撤销 merge 的目标。

方法一,reset 到 merge 前的版本,然后再重做接下来的操作,要求每个合作者都晓得怎么将本地的 HEAD 都回滚回去:

$ git checkout 【行merge操作时所在的分支】
$ git reset --hard 【merge前的版本号】

方法二,当 merge 以后还有别的操作和改动时,git 正好也有办法能撤销 merge,用 git revert:

$ git revert -m 【要撤销的那条merge线的编号,从1开始计算(怎么看哪条线是几啊?)】 【merge前的版本号】
Finished one revert.
[master 88edd6d] Revert "Merge branch 'jk/post-checkout'"
 1 files changed, 0 insertions(+), 2 deletions(-)

这样会创建新的 commit 来抵消对应的 merge 操作,而且以后 git merge 【那个编号所代表的分支】 会提示:

Already up-to-date.

因为使用方法二会让 git 误以为这个分支的东西都是咱们不想要的。

方法三,怎么撤销方法二:

$ git revert 【方法二撤销merge时提交的commit的版本号,这里是88edd6d】
Finished one revert.
[master 268e243] Revert "Revert "Merge branch 'jk/post-checkout'""
 1 files changed, 2 insertions(+), 0 deletions(-)

这样就行了,可以正常 merge 了,不过可能会有很多冲突噢!!

$ git merge jk/post-checkout
Auto-merging test.txt
Merge made by recursive.
 test.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

=====================简单翻译结束====================

最后的最后,还是觉得顶上那些都麻烦爆了。前端天天用 WebStorm 写代码的看过来: WebStorm 右键点击项目文件或文件夹,有一个:

Local History -> Show History

点开后出现一个窗口,可以看到所有的本地改动。找到合适的那份,按左上角那个:

Revert

按钮,也就是个紫色的弯曲的小箭头就回去了。在文件量不大的时候十分管用,强烈推荐。

10

如果确定放弃这次合并的提交,假如是 merge 了错误的分支到 master,先通过 git reflog 或者 gitg、gitk、qgit 等工具确定你 merge 之前 master 所在的 commit,然后在 master 分支上使用 git reset --hard <commit> 重置头指针。一般来说,在 master 上直接执行 git reset --hard HEAD~ 也可以回到合并之前的提交,但 git reset --hard 命令还是使用确定的 commit 为好。注意,git reset --hard 命令有风险,除非十分确定要放弃当前提交,否则最好先 git branch 为当前的提交建立个新的分支引用后再继续,待确定无误后删除即可。

如果错误的合并之后又有了新的提交,可以在完成前述正确的合并之后,通过 git rebase --onto <错误的合并提交> <正确的合并提交> <新提交所在分支> 来在正确的合并提交上重建新的提交。git rebase --onto 命令所重建的提交序列最好是线性的,否则非线性的提交会变成线性的。若需要保存非线性的提交历史,可以考虑使用 --preserve-merges 参数,不过结果很不可靠,具体视提交的非线性程度而定。

5

合并时遇到冲突想取消操作,恢复index,用git merge --abort
git reset --hard 可以回退到某个提交
git revert可以撤销某个提交,撤销会产生一个新的提交

git rebase还木有仔细研究过。

1

喜欢字少的答案

lynnic89 · 2017年06月30日

添加评论
1

我想这里应该是需要 git merge --abort 吧

0

B-R-A-N-C-H
/ \--Merge
M-A-S-T-E-R----M

你用git reset --hard R的哈希值, 退回到R就 可以了。 从 Merge过后的M 退回到R。

0
1

日期:2008年12月19日星期五00:45:19 -0800
来自:Linus Torvalds <torvalds@linux-foundation.org>,Junio C Hamano <gitster@pobox.com>
主题:回复:涉及回复的奇怪的合并行为
摘要:有时候一个已经合并到主线的分支
后来发现是有缺陷的。Linus和Junio给出指导
从这样的过早合并和持续发展中恢复过来
违规分支得到修复后。
Message-ID:<7vocz8a6zk.fsf@gitster.siamese.dyndns.org>
参考文献:<alpine.LFD.2.00.0812181949450.14014@localhost.localdomain>

Alan <alan@clueserver.org>说:

我有一个主分支。我们有一个分支,那一些
开发人员正在开展工作。他们声称已经准备好了。我们合并它
进入主分支。它打破了一些东西,所以我们恢复合并。
他们修改代码。他们得到了他们说的一个点
没关系,我们再次合并。

在检查时,我们发现在还原之前进行的代码更改是
不在主分支中,而是在主分支后进行代码更改
科。

并要求从这种情况中恢复。

陈圈圈 · 2017年12月13日

展开评论
0

使用gitk --all图形界面, 修改各个branch分支名, 例如改为branch_backup, 然后创建新的分支, 分支名就是你要恢复的原始分支名, 一切就恢复到自己出错之前的状态啦

0

Git本地没有提交(包括没有执行add或commit操作的代码)却被还原(merge),找回本地文件记录的方法:
【phpstorm】右键【项目根目录】-Git-Repository-Unstash Changes,出现以下界面,选择需要还原的时间节点 点击Apply Stash按钮即可。
图片描述
此方法能找回 没有执行add或commit操作的代码。

-2

git checkout .

撰写答案

推广链接