Git分支分裂点
我在清理git历史记录树时遇到问题 基本上,我的git存储库有一个分支,如下所示:Git分支分裂点,git,git-branch,Git,Git Branch,我在清理git历史记录树时遇到问题 基本上,我的git存储库有一个分支,如下所示: A--B--C--D--E--F--G--H--I--Z--X--Y... master \ F--G--H--I--J--K--L... branch1 提交E是一些不重要的更改,可能会变得多余。 这里正确的分割点应该是I而不是D。 提交E可以被删除或添加到两个分支中 有没有办法做到这一点 -----更新 哇,非常感谢你的帮助 我试过托瑞克的建议,效果
A--B--C--D--E--F--G--H--I--Z--X--Y... master
\
F--G--H--I--J--K--L... branch1
提交E是一些不重要的更改,可能会变得多余。
这里正确的分割点应该是I而不是D。
提交E可以被删除或添加到两个分支中
有没有办法做到这一点
-----更新
哇,非常感谢你的帮助我试过托瑞克的建议,效果很好 现在。。我还有另一个存储库要清理,但它更复杂 它看起来像:
1--2--3--4--*A--5--6--7--8--*B--9--10--11--*C--*D--12--13--14 master
\
5--6--7--8--9--10--11--12--13--14 branch1
注1:字母代表提交的内容注2:*信函提交仅适用于主分支机构 有没有办法清理这样一棵历史树 另外,对于这种结构的项目,建议使用什么git方法?
i、 e分支后,除了一些特定于分支的提交之外,大多数提交都将包含相同的更新。实现这一点的一种方法是创建一个新分支作为master的副本,并执行git reset--hard i-commit,然后选择所需的提交(希望不会太多)您可以在
I
创建一个新分支,在branch1中所做的所有更改基本上都是如此
git branch -b temp I
git cherry-pick J..branch1
然后,您将有一个新的分支temp
在I
拆分,而不更改E
,并包含branch1
的所有提交,从J
开始,如果这两个分支工作正常,您可以重命名它们,使temp
分支成为您的新branch1
。在樱桃采摘之前,如果您不想在branch1
中使用提交E,可以先在绘制提交图的问题上+1.:-)第二,不是非常重要,但您可能应该将其视为两个分支,master
和branch1
。master
没有什么特别之处,它只是一个与其他分支一样的分支。1
现在,git中所有内容的核心是,您永远不能更改提交。这源于git实际命名每个提交的方式,2使用了40个字符的SHA-1:SHA-1是通过计算提交内容的加密校验和生成的。因此,如果您(尝试)更改任何内容,“真实姓名”将更改,您将有一个新的和不同的提交
相反,您可以做的是将一个旧的提交复制到一个新的提交,在提交完成之前进行所需的更改(因此给出了它的“真实名称”)。我们在这里要做的是复制
您绘制了以下图表:
A--B--C--D--E--F--G--H--I--Z--X--Y... master
\
F--G--H--I--J--K--L... branch1
但这并不完全正确,因为每个提交都指向其父提交,3这里当我们查看master
时F
指向E
,但当我们查看branch1
时F
指向D
。(我在这里假设每个字母代表给定提交的SHA-1“真实名称”)我将假设当前在branch1
上的是副本,尽管这并不重要,只要您对与这些提交相关联的树感到满意(即,当您git checkout
其中一个时得到的内容)
您想要的是这样的:
A--B--C--D--E--F--G--H--I--Z--X--Y... master
\
J'-K'-L'... branch1
这里,J'
、K'
和L'
中的“prime”标记表示这些是提交J
、K
和L
的副本
在我写这个答案的时候,有几个人建议使用git cherry pick
来制作这些副本。这很好,但事实上,我们可以使用git rebase
来实现这个技巧,因为cherry pick
是一把简单的斧头,可以用来砍倒一棵樱桃树,rebase
是一个全自动的链条-你可以用锯子一下子完成所有的任务
我们首先告诉retbase
操作branch1
;简单的方法是git checkout branch1
(或者我们可以将branch1
作为git rebase
的最后一个参数,但我将使用“简单方法”)
接下来,我们需要知道提交要从何处分支,也就是说,有一些方法来命名提交i
。从上面,我们可以说master~3
:从master
中倒数四次提交(哪些名称为提交Y
)你可以通过X
,然后Z
,然后到达I
。或者你可以用真名SHA-1来完成,它总是有效的,但通常需要剪切和粘贴才能正确。对于下面的命令,我只需编写I
。我们将告诉rebase将--放在提交的上
最后,我们需要使用rebase
来选择提交J
,K
和L
进行复制。也有很多方法可以做到这一点。也许最简单的方法是使用git-rebase-i
,它将提供对branch1
上的所有内容重新设置基础,然后您可以删除pick
行他提交了前四次。或者,我们可以告诉rebase
排除特定的提交,但我假设您将使用交互式方法
因此,这里的最后一个命令是git-rebase-i--into i master
(在执行git checkout branch1
命令之后).The-i
使其具有交互性,以便您可以删除提交;-on
为新的一系列提交选择目标,rebase
将对其进行选择;master
部分告诉rebase
哪些提交要排除:具体地说,任何可从名称master
访问的提交。(这不包括A
、B
、C
和D
,但不包括出现在branch
上的复制版本F'
、G'
、H'
和I'
:您只需删除其中的“选择”行)
A--B--C--D--E--F--G--H--I--Z--X--Y... master
\
J'-K'-L'... branch1
git rebase --onto master~3 branch1~3 branch1