多项目服务器的GIT仓库布局

97

我喜欢我设置的Subversion的其中一件事是,我可以拥有一个单一的主仓库,并包含多个项目。当我想要在一个项目上工作时,我只需检出该项目即可。像这样:

\main
    \ProductA
    \ProductB
    \Shared

那么

svn checkout http://.../main/ProductA
作为一个新手使用Git,我想在承诺特定工作流程之前探索一些最佳实践。从目前为止阅读的内容来看,Git将所有内容存储在项目树的根目录下的一个单独的“.git”文件夹中。因此,我可以选择以下两种方法之一:
  1. 为每个产品设置单独的项目。
  2. 设置一个单一的大型项目,并将产品存储在子文件夹中。
这些产品之间存在依赖关系,因此单个大型项目似乎更合适。我们将使用一个服务器,所有开发人员都可以共享他们的代码。我已经通过SSH和HTTP使其正常工作,我很喜欢这一部分。然而,在SVN中的仓库已经有很多GB大小,所以在每台机器上拖动整个仓库似乎不是一个好主意,特别是因为我们需要支付过度网络带宽的费用。
我想Linux内核项目仓库的大小也是如此巨大,因此必须有一种处理Git的正确方式,但我还没有弄清楚。
是否有任何针对使用非常大的多项目仓库的指南或最佳实践?
2个回答

65

关于Git限制,指南很简单:

  • 每个项目一个仓库
  • 主项目包含子模块

这个想法不是把所有东西都存储在一个巨大的git仓库中,而是建立一个小型的仓库作为主项目,它将引用其他仓库的正确提交,每个仓库代表自己的项目或公共组件。


OP Paul Alexander 评论

这听起来与Subversion提供的"外部支持"类似。
我们尝试过这个方法,发现不断更新外部版本引用非常麻烦,因为项目是并行开发的,彼此之间有依赖关系。还有其他选择吗?

@Paul:是的,你可以选择以下两种方法代替从主项目更新版本:

  • 直接从主项目中开发子项目(如“True Nature of submodules”中所述),
  • 或者在子存储库中引用一个指向另一个正在开发同一子存储库的origin:然后你只需要从该子存储库中拉取在其他地方进行的更改即可。

在这两种情况下,你都不能忘记提交主项目以记录新配置。这里没有需要更新的“external”属性。整个过程更加自然。

老实说,这听起来很麻烦,任何需要开发人员每次手动执行的操作都会成为错误和维护的常见来源。
我想我会考虑在超级项目中使用一些脚本来自动化这个过程。

我回复道:

说实话,在最新的Git发布1.7.1之前,你可能是对的。但是现在不一样了。即使从主项目执行,git diffgit status都学会了考虑子模块状态。你不能错过子模块的修改。
话虽如此:

1
@VonC:这听起来很像Subversion提供的“外部支持”。我们尝试过这种方法,但发现不断更新外部版本引用非常麻烦,因为这些项目是并行开发的,彼此之间存在依赖关系。还有其他选择吗? - Paul Alexander
@Paul:是的,与其从主项目更新版本,你可以直接在主项目中开发子项目(参见https://dev59.com/mXI-5IYBdhLWcg3wMFMf#1979194),或者在子仓库中引用一个指向正在其他地方开发的同一子仓库的源:从那里,你只需要从该子仓库拉取在其他地方进行的更改。在这两种情况下,你都不能忘记提交主项目以记录新配置,没有“外部”属性需要更新。整个过程更加自然。 - VonC
3
@Paul:老实说,你可能是对的...直到最新的Git版本1.7.1。(http://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.7.1.txt)`git diffgit status`都学会了考虑子模块状态,即使从主项目执行。你绝对不能错过子模块修改。 Translated: @Paul: 说实话,你可能是正确的... 直到最新的 Git 发布版本 1.7.1。(http://www.kernel.org/pub/software/scm/git/docs/RelNotes-1.7.1.txt)`git diffgit status` 都已经学会考虑子模块状态,即使是从主项目中执行。你不可能漏掉子模块的修改。 - VonC
@Cawas:嗯,如果你看一下https://dev59.com/HEXRa4cB1Zd3GeqPsYe4#210289,David在3年零3个月后才接受了我的帖子作为实际答案。 - VonC
1
在 @PaulAlexander 说些什么之前,我选择相信他现在实际上正在使用子模块。 - cregox
显示剩余4条评论

2
GitSlave让你可以将多个独立的仓库作为一个整体进行管理。每个仓库可以通过常规的git命令进行操作,同时gitslave允许你在所有仓库上额外运行一个命令。
super-repo
+- module-a-repo
+- module-b-repo

gits clone url-super-repo
gits commit -a -m "msg"

Repo-per-project(每个项目一个仓库)具有组件化和使用Maven等工具简化构建的优点。

Repo-per-project通过限制开发人员更改的范围(例如错误提交或垃圾代码)来提供保护。


你能否包含一些关于gitslave和git子模块的优缺点的内容? - M.M
1
Gitslave的最大优点是它让你的Git仓库独立存在。你可以使用普通的git命令管理仓库,而不会影响gitslave之间的关系。但是当你想要在所有仓库中执行一个标签时,gitslave可以做到。 - Andre
1
子模块,在我看来,充满了复杂性。开发人员需要深入理解并与之密切合作。 - Andre

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