【问题标题】:Git: Work on merged branch, which was unmerged afterwardsGit:在合并的分支上工作,之后被取消合并
【发布时间】:2017-10-05 13:27:17
【问题描述】:

我遇到以下问题: 我在一个分支 A 工作。 分支 A 已合并到 Master 分支中,到目前为止一切正常。

一段时间后,客户决定撤消在主分支上的分支 A 中所做的更改,因为它必须更新。

所以主分支中的历史看起来像:

Some stuff
Some other stuff
Some stuff, where the merge of Branch A was reverted
Some other stuff
Some other stuff
Branch A was merged into master
The commit of Branch A (Branch A contains one Commit)

我想变基分支 A,所以我想要这样的东西:

The commit of Branch A (From here I want to continue working)
Some stuff
Some other stuff
Some stuff, where the merge of Branch A was reverted
Some other stuff
Some other stuff
Branch A was merged into master
The commit of Branch A (Branch A contains one Commit)

请注意,我不想更改远程 master 的历史记录,我需要将分支 A 的提交重新设置为我的 master 的最后一次提交。然后我想再次将我更新的分支 A 推送到 Master。

现在我想继续在分支 A 上工作,但首先我想在当前主分支上重新设置分支 A,以获得最新状态。

现在的问题是:当我在 master 上 rebase 分支 A 时,git 似乎删除了我在分支 A 中所做的更改。我认为这是因为 Master 分支中的合并反向。所以:Git 看到,分支 A 在 master 分支中被删除了,所以当我在 master 上 rebase 分支 A 时,删除也会完成。

我不想将我在分支 A 中更改的文件一个接一个地复制到另一个分支上,这是从 master 结帐的。我认为有更好的解决方案,有什么建议吗?

【问题讨论】:

  • 客户究竟做了什么?他是revert 合并提交,还是用rebase 删除它?一个人将决定最佳行动方案的答案。
  • @SebastianLenartowicz 给定的历史记录表明存在还原提交。
  • 为什么不在分支 A 上合并(而不是变基)master 后恢复它?
  • 有一个提交,它只是恢复了分支 A 的合并。恢复恢复听起来不错,但是当分支 A 再次被推送到我们的远程主服务器时会发生什么,我无法访问至。我认为分支 A 中的更改再次被删除,但我的新更改将设置在顶部,我理解正确吗?
  • 你能澄清master指向哪个提交,branch-a指向哪个提交吗?

标签: git merge rebase


【解决方案1】:

由于您不想触及 master 的历史,您需要将您的更改重新应用到 master 的顶部,忽略它们已经应用并恢复的事实。根据还原提交的确切性质,我们称之为<revert>,我看到了两种实现此目的的方法:

  1. 如果<revert>撤消了您的更改,那么您可以再次还原它以获得重新应用您的更改的提交(想想--x == x)。

    李>
  2. 如果还原提交不是纯粹的,我会这样处理这种情况:

    • 使用git format-patch为您的分支创建补丁序列。

    • 使用git am将此补丁序列应用到master。

    关键是,git am 与历史无关:它只查看当前提交的状态并将补丁应用于该状态。

【讨论】:

    【解决方案2】:

    如果您使用git checkout branch-a && git rebase -i master,您将在文本编辑器中获得一个提交列表,每个提交前面都有pick 命令。您可以将其更改为几个选项之一,所有这些都在给定的文本中进行了解释。例如,您可以skip 还原提交,这些更改将不会被还原。

    另一种可能的解决方案是像 git revert 那样重新设置基础,该提交恢复了 branch-a 的合并。

    【讨论】:

    • 听起来很酷,但我理解正确,为此,我需要访问我们的远程主机?或者当我在本地主分支上执行此操作时,我会继续在此分支上工作。由于还原提交仍在历史记录中,当我再次将其推送到我们的远程主机时会发生什么?
    • @MJohnyJ 请注意,您可以对本地存储库进行任何更改,而无需访问任何远程分支。这里的建议是重新定位您的branch-a。我写了这篇关于masterbranch-a 点的假设,我现在认为这是不正确的。请您澄清一下这些分支机构在哪里?
    • @MJohnyJ git rebase -i 将允许您删除还原提交。您可能需要修改最后一个参数,甚至使用--onto。您甚至可以还原还原提交以恢复更改。
    • 还原还原为我完成了这项工作!这也是合乎逻辑的,历史保持原样,推送到远程主机应该没问题。谢谢!
    • @MJohnyJ 很高兴它成功了!我最初的答案是基于对您的分支状态的错误理解。
    【解决方案3】:

    嗯,这有点棘手。由于BranchAHEAD 已经是master 的一部分,git 认为master 中的代码比BranchA 更新。在这种情况下,如果你们重置主分支中的更改而不是通过显式提交恢复它们会更好。

    以下所有选项都涉及重写历史记录,因此请先在某个临时分支中尝试它们。

    一种选择是使用rebase --onto 更改主分支,以便删除合并和恢复提交。

    git rebase --onto <commit_id_before_merge_commit> <revert_merge_commit_id> master
    

    其次是更改BranchA 中的提交哈希,这样 git 就不会像在 master 中那样识别它们。

    git checkout BranchA
    git reset HEAD^n # n is the number of commits that are exclusive to branchA
    git add -u # Add all the files. Make sure to add newly created ones.
    git commit -m 'some message'
    git rebase master # should work now
    

    第三,您还可以使用交互式变基来更改BranchA中的提交ID

    git rebase -i <first_exclusive_initial_commit_id_of_branchA>
    

    【讨论】:

    • 更改提交哈希似乎是一个非常好的主意。这是我能看到的唯一方式,无需访问我们的远程主仓库。但不确定,如果它是解决问题的正确解决方案
    猜你喜欢
    • 2013-12-02
    • 1970-01-01
    • 2023-03-06
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多