如何处理Git存储库的元存储库?

5
在项目目录中给定一个Git仓库的树形结构,例如:
Projects/
+A/
|+.git/
+B/
|+.git

我想建立一个名为Projects.git的git存储库,它不跟踪项目内容,只跟踪它们的存在和状态。克隆此存储库的人应该只有未克隆的存储库AB等的框架,并可以单独激活它们是否保持同步。典型的工作流程如下:
  • 首次设置:git clone server:Projects.git
  • 激活项目A,也会克隆它
  • 现在每个git-push/pull,无论是在Projects/还是在Projects/A中,都应该更新A.gitProjects.git关于A的信息。与B相关的任何内容都应被忽略,因为它是非活动的且本地为空
  • 激活项目B,也会克隆它
  • 现在,在Projects中进行任何git-push/pull操作都应该在AB中进行,而在A中进行的推送/拉取操作不应影响B
  • 停用项目A,之后(在验证A.git不需要git-push之后)清空本地目录A,对Project.git没有影响
如何最好地处理这个问题?我的当前方法是一些钩子魔法,但我对git子模块不够熟悉,无法确定是否可以使用子模块实现此目标,或者是否需要使用其他解决方案。
3个回答

7

3

这正是子模块的用途:
跟踪每个子仓库的确切配置(即确切的提交SHA1)。

如"如何在单行命令中git clone --recursive并检出所有子模块的主分支"所述,您可以使用一个命令克隆父仓库及其所有子模块。

如"子模块的真实本质"所解释的那样,您可以修改子模块,前提是要意识到每个子模块都处于分离头状态(您需要先检出一个本地分支),并且您需要先提交和推送子模块,然后再回到父仓库,在那里提交和推送(记录新配置,即新的子模块SHA1)。

您可以删除子模块目录,而不会损坏父仓库对该子模块的引用。


这位Tobias Kienzler 的评论

听起来有点像我想要的,但是分离的头在这种情况下相当无用 - 当我克隆一个子模块时,它应该在它的主头上。
基本上,我正在寻找一种方法,可以拥有所有项目的本地索引,而不必单独克隆它们,并且可以使用“同步当前已克隆的所有项目”的一键式命令。

我建议看一下git-slave:

Gitslave创建了一组相关的存储库——一个超级项目存储库和许多从属存储库,所有这些存储库都在同时开发,所有git操作通常应该在其中运行;因此,当您分支时,项目中的每个存储库依次分支。
同样,当您提交、推送、拉取、合并、标记、检出、状态、日志等时,每个git命令都会依次在超级项目和所有从属存储库上运行。

这听起来有点像我想要的,但是在这种情况下,分离的头部相当无用 - 当我克隆一个子模块时,它应该处于其主头部。基本上,我正在寻找一种方法,可以在不必逐个克隆它们的情况下,拥有所有可用项目的本地索引,并且有一个“同步当前已克隆的所有项目”的一键命令。也许使用git存储库来实现这一点实际上是个坏主意? - Tobias Kienzler
2
@TobiasKienzler 那你可以看看 git-slave,它更接近你想要的:http://gitslave.sourceforge.net/ - VonC
谢谢,我会看一下的。 - Tobias Kienzler

1

为什么不使用git已经提供的功能:

git submodule [--quiet] foreach [--recursive]

git submodule foreach git checkout develop
git submodule foreach git commit
git submodule foreach git push

1
这个问题的简单答案是指向许多关于子模块的不同文章;例如 https://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/ 等等。许多开发人员发现 git 子模块令人困惑,在许多情况下它们似乎是错误的解决方案。当然,有一些情况下它们似乎能够正常工作。为了得到一个好的答案,需要一个清晰的回答,说明它们何时适用以及如何避免陷阱。 - Michael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接