我的项目使用了 100 多个 git 个子模块,哪个子模块替代方案可以优雅地处理大量存储库
My project uses over 100 git submodules, which submodule alternative can handle a lot of repositories gracefully
我一直在研究 git 子树和 git 子模块的其他替代方案。我的项目有 100 多个子模块,管理它们非常笨重。
任何人都可以推荐一个工作流程,该工作流程非常适合需要保持同步的大量存储库。
如果您的项目有超过 100 个 git 组件和依赖项的子模块,无论您使用哪种方法,它们的管理都将变得笨拙 :-) 我建议寻找尽可能多的脚本和自动化部分的方法.相信我,对大多数人来说,使用和链接 git 命令的新鲜感很快就会消失,尤其是在截止日期临近时。关于管理 git 个子项目的不同方法的比较,已经有一个很好的答案 here。
关于工作流程,我将首先将您控制的存储库与非您控制的存储库分开,即第 3 方存储库。
对于不经常更改的第三方存储库(通过合并或上游 PR),您仍然可以使用子模块。通常,您会将这些子模块指向一些稳定标签的 HEAD。同步它们只是 运行 宁(或脚本)git submodule update --recursive --remote
的问题。如果这些第 3 方依赖项可以在包管理工具中指定,例如 bundler (for ruby projects),这将有助于简化您的子项目管理。
对于您拥有并经常更改的存储库,gitslave or git-subtree 是两种选择,具体取决于您团队的偏好。
gitslave 将 git 操作复用到多个分支中。 IOW,当您进行分支、合并、提交、推送、拉取等操作时,每个命令将依次 运行 在父项目和所有从属项目上。这要求团队以自上而下的方式工作,从超级项目开始到奴隶。
gitsubtree 使用 Git 的 subtree merge
功能来实现与子模块类似的效果,通过将文件实际存储在主存储库中并将更改直接合并到该存储库.最终结果是一个规范的存储库,可以选择包含所有子项目的历史记录。在某种程度上,这允许团队成员更多地关注他们负责的子树,但需要额外的工作才能合并回父树。
作为一名开发人员,我的偏好是在较低的子项目级别工作(做我的 "red, green, refactor" cycle),并且仅在必要时才接触父项目。但无论您选择自上而下还是自下而上的工作流程,请尝试在您的分支和合并策略中找出重复容易出错的步骤,并尽可能编写脚本。
我遇到了同样的问题,不是100个子模块,而是大约15-20个,我构建了一个cli来协助提交,推送,拉取,变基,结帐等。我也用过hard linking 在我的应用程序中,因此 cli 也可以处理,但没有必要硬 link。 cli 是用 go 编写的,并且有针对各种 os 平台
的版本
对于我的应用程序,我的工作流通常有一个“.boiler”文件夹,我的所有子模块都在其中,然后我将 .boiler 中的 link 文件硬到我的应用程序的 "src",然后当我对 linked 文件进行编辑时,它会更新 gitsubmodule
中的源文件
这是带有安装说明的 cli 的 link,当然您可以只下载版本并将其添加到全局 PATH
中的任何路径
使用 monorepo 更好。子模块的明智原因是,如果您需要不同的包具有不同的访问权限。
如果是这种情况,则根据访问权限将代码拆分为单独的 monorepos。然后使用 https://github.com/ingydotnet/git-subrepo 允许所有 monorepos 在一个单一的 monorepo 中。
我一直在研究 git 子树和 git 子模块的其他替代方案。我的项目有 100 多个子模块,管理它们非常笨重。
任何人都可以推荐一个工作流程,该工作流程非常适合需要保持同步的大量存储库。
如果您的项目有超过 100 个 git 组件和依赖项的子模块,无论您使用哪种方法,它们的管理都将变得笨拙 :-) 我建议寻找尽可能多的脚本和自动化部分的方法.相信我,对大多数人来说,使用和链接 git 命令的新鲜感很快就会消失,尤其是在截止日期临近时。关于管理 git 个子项目的不同方法的比较,已经有一个很好的答案 here。
关于工作流程,我将首先将您控制的存储库与非您控制的存储库分开,即第 3 方存储库。
对于不经常更改的第三方存储库(通过合并或上游 PR),您仍然可以使用子模块。通常,您会将这些子模块指向一些稳定标签的 HEAD。同步它们只是 运行 宁(或脚本)git submodule update --recursive --remote
的问题。如果这些第 3 方依赖项可以在包管理工具中指定,例如 bundler (for ruby projects),这将有助于简化您的子项目管理。
对于您拥有并经常更改的存储库,gitslave or git-subtree 是两种选择,具体取决于您团队的偏好。
gitslave 将 git 操作复用到多个分支中。 IOW,当您进行分支、合并、提交、推送、拉取等操作时,每个命令将依次 运行 在父项目和所有从属项目上。这要求团队以自上而下的方式工作,从超级项目开始到奴隶。
gitsubtree 使用 Git 的 subtree merge
功能来实现与子模块类似的效果,通过将文件实际存储在主存储库中并将更改直接合并到该存储库.最终结果是一个规范的存储库,可以选择包含所有子项目的历史记录。在某种程度上,这允许团队成员更多地关注他们负责的子树,但需要额外的工作才能合并回父树。
作为一名开发人员,我的偏好是在较低的子项目级别工作(做我的 "red, green, refactor" cycle),并且仅在必要时才接触父项目。但无论您选择自上而下还是自下而上的工作流程,请尝试在您的分支和合并策略中找出重复容易出错的步骤,并尽可能编写脚本。
我遇到了同样的问题,不是100个子模块,而是大约15-20个,我构建了一个cli来协助提交,推送,拉取,变基,结帐等。我也用过hard linking 在我的应用程序中,因此 cli 也可以处理,但没有必要硬 link。 cli 是用 go 编写的,并且有针对各种 os 平台
的版本对于我的应用程序,我的工作流通常有一个“.boiler”文件夹,我的所有子模块都在其中,然后我将 .boiler 中的 link 文件硬到我的应用程序的 "src",然后当我对 linked 文件进行编辑时,它会更新 gitsubmodule
中的源文件这是带有安装说明的 cli 的 link,当然您可以只下载版本并将其添加到全局 PATH
中的任何路径使用 monorepo 更好。子模块的明智原因是,如果您需要不同的包具有不同的访问权限。
如果是这种情况,则根据访问权限将代码拆分为单独的 monorepos。然后使用 https://github.com/ingydotnet/git-subrepo 允许所有 monorepos 在一个单一的 monorepo 中。