【问题标题】:How can I drop a branch from a mulitple branch merger in git?如何从 git 中的多个分支合并中删除一个分支?
【发布时间】:2012-02-24 12:10:39
【问题描述】:

我刚刚将三个不同的分支合并为一个功能集的一部分,然后推送结果,因此存储库树目前如下所示:

--- A --- A1 --- A2 --- A3 -- | \ + --- B1 --- B2 --- B3 --- B4- | \ + --- C1 --- C2 --- C3 ---------C4

但是,我刚刚被告知 B 分支尚未准备好迎接黄金时段,因此我需要撤消这些提交。如何回滚我的更改,以便我的新负责人 C5 将合并 C3A3 提交?完成后,我希望存储库如下所示:

+ --- B1 --- B2 --- B3 --- B4 --- B5 | / --- A --- A1 --- A2 --- A3 -- | \ + --- C1 --- C2 --- C3 --- C4 --- C5

【问题讨论】:

  • 为什么不直接将所有分支硬重置为第 3 状态,然后从 B 和 C 与 A 合并?您的意思是您在失败合并后已经做了一些额外的工作,并希望在保留后续工作的同时修复此合并?
  • @the.malkolm - 在某些情况下,我认为可能是这种情况,其中一位开发人员询问如何删除一些不会发布的功能代码。

标签: git merge revert


【解决方案1】:
# checkout before merge
git checkout C3
# make merge we want
git merge A3
# rebase any work on top of the new merge
git rebase --onto HEAD C4 branch_C
# use fixed version as branch_C
git branch -f branch_C HEAD
# aha! now you on the fixed branch_C
git checkout branch_C

与 B 完全一样。我想你在“坏”合并后没有进一步分支 C 和 B。

【讨论】:

    【解决方案2】:

    假设您尚未与其他人共享此存储库,您可以尝试git rebase --onto

    git rebase --onto <to> <from> <what>
    

    我假设您的分支命名为 A(在 A3)、B(在 B4)和 C(在 C4):

    git rebase --onto B3 A3 C
    

    其中 B3 和 A3 实际上是提交 SHA 本身。

    强烈建议在执行此命令之前备份您的存储库,以便安全地播放它。

    【讨论】:

      【解决方案3】:

      我来自喜欢重做的阵营只要它没有被推动,留下一个不那么冗长的历史,我通常这样做:

      # go back to commit C3
      git checkout C3
      
      # redo the merge with only A
      git merge branch_A
      
      # make sure you've gotten the desired alteration
      # git diff --stat branch_C
      # git diff branch
      
      # switch your C branch over to your redone version
      git checkout -B branch_C
      
      # otherwise if you change your mind, just go back to C4
      # git checkout branch_C
      

      编辑: 评论 #4 完全正确,因为之前的版本没有任何结果。此编辑更改了之前合并 B4git merge 行。初始结帐时的 --detach 选项也被删除,因为如果参数 C3 不是分支名称,则它是多余的。

      【讨论】:

      • 真的没有理由期望在 C3 有一个分支。事实上,一切都表明并非如此:在图片中,C3 代表提交。所以你使用--detach 是不必要的干扰。
      • 确实如此。但是我对--detach 的使用在我的建议中更多是关于明确的,我认为它在上面的使用具有以下优点: 1. 它暗示了使用分离状态的概念,这与在分支上使用git checkout 相似但略有不同. 2. 如果我没有明确说明这些内容,不太熟悉的人可能会认为指定分支名称是同义词,然后在移动它后最终会感到困惑。 (尽管再三考虑,这些人可能不会创建任意分支..)
      • 重点是,虽然了解它是一件好事,但这并不是展示它的含义或为什么需要使用它的好方法,因为你正在使用在没有操作的情况下。
      • 如果我错了,请纠正我,但您的演练实际上并不会导致代码库是 A3C3 合并而没有 B3 代码。我想要的是C 分支的负责人成为A3C3,除非是这种情况,否则我必须否决这个答案,因为它实际上并没有回答问题。
      【解决方案4】:

      还原 C4(并提交该还原)​​,然后将 A3 合并到您刚刚创建的 C5 中。

      --- A --- A1 --- A2 --- A3 -----------------------------
          |                         \                          \
          + --- B1 --- B2 --- B3 --- B4-                        \
          |                              \                       \
          + --- C1 --- C2 --- C3 ---------C4--- C5(reverts C4) -- C6
      

      最终得到 B4 包含 B3 + A3,C6 包含 C3 + A3。

      我想你也可以通过变基来做到这一切,但我更喜欢在我做了一些乱七八糟的事情时留下我的足迹,这样我就可以看到我的错误以及我为修复它所做的工作。 Rebase 撤消了历史,这让我抽搐。

      【讨论】:

      • 如果需要,是否只需恢复到B3 并承诺撤消B4 提交?
      • Revert 不会完全“撤消”提交。您不会“恢复到”较早的版本。恢复一个提交会创建一个新的提交,它是指定提交的 INVERSE,撤销 CHANGE,同时及时向前移动。所以:要撤消 B4 提交,您需要还原 B4,然后在该分支上提交它。请参阅gitready.com/intermediate/2009/03/16/…git reset 让您及时倒退,有点像变基,但我更喜欢还原并记录我的错误和修复。
      • 恢复合并很有趣。阅读手册页,在 -m 选项下,包括后续合并不会带回更改的警告。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 2014-10-02
      • 1970-01-01
      • 2010-12-15
      • 2019-11-09
      • 2012-06-21
      • 2019-03-11
      相关资源
      最近更新 更多