Git 在分支之前拆分提交

Posted

技术标签:

【中文标题】Git 在分支之前拆分提交【英文标题】:Git split commit before branch 【发布时间】:2022-01-13 23:09:54 【问题描述】:

假设您有以下历史记录:

         D———G feature1.1
        /
...A-B-C-E-F  feature1

现在我想将 B 拆分为两个提交以获取:

             D———G feature1.1
            /
...A-B1-B2-C-E-F  feature1

你不能只做 git rebase -i ... 然后选择编辑,因为你得到了这个

     B-C-D-G feature1.1
    /
...A-B1-B2-C'-E'-F'  feature1

但这可以通过使用 git rebase --onto C' C feature1.1 快速解决。

现在来看一个更具体的用例。如果 feature1 是你的 master 分支,A 是你的初始提交并且你想拆分 A,你会怎么做。同样的技术不起作用,因为在 rebase 之后它们不再有共享的历史记录。

【问题讨论】:

您仍然需要使用相同的技术:使用rebase --onto--onto 的目标将是拆分 A 的前半部分,无论最终的哈希 ID 是什么。 【参考方案1】:

主要的祖先手术是git filter-branch 领土,使用任何最方便的工具来进行任何内容更改。有时在 filter-branch sn-p 中“当你在那里”时最容易做到这一点,但在这里更容易提前设置内容,只需使用 filter-branch 进行祖先重写。你可以在不重写现有祖先的情况下做的事情是让A---B1---B2,开始这样做

git checkout B
git reset A

你的工作树现在是 B 内容,你的索引是 A 内容,而 HEAD 即你的下一个提交的父是 A,所以添加 B1 内容是最方便的:

git add files whose changes all belong in B1
git add --patch files whose changes partially belong in B1
git reset --patch any hunks you added by mistake
git commit   # this makes B1
git add .    # everything that remains belongs in B2, so add everything
git commit   # this makes B2

现在唯一剩下的就是重新连接祖先,不需要更改内容。仅进行本地重新布线,然后使用 git filter-branch 将本地历史重写烘焙到依赖于它的所有重写历史中:

git replace --graft C B2
git filter-branch -- --all

【讨论】:

以上是关于Git 在分支之前拆分提交的主要内容,如果未能解决你的问题,请参考以下文章

Git - '你的分支在“X”提交之前是“X”。

撤消 Git 分支提交和合并

如何拆分隐藏在历史中的 Git 提交?

如何拆分隐藏在历史中的 Git 提交?

git 在多个修补程序和功能提交后同步分支

Git:如何防止特定的提交被合并到另一个分支中?