使用原型代码将Git repo重组为实际可发布的项目

时间:2015-05-31 09:04:16

标签: git

我最近在开发一个API库,它将一个相对较大的外部API的一部分包装到一个更惯用的结构中。当我在编写原型代码时进行API探索时,我最终实现了三个具有不同功能程度的可用子API。或者更简单地说,我有一个结构上看起来像

的项目
dir:root
 └ dir:feature-a
 └ dir:feature-b
 └ dir:feature-c
 └ dir:common
 └ file:build.gradle
 └ file:build.py

其中每个功能都与其中一个子API匹配。值得一提的是这些目录并不平坦,为了简单起见,我只是省略了子目录。

我的主要问题是,虽然我实际上只提供了一个半正式的版本历史,但它只在一个分支中,并且只有一个子API可以发布。理想情况下,我想找到最便捷的方式

  1. 拆分现有仓库,以便我可以将每个功能转换为自己的分支,以便我可以逐个发布它们,因为它们足够成熟
  2. 保留当前版本的历史记录(可能会有一些重新定位)
  3. 我之前使用git filter-branch用于类似目的,但这里的一个主要曲线球是存储库根目录实际上是另一个存储库 - 在元级别上,存储库有两个父母,当然这是 funky 并且对于使构建脚本保持最新非常有用但是如果我尝试用filter-branch做我想要的东西,项目根目录下的构建脚本将被删除,这绝对不是我想要的。

    最后,common目录有点特别 - 我不介意削减其版本历史记录,只要其内容在那里。

1 个答案:

答案 0 :(得分:4)

<强>摘要

如果您想保留某些公共资源(build.*)的历史记录并在将来轻松合并这些资源,您想要重写/过滤/删除子资源使用feature-a在存储库(commongit filter-branch)中设置其他树的集合,您应该首先按顺序重写现有的提交:

  • 项目之前的所有常见提交都是从模板分叉的(这已经是这种情况)。
  • 所有提交修改build.*,包括本地更改和上游Cradle的合并。
  • 最后,feature-*common
  • 的所有项目特定提交

然后,您可以在项目特定的开发线上安全地运行git filter-branch,而无需重写任何上游资源历史记录。如果你不这样做,你可能会最终重写涉及构建脚本的提交,包括来自上游Cradle的merge-commit,这将禁止历史可追溯性和未来的合并。

<强>详细

听起来你有一个黄金项目模板,称之为T,每次你开始一个新项目时,你都会分叉这个回购(无论是在传统的GitHub意义上,还是只是创建将会是什么一个不同的克隆)称之为Pn。因此PnT以相同的历史记录和常见提交开头(称为分支点Pn-0)。

Pn开发其代码库时,其他项目可能会识别对基础项目模板基础结构的改进,并对F中的文件T进行更改。任何项目Pn(可能在模板前面提交数百次提交)仍然可以合并T中常见文件的更改。

现在,您想要在Pn中重写历史记录。从Pn-0开始,您已经进行了许多项目特定的提交,然后是T的合并,然后是更多项目特定的提交。如果您必须将P重新设置回Pn-0以便filter-branch,则T的合并历史记录将丢失,因为历史记录已经分歧,未来将从{{}}合并{1}}变得地狱般的。

这是否描述了您的问题?

我认为您正在看到,当您希望完全自由地重写历史记录以重新组织项目回购时,使用项目克隆从模板方法有其局限性。如果您在T合并提交之前和之后都有历史记录,那么您将不得不进行一些奇特的重组以保留共同的历史记录。那个解决方案是:

  • T成为Tx的最新提交,您已完全合并到T
  • Pn提取到T回购中,并在Pn中创建一个以提交Pn开头的分支。
  • 将您当前的Tx历史记录重新定位到该分支上,将其从Pn(常见提交Pn-0)移至T,最新的常见提交{ {1}}。

此方法将在Tx中重播您的整个历史记录,就像它以T而不是Pn开头一样,因此提交Tx有一个新的父Pn-0 。当然,每个提交都将被重写,因此Pn-1的任何现有克隆都会立即成为孤立状态。

完成此操作后,您可以从重写的提交Tx开始运行Pn,并删除任何不完整模块的历史记录。

现在 - 这是一个相当大的麻烦,并以棘手的方式重写历史,但历史将保留。你不想每天都在做这个过程。

您可能想要考虑的一件事是,是否有任何方式可以在没有源共享的情况下生成和使用您的摇篮。它可能不像Git-merge一样方便,但如果您的模板项目是版本控制的并且您organize your build logic并且可能使用shared scripts,那么您可以模块化您的模板项目,这样您就不再依赖于孩子 - 项目维护共同的源历史以便合并 - 他们只会使用最新的模板二进制文件。取决于构建逻辑以外的模板中的内容。