【问题标题】:Rollback a Git merge回滚 Git 合并
【发布时间】:2012-07-28 04:22:06
【问题描述】:
develop branch
--> dashboard (working branch)

我使用git merge --no-ff develop 将任何上游更改合并到仪表板中

git 日志:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <root@magneto.giveforward.com>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

合并中有大约 50 多个提交,我想知道如何恢复合并,以便仪表板回到合并前的状态

第二部分是,如果我不与 --no-ff 合并,我不会得到提交 '​​Merge branch 'develop' into dashboard' .. 我将如何滚动它合并回来?

【问题讨论】:

标签: git


【解决方案1】:

只需使用git reset --hard HEAD^ 重置合并提交。

如果你使用 --no-ff git 总是会创建一个合并,即使你没有在两者之间提交任何东西。如果没有 --no-ff git 只会快进,这意味着您的分支 HEAD 将设置为合并分支的 HEAD。要解决此问题,请找到您要恢复的提交 ID 和 git reset --hard $COMMITID

【讨论】:

  • 如果您在合并之前不知道提交,这是一个很好的解决方案。
  • 为我工作,因为我不知道提交 ID。+1
  • 如果不需要的合并已经提交到远程,我使用 git push -f 在恢复后更新远程分支。
【解决方案2】:

other questions. 已经详尽地介绍了恢复合并提交。当您进行快进合并时,您描述的第二个合并,您可以使用 git reset 回到之前的状态:

git reset --hard <commit_before_merge>

您可以通过git refloggit log 找到&lt;commit_before_merge&gt;,或者,如果您感觉很混乱(并且没有做任何其他事情):git reset --hard HEAD@{1}

【讨论】:

  • 感谢您的快速回复..查看 git log,合并前的提交是 50+ 次提交,因为 git merge develop 实际上放入了所有其他提交。我想我没有得到的是,如果我不知道合并是什么/在哪里 - 我怎么找到它?你提到找到 commit_before_merge .. 我想我不理解那部分
  • 看起来像 git reflog 看起来它很好地总结了最后一个头,并让我知道我需要重置到哪里。 git log 似乎粒度太大,无法确定要重置的位置。谢谢
  • 是的,reflog 是救命稻草。 HEAD@{1} 只是描述了 HEAD 的第二个最近状态,或者更专业地说:“后缀 @ 的 ref 和括在大括号对中的序数规范(例如 {1}、{15})指定第 n 个先验该参考的价值。”
  • 如何将还原推送到远程?我不知道它会如何工作。
  • 这是没有希望的。它会在合并后销毁所有提交。
【解决方案3】:
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

但可能会有意想不到的副作用。请参阅git-scm.com/docs/git-revert 中的--mainline parent-number 选项

也许一种粗暴但有效的方法是检查该提交的左父级,复制所有文件,再次检查HEAD,然后用旧文件替换所有内容。然后 git 会告诉你正在回滚什么,然后你创建自己的还原提交:)!

【讨论】:

  • +1 因为这个答案不会像重置那样混淆历史(如果你已经推送到远程,这真的很重要)。但是我应该预料到什么意外的副作用?
  • 这是你提到的副作用吗? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
  • 你说git reset 是解决方案,但也提到它可能有意想不到的副作用。但是,该链接来自git revert,而不是git reset :)
  • 请注意,git reset 没有 -m 标志。另请注意@JorgeOrpinel 引用了 git-revert 文档,而不是 git-reset。我认为他的意思是说git revert 而不是git reset
  • 如何避免指定主线但提交1234xyz不是合并错误。
【解决方案4】:

从这里开始:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git revert 添加一个回滚指定提交的新提交。

使用-m 1 告诉git这是一个合并,我们想回滚到主分支上的父提交。您可以使用-m 2 来指定开发分支。

【讨论】:

  • 请注意,在此之后您不能重新合并分支,因为文档说:“恢复合并提交声明您永远不希望合并带来的树更改。因此,稍后合并只会引入不是先前还原合并的祖先的提交引入的树更改。这可能是也可能不是你想要的。"
  • @DaliborKarlović 这句话有点苛刻。您绝对可以稍后恢复这些更改,诀窍是恢复还原提交。更多信息here 在“还原还原”部分中
  • 遗憾的是,@Hilikus 评论中的here 链接不再有效。该网站声称内容已移至一本书(git-scm.com/book/en/v2),但如果是这样,那么在其中定位并非易事。
  • @DaliborKarlović 上面的答案来自@Christopher?
  • 撤消合并内容已移至here
【解决方案5】:

如果您合并了分支,则使用拉取请求恢复合并,并合并该拉取请求以恢复。

我觉得最简单的方法是:

  1. 从develop/master(您合并的地方)取出一个新分支
  2. 使用git revert -m 1 xxxxxx(如果还原是使用分支合并)或git revert xxxxxx(如果是简单还原)还原“还原”
  3. 新分支现在应该包含您要再次合并的更改。
  4. 对此分支进行更改或合并到develop/master

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-18
    • 2012-08-07
    • 2011-06-12
    • 1970-01-01
    • 2012-04-29
    • 2023-03-25
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多