gpt4 book ai didi

git - 如何将一个孤儿分支附加到“原样”母版?

转载 作者:太空狗 更新时间:2023-10-29 14:18:26 25 4
gpt4 key购买 nike

在迁移到使用git的过程中,我们获得了一个解决方案的生产版本,并将其作为master提交。
然后我们制作了一个开发版本,并创建了一个名为develop的孤立分支。
(背景:我们在这里有点纠结的原因是,从开发版本到生产版本没有一个干净的演进过程。此外,组装相关解决方案的复杂性使我们希望避免取消回购并再次尝试。最后,我们只想将这些版本导入git,并在git中开始清理。
所以-现在我们认为最好从master分支开发版本,而不是将其作为孤立分支。
我们如何基本上接受主提交并使其成为develop commit的父级,而不进行任何合并?不更改第一次开发提交的文件内容?
那就是-只是移植到它身上,如果这有什么意义的话?

最佳答案

听起来您希望修改提交图,而不修改附加到这些提交的任何树。
如果您理解git在内部的工作方式,那么这个语句将更有意义。这里的关键是:
所有提交都是永久的和不变的,因为提交的“真实名称”(或者实际上是git的四个内部对象中的任何一个)是其内容的sha-1密码校验和。这意味着,如果您试图更改任何内容(或者磁盘驱动器发生故障会更改某些内容),git将抱怨校验和不正确,因为您在每个对象中看到的内容不再与其“真实名称”匹配。
每个提交都带有一个“tree”对象的sha-1 id,该对象充当该提交附带的源的完整快照。(树给出了每个文件或目录的文件名和sha-1“真名”。子目录由另一棵树表示。这里的细节并不重要。)
每个提交还列出其父级的“真名”sha-1 id。因此,给定develop的提示提交,git可以读取该提交并找到其直接父级。git通过读取该父(或那些父)找到下一个id,然后为其父读取,依此类推。该过程在读取“根”提交(没有父级)时停止。执行--orphan签出,然后进行提交,将生成新的根提交,这无疑是您创建分支的方式。
存储在任何给定提交中的这些父ID和树ID被称为“指向”Git存储库中的其他对象。(回购协议中只有四种类型的对象。我们已经提到了“commit”和“tree”,另外两个是“blob”,这就是git保存文件和“tag”的方式。树指向blob和子树,“标记”对象用于带注释的标记。)
因此,您要做的是更改develop分支的根提交,以便它现在有一个父提交,特别是一些可以从master分支的当前尖端访问的提交。(也许您需要提示本身,也许您需要类似于master~100:此细节仅在您进行更改时才重要。)
坏消息是,由于项目1,你不能完全这样做。
好消息是,你可以用三种方法中的任何一种(然后根据需要和需要,使移植永久化)。
首先,git有一个叫做“grafts”的东西。他们工作得不太好,所以git有一个新的更好的东西叫做“替代品”。根据你的吉特葡萄酒的年份,你应该至少有一个,几乎可以肯定两者都有。
这两种方法都使用相同的基本思想。当git从commit遍历到parent时,您希望在某个时候能够让git更改它的遍历。使用git grafts,只需指定在id<X>的对象上,它应该遍历父对象。这可以让您找到当前<Y>上的根提交,并将其直接移植到develop中的某个提交上。
这些嫁接不会被master复制,并且会引入其他问题,因此git现在有git clone。这将在存储库中创建一个实际的对象,并允许您检查带有或不带替换的提交图。若要使用这种情况,您将为根提交做出替换提交,这与现有的根提交完全相同,只是它具有您希望的父级。
如果您想完全重写历史记录,使所有用户在经历一个痛苦的重写步骤后都能轻松完成,那么您可以设置移植,然后使用git replace复制和替换移植。或者,也许稍微简单一点,指定一个父过滤器(而不是其他过滤器)。有关详细信息,请参见the git filter-branch documentation;它有一个本例的示例。(文档表明创建移植更简单,我认为使用git filter-branch更简单;但是不管怎样,都有一个方便的例子。)
注意,filter分支复制每个“filtered”提交,并应用一些更改,方法是(实际上)签出该提交,然后应用筛选器,然后从结果创建新的提交。在这种情况下,第一个更改是将父ID添加到根提交。第二个更改是一个筛选器分支自动执行的操作:使不再孤立的根副本之后的提交指向根副本。第三个变化与第二个相同,依此类推:

      A--B--C     <-- develop (before filtering)

...--o--o--... <-- master
\
A'-B'-C' <-- develop (after filtering)

这里,commit --parent-filter与commit A'完全相同,只是它有一个父ID; AB'完全相同,只是它的父ID是 B而不是 A';依此类推。
(注意,顺便说一下,父箭头都指向左边,但是 A从左到右。它首先枚举要过滤的所有提交,以从右到左的方式获取它们的id,然后从左到右进行过滤。
This existing SO Q-and-A has a lot more on using grafts or replace.
我确实在上面提到了第三种方法。只有当 filter-branch没有现有的合并提交时,才会执行此操作。然后,您可以简单地将 develop中的每个提交重新定位到目标提交,即 siride suggested in a comment。您需要使用 develop运行rebase命令,以便从独立 --root分支的根目录复制每个提交。
这之所以有效,是因为 develop只是复制提交,与 git rebase的工作方式大致相同。从某种意义上说,这是更多的工作,因为ReBaseEXCESS提交的方式是使用DIFS(重复使用 git filter-branch s,或多或少),而不是简单地保留每个复制提交的现有“树”对象,但是比 git cherry-pick更容易工作。这里的缺点是rebase根本不处理合并提交(好吧,除非您使用使用交互式rebase代码的 git filter-branch)。

关于git - 如何将一个孤儿分支附加到“原样”母版?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32954312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com