在文件系统上组织数以百计的Git存储库

大量文件和目录的组织一直是一个问题,如果经常需要在目录树里转来转去,就会特别痛苦。大量Git存储库的管理就属于此类问题,为此我创建了一些工具来缓解问题。尽管这些工具主要被用于Git存储库的管理,但相同的思路也适用于其他领域。

将Git存储库视作单一事实来源:git-list

市面上有很多对Git存储库进行批量管理的工具,但没有一个工具以将Git存储库视作单一事实来源的方式对待它们,于是我创造了git-list。尽管泛用化的工具会更符合Unix原则,但我认为这个场景不太适合,尤其是考虑到下一个工具的情况下。

在git-list的语境下,将Git存储库视作单一事实来源来管理意味着:

  • Git存储库的远程URL被认为具有唯一性和稳定性,git-list会基于远程URL维护一个目录结构。

  • 由git-list维护的目录结构不应该被人工修改,只能通过git-list修改。

在使用git-list前,需要由用户手动创建一个YAML文件,该文件记录了一个列表,每个列表项都是存储库的URL。在使用git-list时,需要首先用git-list的clone子命令,基于事先定义的列表在当前目录下批量克隆所有存储库,之后所有批量操作都将基于此列表执行。

由git-list克隆的存储库,其路径将以远程URL为基础按规则生成:https://github.com/BlackGlory/git-list.git将会生成路径github.com/BlackGlory/git-list,很容易推理。这个路径只有在Git存储库发生所有权转移和重命名的情况下会发生变化。

现在你得到了一个组织结构严谨且容易推理的目录,以及批量操作此目录的工具,但这最多只让我们摆脱了命名和存储Git存储库时的混乱,还不足以改善在目录树里转来转去特别痛苦的问题。接着我们需要另一个工具,以利用单一事实来源带来的好处。

通过标签系统和符号链接生成符合人体工程学的目录:garland

缓解在目录树里转来转去的痛苦,需要我们建立合理的目录结构。但在我们有单一事实来源之前,实现一个合理的目录结构很困难,因为随意移动目录不仅会带来混乱,还无法解决同一个目录同时被两个不同的上下文使用的问题。有经验的人在这种情况下会尝试用符号链接解决问题,但很快就会因为输入命令的繁琐和穿梭于各个目录产生的认知负荷而疲惫不堪。在缺乏指导方针的情况下,组织出一个合理的目录本身也并不容易。尤其是在你有数以百计的Git存储库时,手动组织目录基本上是不可能的,即使有人做到了,也没能力应付未来的变化。

garland是解决层级结构生成问题的自动化工具,它通过引入可计算的标签系统来可维护地解决上面提到的问题。在使用garland后,建立合理目录结构的问题就被简化为了“设计一个符合需求的标签系统”

和git-list类似,garland也依赖事先编写的文件来驱动。garland需要两个文件来工作:

  1. 1.

    标签定义文件,该文件定义了能被garland识别的目录及其具有的标签。我们在此利用git-list生成的具有唯一性的稳定的存储库路径,为每一个存储库打上标签。

  2. 2.

    蓝图文件,该文件定义了生成的目录的结构,每个结构都可以包含一个条件表达式,条件表达式的结果决定了一个源目录是否应该在此创建相应的符号链接。条件表达式是我在garland里发明的一种用于标签系统的逻辑计算领域特定语言,通过它,用户可以以andornot这样的逻辑运算符来计算标签。举例来说,如果一个目录在标签定义文件里有librarypublic两个标签:library and public的计算结果为真,在此创建目录的符号链接;library and private的计算结果为假,不在此创建目录的符号链接。为了便于使用,层级结构将自带and语义,并且条件表达式支持用括号改变运算优先级。