【问题标题】:Accidentally merged master into develop and pushed不小心将master合并到develop和push
【发布时间】:2013-10-01 12:06:50
【问题描述】:

我在一个 git repo 工作,我们维护一个 master 和一个 develop 分支。在发布前在开发中进行更改并合并到主中。今天不小心把master合并到develop,结果推到develop。开发中的 git log 现在显示 merge develop into master 提交。我需要以某种方式解决这个问题。我使用git reflog 找到了最近一次好的提交。恢复它的正确方法是什么?

由于我已经推送了,我想避免重写历史。但是,我不确定是否可以使用git revert。我不相信“恢复错误的合并”操作方法和其他 SO 问题是否适用,因为我想要恢复的提交本身就是合并 (https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.txt)。

【问题讨论】:

    标签: git github


    【解决方案1】:

    可以使用git revert 恢复合并。请注意,当您这样做时,会使未来的“重新合并”变得更加困难。阅读您紧密链接的那条消息-它说了很多关于如何使未来“重新合并”工作的信息-但请注意,它正在谈论将develop合并到master,而您说您做了相反的事情,合并@ 987654324@转develop

    A -- B -- C -- D -- E          <-- master
          \          \
           F - G - H - M           <-- develop
    

    在这种情况下(将 master 合并到 develop 中,而不是相反),您可以选择许多不同的选项,它们各有优缺点...

    最简单的方法,如果可以的话我更喜欢

    (0) 什么都不做。如果合并CD 不会破坏develop 分支,那么就这样吧。稍后,有人会 git checkout mastergit merge --no-ff develop 并得到这个(假设先将另一个提交 I 添加到 develop):

    A -- B -- C -- D -- E -- M2    <-- master
          \          \      /
           F - G - H - M - I       <-- develop
    

    在这里,merge 查找在 develop 中所做的事情,因为它从 master 中分离出来,在 B。所以它放入FGH,跳过M 的任何从master 脱落的部分(可能是所有部分),最后放入I 并进行合并提交@ 987654347@(因为提交E;但如果E不存在,那是因为我也使用了--no-ff)。

    一些简单但缺点明显的方法

    (1) 只是“重写历史”:从分支develop 中删除提交M。提醒所有使用该分支的其他人这即将发生:提交 M 正在消失,他们应该采取任何必要措施来处理这个问题。

    (2) 停止使用旧名称develop,改用新分支名称develop1 或其他名称:

    A -- B -- C -- D -- E          <-- master
         |           \
         |             M           <-- develop
          \          /
           F - G - H               <-- develop1
    

    这与选项 (1) 相同,只是提交 M 仍然存在,以及它上面的分支标签,并且您有一个新的/不同的分支标签指向提交 H。您仍然需要提醒每个人,但这可能会使他们的工作更轻松。你可以稍后删除develop,当每个人都同意时。

    还原及其缺点

    (3) 恢复合并。和链接的文章一样,让我们​​使用W 来表示新的revert commit:

    A -- B -- C -- D -- E          <-- master
          \          \
           F - G - H - M - W       <-- develop
    

    W 中有什么内容?不管需要什么来“消除合并的影响”。在这种情况下,这意味着更改会取消在CD 中所做的任何事情。到目前为止一切顺利,develop 又一次有了来自FGH 的变化。问题出现稍后,如果/当有人这样做时:

    git checkout master
    git merge develop
    

    第二个命令查找masterdevelop 的拆分位置,即提交B,因此它会获取从那时起的所有更改。此时包括W 中的那些,它们将un-执行CD,完全不是你想要的。之后可以修复它,但无论谁进行合并,都必须知道这个“删除CD”的定时炸弹等着他们。

    请注意,这与“什么都不做”选项 (0) 中的合并相同。这里的问题是W内容。在情况 (0) 中,您想要提交 I 的内容,但在这里您想要 W 的内容。

    另一种选择

    考虑到上面显示的内容,这可以说是最糟糕的选择,但我还是会列出它:

    (4) 使用您想要保留的提交的 副本 创建一个全新的分支,并将其命名为 develop。 (或将其命名为其他名称,但随后我们又回到了上述develop1 类似的情况,您可能应该只使用那个。)无论您是保留old-develop 分支,还是放弃它(通过不标记它),取决于你,但我会把它画进去:

           F' - G' - H'            <-- develop
          /
    A -- B -- C -- D -- E          <-- master
          \          \
           F - G - H - M           <-- old-develop
    

    这在您包含的链接中有所描述。它只在更复杂的情况下才真正有用。

    【讨论】:

    • +1 只是为了您必须花在这些图纸上的时间;)
    【解决方案2】:

    您可以通过将您的本地分支重置回最后一次良好的提交来解决此问题,然后将其推送:

    git checkout develop
    git reset --hard lastgoodcommit
    git push origin develop
    

    请注意,您的上游存储库默认情况下可能不允许非快进合并。如果是这样,您将需要在上游修改该选项,执行上述推送,然后恢复原始设置。

    【讨论】:

    • 执行此操作的标准方法是push --force,并且 OP 表示如果可能他们不想重写历史记录。
    • 当然,但不是“不想重写历史”和“恢复错误的合并”在很大程度上是不兼容的目标。问题是,如果您除了重写历史记录之外还做了任何其他事情,那么看起来之前在master 上的提交已经被合并到develop 中,即使它们没有(在做了任何尝试撤消此操作之后) .
    • 您的意思是因为它们仍会出现在git log 中吗?并且只有在您也看到还原后才能清楚历史记录?
    • 是的,来自 master 的那些提交仍然会显示在日志中,并且一些工具会认为这些提交已经存在于您的开发分支中,即使稍后的还原已经取消了它们的影响。如果你能应付得来,那绝对是最好的强制推倒历史。
    【解决方案3】:

    我使用 GIT 扩展。有一个功能可以右键单击 UI 中的修订并恢复到它。

    【讨论】:

      【解决方案4】:

      是的,您可以恢复合并,但您需要指定哪个父项是主线。由于您将开发合并到主控中,这应该可以解决问题:

      git revert --mainline 1 HEAD
      

      为了确保你得到你想要的,你应该用 $lastgoodcommit 做一个 diff,但是,$lastgoodcommit 应该是 HEAD^。这当然是,如果您还没有在合并之上进行提交,如果有,那么您需要将 HEAD 替换为合并提交。

      最后,您还可以手动执行还原,方法是检查当前提交之上的代码:

      git checkout $lastgoodcommit -- .
      

      '--.'是否有区别于正常的签出,其中 HEAD 切换到指定的提交,在此处的命令中,工作目录中的所有文件和暂存区域都将与 $lastgoodcommit 中的完全相同。如果您使用 $lastgoodcommit 进行比较,您应该再次看到没有任何变化。本质上它是一个还原。

      您也可以尝试使用“git checkout --patch”来选择性地还原代码块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-30
        • 2018-12-15
        • 1970-01-01
        • 1970-01-01
        • 2022-07-26
        • 2021-04-16
        • 1970-01-01
        相关资源
        最近更新 更多