将代码组织成 Git 个子模块

Organizing Code Into Git SubModules

我想知道 Git 子模块是否合适 我目前保留在 RCS 下的一些代码的组织,如果 那么,应该如何组织子模块。

模块总纲

假设我有一组库模块(也许是图书馆,也许 部分单库;这是一个待讨论的项目)。 假设其中一些模块是基础模块,而其他模块依赖于 在基本模块上。 所有这些模块都旨在供其他打包使用 软件(程序),大概包括适当的 选择这些包作为子模块。

具体来说,库模块是:

许多其他程序使用 stderr。 相当多的那些使用也使用 filter (以及所有使用的代码 filter也直接用stderr),但是有相当多的 使用 stderr 但不使用 filter 的程序。 有些程序使用debug;基本上所有这些程序也使用 stderr 直接,但他们可能会也可能不会直接使用 filter。 使用 phasedtest 的单元测试程序可能会或可能不会使用 stderrfilterdebug 直接(他们更有可能使用 stderr 而不是 其他人),但 phasedtest 本身需要它们,所以这样的程序总是 间接使用这些模块。 有些程序可能会使用 rational;通常他们也会使用 stderr (我写的几乎所有东西都使用 stderr),但那些程序不 一般直接用phasedtest自己,

澄清一下:目前,这些潜在的 Git 模块和 子模块根本不在 Git 中;他们中的大多数有广泛的(10-30 年)在 RCS(Y2K 之前的 SCCS)中的历史,当 它们被转换为 Git。 目的是在适当的时候将所有回购协议放入 GitHub。 总的来说,这些模块都相当稳定。 它们确实得到修订或扩展,但不一定每年。 有时,三年或更长时间过去了,其中一些没有改变。 我有一个 build/distribution 系统,其中的文件构成了什么 可能成为子模块被拉入更大的分布 准备发布时的程序。 在正常(单人)开发过程中,material 生活在 将数百个源文件内置到一个(静态)库中 库(在 $HOME/lib 中)和单个头目录($HOME/inc, 类似于但完全独立于 /usr/include/usr/local/include).

我正在寻求结构 "right" — 足够正确,我 不会后悔我所做的一切 — 在将它们转换为 Git 之前。 我还有版本标记和标记问题需要解决;那是一个 整个单独的 bag'o'worms 而不是这个问题的一部分。

应该如何组织子模块?

根据我对子模块的理解,似乎是:

出现的问题

  1. filterdebug都独立需要stderr子模块 (但他们不太可能在很大程度上依赖于任何特定的 stderr 的版本——几乎任何发布级别的工作版本 10 个就够了)。因此,他们都需要在子模块中使用 stderr 版本。

  2. 有多少图书馆:应该有多少?选项包括:

    • 是否应该有三个独立的库:libstderrlibdebug、 和 libfilter?
    • 或者 libfilter 应该包含 stderr 中的 material,并且 libdebug 应该包括 stderr 中的 material(两个 库)?
    • 或者应该有一个复合库 libjlss stderrdebugfilter的元素在里面?
    • 如果共享库而不是共享库,答案会有所不同吗? 静态?
  3. phasedtest代码是否应该组织成第四个库 包含模块 stderrfilterdebug 作为子模块 (这样 stderr 就会出现三次,一次是直接 依赖和两次作为 debugfilter 的依赖),或者 它应该是一个需要与三个链接的较小的库吗? 独立的依赖库?

  4. 由于rational模块只需要phasedtest进行测试, 它不会安装 phasedtest 库。 但它将需要它们可用于测试。 如果它需要预安装的 phasedtest 库 (libraries), 或者它应该是独立的并且有必要的代码 将测试作为其分发的一部分?

  5. 使用 rational 的程序也可能使用 stderr(可能会), 但可能会或可能不会使用 debugfilter,并且会是 不太可能使用 phasedtest 除了自己的单元测试 组件。

主要问题

辅助问题

你的前两个问题("are git submodules appropriate?" 和 "how should I organize them?")不太适合 Whosebug:答案将主要是意见问题,而且很难确定"correct".

形式的任何单一答案

你的辅助问题更容易解决:

Is there a minimum sensible size for a repository?

不是,不是。

Is there a maximum sensible number of submodules for a single repository?

同样,不,但是在创建包含数百个子模块的怪物存储库之前,请确保您熟悉使用它们首先。人们对如何最好地管理子模块有不同的看法。 Here is one person 谁花了点时间思考。我不同意他所有的想法,但这至少是开始思考这个问题的一种方式。

Does it matter if a single submodule is a sub-submodule of a number of of submodules used by a single repository?

不完全是,不,虽然如果你有多个存储库实例分散在你的源中,你可能会 运行 进入版本偏差问题(例如,一个在版本 A 而另一个在版本 B 和另一个版本 C) 除非你非常小心。

Is there a conventional directory structure for submodules? All directories directly in the top-level directory, or some in standard directory name in the root directory, or in quasi-random locations in the superproject directory hierarchy?

没有,但通常你会选择适合你的东西并坚持下去。我见过许多将子模块放入 libmodules 目录的项目,而其他项目则将它们放在顶层。

Are there any glaring gotchas that I've not spotted?

请记住,当作为子模块签出时,当前 HEAD 由父存储库管理。也就是说,如果你 cd 进入一个子模块,进行更改,推送它们,然后在父项目 运行 git submodule update 中,你将回滚子模块的本地副本到任何提交记录在parent.

正是出于这个原因,我通常将子模块视为存储库的只读实例,只能由 运行ning git pull 更新(随后在父存储库中提交) ).我只在存储库的独立签出中编辑文件。

您需要训练自己定期 运行 git submodule update 将新更改拉入父存储库(以防这些更改包括子模块的新版本)。

如我所见,您有 3 个选项子模块、子树或依赖项(预构建的静态库)。我最近一直在使用子模块,这是一种将 git 存储库放入 git 存储库并跟踪您的根存储库正在使用的子模块存储库提交的方法。如果您需要在子模块中进行更改,您应该使用子模块,否则请使用子树或依赖项。

要使用依赖项,您需要某种可以打包和解析依赖项的工具——依赖项管理器。那里有一些,但我还没有找到任何通用的,并且没有嵌套构建工具。