【问题标题】:Revert a merge after being pushed推送后恢复合并
【发布时间】:2012-09-14 02:23:19
【问题描述】:

我执行的步骤:

我有两个分支branch1和branch2,

$git branch --Initial state
$branch1

$git checkout branch2
$git pull origin branch1 --Step1

我解决了冲突并做了一个

$git commit -m "Merge resolved"

然后

$git checkout branch1
$git merge branch2
$git push origin branch1

现在我意识到,在第 1 步时,自动合并删除了一些代码并推送了更改代码,现在我想回到我的初始状态以恢复任何更改。需要立即帮助吗?

【问题讨论】:

  • git revert 不会做你想做的事吗?
  • 它给出的消息为:致命:提交 b4a758b36a5bde9311061fe7b56e4f47859de052 是一个合并,但没有给出 -m 选项。 @FrederickCheung
  • 查看有关 -m 选项的手册。 kernel.org/pub/software/scm/git/docs/git-revert.html 很快您就可以使用 -m 1 或 -m 2。这将选择您要恢复到两个父版本中的哪一个。
  • 是的,我使用了 git revert -m 1 SHA,现在所有的更改都是在我的本地提交的,
  • vim 出现错误,在还原操作时退出它,我运行 git config --global core.editor /usr/bin/vim 并解决了问题,然后还原成功运行到解决问题。谢谢

标签: git git-revert


【解决方案1】:

尝试使用git reflog <branch> 找出您的分支在合并之前的位置,并尝试使用git reset --hard <commit number> 来恢复旧版本。

Reflog 将向您显示分支的旧状态,因此您可以将其返回到您喜欢的任何更改集。

使用 git reset 时请确保您在正确的分支中

要更改远程存储库历史记录,您可以使用git push -f,但不建议这样做,因为有人可能已经下载了由您推送的更改。

【讨论】:

  • 我已经将代码推送到远程分支,这将如何从那里恢复代码..
  • 如果你已经推送了,你不想像 Ilya 描述的那样重写本地历史
  • 对不起,我错过了那个东西......有时你可以使用 git push -f 来重写远程历史。这取决于您的远程存储库配置和其他团队成员(如果他们不会因为强制推送而杀死您)。
【解决方案2】:

您可以在official guide 之后恢复合并,但这会使 Git 错误地认为合并的提交仍在目标分支上。

基本上你必须:

git revert -m 1 (Commit id of the merge commit)

【讨论】:

  • 应该小心1。这意味着合并提交的first 父级。但是,如果一个(假设)“意外”将 master 合并到分支,然后将 master 快速转发到合并提交 - 应该使用 -m 2 恢复 master 上的合并。
  • 小心1。它通过部分还原合并弄乱了我的存储库,而我想完全还原合并。我最终还原了还原!
【解决方案3】:

第一个选项是使用git revert

git revert -m 1 [sha-commit-before-merge]

git revert 将恢复更改但会保留历史记录。因此,您将无法继续在同一个分支中工作,因为您无法再看到合并分支与您的功能分支之间的实际差异。 也可以使用以下方式删除历史记录。当且仅当您是当前唯一一个将更改推送到分支时,请非常小心地执行此操作。

git reset --hard [sha-commit-before-merge]
git push [origin] [branch] --force

【讨论】:

    【解决方案4】:

    在我的例子中,我将我的分支(比如:my-branch)与另一个功能分支(feature-branch)合并,但不是 master。 所以我的分支历史是这样的:

    my-branch (before merge)
    
    ---master----m1----m2----m3---m4
    

    在将它与另一个 feature-branch 合并后,它在 master 之上提交了 f1, f2,它变成了这样:

    my-branch (after merge)
    
    ---master----m1----m2----f1----f2----m3---m4----mergecommit
    

    这可能是因为在我的分支上工作时,我在 2 次提交后从 master 进行了合并,或者 2 个分支之一可能没有与 master 保持最新。 因此,在这种情况下,git revert -m 1 无法正常工作,因为它会将 f1f2 提交留在两者之间。

    解决方案很简单,适用于正常情况下,我们没有中间提交:

    git rebase -i HEAD~6
    

    根据您想要更改的过去提交的数量,使用适当的数字而不是 6。 现在 Vim 编辑器已打开,只需将不需要的提交标记为 drop 并使用 :wq 退出 验证日志:

    git log --oneline 
    

    强制推送

    git push -f
    

    现在远程分支应该处于以前的状态。

    【讨论】:

      【解决方案5】:

      正如另一个答案中提到的,在合并时执行 git revert 的主要问题是 git 仍然认为所有以前的提交都已合并(它只会更改代码)。如果您稍后尝试合并该分支,您会发现之前的提交丢失了。

      更好的方法(显然是在与您的团队协商后,以免他们继续处理有问题的分支)是 git reset 到较早的提交。不必进行硬重置,因为这只涉及如何处理您当前的工作更改,因此这部分取决于您。

      如果您想在重置之前先在那里进行更改,您也可以从之前的提交创建一个临时分支。在这种情况下,您将重置为临时分支上的提交。

      如果不从上游拉取,您将无法推送,但显然您不想拉取您试图还原的更改。因此,您需要执行强制推送(或者如果在此期间推送了任何更改,则使用租约强制推送以停止)。

      旁注:作为 VS Code 和 Git Graph 的粉丝,我发现通过右键单击本地分支标记名称并选择“Push Branch...”,选择 Force 或 Force With 即可轻松完成强制推送租约,选中“设置上游”框。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-02
        • 1970-01-01
        • 2013-01-19
        • 2015-08-07
        • 2016-07-12
        • 2017-02-26
        • 2021-05-18
        • 2011-07-16
        相关资源
        最近更新 更多