2025-01-27 07:00:03

嵌套的Git存储库?

我可以嵌套Git存储库吗?我有:

 /project_root/
 /project_root/my_project
 /project_root/third_party_git_repository_used_by_my_project

git init/add /project_root是否有意义,以简化本地所有内容的管理,还是我必须分别管理my_project和第三方项目?


我将为每个项目使用一个存储库。这样,历史就更容易浏览了。

我还会检查我正在使用的第三方库的版本,到使用它的项目的存储库中。


您可能正在寻找称为子模块的Git特性。该特性帮助您管理嵌套在主存储库中的依赖存储库。


将第三方库放置在单独的存储库中,并使用子模块将它们与主项目关联起来。这里是一个演练:Git工具-子模块(Pro Git书籍,第2版)。

在决定如何分割回购时,我通常会根据修改它们的频率来决定。如果它是一个第三方库,并且只有你对它所做的更改才会升级到新版本,那么你一定要将它与主项目分开。


Git-subtree将帮助您在单个树中处理多个项目,并为它们保留可分离的历史记录。


为了完整起见:

还有另一个解决方案,我推荐:子树合并。

与子模块相比,它更容易维护。 您将以正常的方式创建每个存储库。 在主存储库中,您希望合并主目录下的另一个存储库的主存储库(或任何其他分支)。

$ git remote add -f ThirdPartyGitRepo /project_root/
$ git merge -s ours --no-commit ThirdPartyGitRepo/master
$ git read-tree --prefix=third_party_git_repository_used_by_my_project/ -u ThirdPartyGitRepo/master
$ git commit -m "Merge ThirdPartyGitRepo project as our subdirectory"`

然后,为了将其他存储库拉到你的目录中(更新它),使用子树合并策略:

$ git pull -s subtree ThirdPartyGitRepo master

我用这个方法已经很多年了,它是有效的:-)

关于这种方式的更多信息,包括将其与子模块进行比较,可以在git howto文档中找到。


你可以加上

/project_root/third_party_git_repository_used_by_my_project

to

/project_root/.gitignore

这应该可以防止嵌套回购被包含在父回购中,并且您可以独立地使用它们。

但是:如果用户在父repo中运行git clean -dfx,它将删除被忽略的嵌套repo。另一种方法是对文件夹进行符号链接并忽略符号链接。如果你然后运行git clean,符号链接将被移除,但“嵌套”的repo将保持完整,因为它实际上驻留在其他地方。


总结。

我可以嵌套git存储库吗?

是的。但是,默认情况下,git不会跟踪嵌套存储库的.git文件夹。Git具有专门用于管理嵌套存储库的特性(请继续阅读)。

git init/add /project_root是否有意义,以简化本地所有内容的管理,还是我必须分别管理my_project和第三方项目?

这可能没有意义,因为git具有管理嵌套存储库的特性。Git内建的用于管理嵌套存储库的特性包括子模块和子树。

下面是一个SO问题,涵盖了使用每种方法的利与弊。