我正在将一个已有10年历史的大型CVS存储库迁移到Git。将这个多项目存储库分成几个Git存储库似乎很明显。但是决策者习惯了CVS,因此他们的观点受到CVS哲学的影响。

为了说服他们从一个CVS存储库迁移到不同的Git存储库,我需要给他们一些争论。说使用多个Git回购是使用Git的方式。我真的不知道为什么(他们给我一些想法)。我是该领域的新手,所以我在这里问我的问题。

使用多个Git存储库而不是使用包含来自不同团队的不同应用程序和库的单个Git存储库的论点是什么?

我已经列出了:


分支/标签影响整个Git存储库文件=>污染其他团队项目

4GB限制Git存储库大小,但这是错误的

git注释在膨胀的Git存储库上可能会变慢...





Eamon Nerbonne已经注意到相关的问题:在git存储库中选择单个项目还是多个项目?

团队经理最终接受拆分的原因:单个Git存储库(550 MB)需要13分钟才能在Windows上克隆(一分钟)在Linux上)。
膨胀的CVS存储库分为100个Git存储库:


一个存储库中的每个死应用程序
一个存储库中的每个稳定的库(源代码几乎再也没有改变)
将相关的应用程序/库保存在一个存储库中
将未用于编译(配置...)的大文件移动到其他存储库(Git不喜欢大文件)
将其他不相关的文件跳过(*.jar*.pcb*.dll*.so*.backup ...)


成功安装了Android开源项目使用的repo工具,以处理所有这些Git存储库:


在Linux上轻松安装
由于Cygwin和NTFS本机符号链接要求,在Windows上更加困难




评论

问题到底在哪里?

@JimMartens:Git用户通常使用多个Git存储库而CVS用户使用单个存储库的原因是什么? (每个可交付模块一个Git存储库?)感谢您的评论,我可能会更改问题的解释...最后,我更改了标题;-)

有吗我们曾经为不同的项目使用不同的SVN存储库。

谁说git用户使用多个较小的存储库?

请参阅:programmers.stackexchange.com/questions/161293/…

#1 楼

您正在处理多个团队和多个项目。

简短的答案是,您的团队和项目具有不同的需求和变化的依赖关系。

整体存储库方法减少了对“一切”的提交。在这种配置下稳定!!!” (即来自许多团队的不切实际的巨大承诺)。那或许多项目不兼容的中间点。无论哪种方式,在支持配置上都会浪费大量的精力,这简直是从来没有想过的。

您的存储库应改为独立构建,并应具有表示其依赖关系的多个存储库。依赖项应由项目维护人员在开发的适当位置进行配置,更新和测试。


ProjectA于3年前发布了其主要版本。它处于维护模式,具有“较旧”的系统要求。它应该引用一组适当的依赖项。它有20个依赖项。
ProjectB刚刚发布。它具有更现代的系统要求,并且由另一个团队开发和测试。它具有15个依赖库(= repos),其中10个与ProjectA共享。这些项目通常引用其依赖库的不同提交。依赖关系在开发的适当时点进行更新。
ProjectC尚未发布。它与ProjectB非常相似,但对其依赖项进行了重大更改和改进。 ProjectB的开发人员仅对获取与ProjectC共享的依赖关系的稳定版本感兴趣。 ProjectB的团队对共享依赖项做出了一些承诺,尽管它们大多数时候只是错误修正和优化。整体式存储库要么阻止ProjectC的开发以维持对ProjectA的支持,要么阻止ProjectC的更改使A和B中断,否则开发人员最终将最终不共享/重用代码。

分布式)存储库,每个团队可以独立工作并最大程度地减少对其他项目的影响,同时重用并不断改进代码库。当其他团队进行更改时,这也可以防止团队转移焦点/速度。集中式整体存储库使每个团队都依赖于每个团队的行动,并且必须同步。

评论


我正在审查我们的存储库数量。 monorepo的一个引人注目的优势是,像所有其他项目一样,对真正的全局文件(如系统配置)进行了版本控制。因此,monorepo将包含支持Project A的旧配置。

– John McGehee
18年4月6日在15:28

您在此处描述的内容与Google恰恰相反。 (该论文描述了为什么他们认为即使使用了20亿行代码,单片方法仍然效果更好。)

– cjs
18年4月17日在5:03

@ CurtJ.Sampson好吧……Google已经建立了一个内部版本控制系统,几个支持的实用程序,构建系统,有一个编译器团队等,所有这些都支持其工作流程。我的商店没有这些工具或团队。除非您为Google工作,否则您也不会拥有这些工具。 Google的Android代码库使用Git;他们使用了800多个Git存储库。这个问题是针对Git的,对吧? FWIW我通常通过以下方式构造我的存储库:A)具有几个共享库的大型存储库B)依赖于A和C的各种应用程序/项目存储库,以及具有各种媒体资产的单独存储库。

–贾斯汀
18年5月3日在4:42

我提出Google的例子是一家公司,它显然具有很高的技术水平,并发现只有一个回购协议如此引人注目,以至于他们愿意花费数百万美元来创建他们所需的独特系统。如果某人根本不理解为什么要付出这种努力,那么我希望他们显然应该思考的不是“ Google的错”,而是“这里我想念的东西”。但是,请多考虑一下,我想我需要添加一个答案,以适当的时间争论我的观点。

– cjs
18年5月3日在5:45

不用担心,@ justin,StackExchange网站上的答案不只是为您而写的,在您阅读我的文章之后,我也不会尝试。

– cjs
18年5月4日在1:22



#2 楼

在这个线程中似乎没有支持大型存储库的理由,所以这里是一个:

包含所有代码的大型存储库的优点在于,您拥有可靠的存储库。真理之源。您的总体项目中的所有状态都在该存储库的历史记录中表示。您不必担心诸如“从3个月前开始我需要构建哪个版本的libA?”之类的问题。还是“由于Susan更改libC或Bob更改libD而导致集成测试开始失败?”或“是否有要使用evilMethod()的调用者?”这都是历史。

将相关项目拆分为单独的存储库时,git不会为您跟踪它们之间的关系。您的构建系统需要知道在哪里可以找到所有依赖关系的代码,更重要的是要构建什么版本的代码。您可以“仅从master构建所有内容”,但是这使得很难重现过去的构建,难以进行需要在存储库之间同步的更改(或回滚),并且很难使分支保持稳定状态。

所以问题不是“一个大的回购还是多个小的回购?”它实际上是“使用工具的一个大仓库或许多小仓库”。您要使用什么工具? Google的Repo(Android)和gclient(Chromium)是两个示例。 Git子模块是另一个。所有这些都有主要缺点,您必须权衡大型仓库的缺点。

编辑:这里有更多答案在git存储库中的单个或多个项目之间进行选择?

PS:综上所述,我正在开发一种工具,希望可以使事情变得更好,例如当您必须拆分存储库或使用其他人的代码时:https://github.com/buildinspace/peru

评论


完全同意,将存储库任意拆分为多个存储库不一定是件好事。版本控制的含混性:没有一个事实来源可以用来构建整个项目-可维护性:您必须专门编写文档来告诉人们项目之间的关系以及如何将它们编译和合并在一起-工作流程:如果您经常在一个存储库中进行更改,然后从另一个存储库进行部署,则您将不断地需要将构建从一个项目复制到另一个项目,这与在同一存储库中进行构建相比似乎完全没有必要。

–克里斯·刘易斯
16-2-5在11:14

一个存储库和一个Dockerfile提供了一个共享的开发环境,该环境对于整个项目而言都是开箱即用的,从而节省了大量的时间和精力。另外,对于新开发人员而言,设置非常容易,并且与n个存储库相比,他/她不需要了解许多工作原理的详细信息,在n个存储库中,您需要知道x的哪个版本与y的哪个版本以及您需要放置的版本此文件夹具有这些文件权限,在工作一天后,可以编辑10个配置文件以具有登录页面,因为ah该库在Debian Wheezy上不可用。

– Aalex Gabi
16年8月8日在20:53

当涉及到代码共享时,我已经开始在多个存储库中感到痛苦。由于公共代码有很多不同的解决方案,因此您永远不能百分百确定不再使用某些代码。这带来了严重的可维护性问题。这与您在此处使用evilMethod()提到的内容一致。

– julealgon
18年5月18日在14:01

#3 楼

与大型存储库一起使用时,Git往往会遇到性能问题。

引用Linus:


git显然根本没有这种模型。 Git
从根本上看从来没有真正超过整个回购协议。即使您
限制了一些事情(例如,只检查了一部分,或者
历史可以追溯一小段时间),git仍然总是关心整个事情,并且

因此,如果您强迫git将所有内容视为一个巨大的存储库,那么git的缩放比例将非常糟糕。我认为该部分不是真正可修复的,
尽管我们可能会对其进行改进。


强调我的。这并不是说您公司的版本控制存储库“很大”,但这是人们倾向于避免在Git中使用大型存储库的原因之一。

评论


感谢您的链接;)这就是Google将code.google.com Git存储库限制为4 GB的原因。干杯

– oHo
2013年8月1日14:21



因此,基本上使用多个存储库只是性能优化?

–Eamon Nerbonne
13年15月15日在17:01

这是一项性能优化,但是我不确定这是否只是一项性能优化。根据AProgrammer的回答,它也是一种表示git中“模块”概念的方法。

–布赖恩
13年15月15日在18:59

在这里,我们需要说明清楚:使用Git作为源代码存储库(Android,Linux)实现的解决方案很少。这是肯定的证明,Git可以用于大型存储库。尽管确实需要其他技术

–布达
15年11月14日在22:48

Git还不支持很多能够提高拥有大型存储库能力的功能。这在SVN中效果很好,但在git中效果不佳,在git中,主要支持的工作方式是签出整个存储库,不仅签出所有文件夹,还签出所有历史记录。在git中很难完成很多事情,例如仅共享一个文件夹或使用外部文件(允许内部引用同一仓库)。

– jgmjgm
17年9月7日在11:16

#4 楼


他们想要[可以在所有项目中显示其更改的东西,而不是试图记住他们对[更改]所做的项目。。


Sourcetree(自由-be-beer GUI Git前端)允许您注册多个存储库,将它们组织成逻辑组,然后一次查看所有存储库中的状态:


我不隶属于他们以任何方式。

评论


Smartgit也这样做...但是更好。

– CAD bloke
16-2-27在8:50

@CADbloke现在SmartGit的界面如何?我记得在一两年前我在两者之间做出决定时,SourceTree显然比SmartGit更易于使用,因为SmartGit相当简单而且存在问题。我什至无法使我的差异工具正常工作

–user120242
16 Mar 10 '16 at 3:10

我喜欢。 SourceTree最近脱轨了。我购买了Smartgit,也将其用于汞。我喜欢其中的差异工具。它们非常相似,但我认为Smartgit最近取得了更多进步。

– CAD bloke
16 Mar 10 '16 at 3:14

您是否使用了Beyond Compare,我发现此差异工具比其他工具更好?它如何比较?

–user120242
16 Mar 10 '16 at 4:27

我知道这已经很老了,但是Sourcetree已经倒退了,或者我只是找不到左侧的概述窗格。我有每个回购的左中角(文件状态,分支等),而不是多个回购的那个。我如何获得它的任何想法(或者不再是?)

– JoelAZ
18年8月9日在23:44

#5 楼

TL; DR;等效于git存储库的是CVS模块,而不是CVS存储库。

CVS设计时将模块的概念定义为存储库的细分,通常将CVS存储库与多个模块一起使用过着很独立的生活例如,很容易拥有特定于一个模块的分支,而在另一个模块中却不存在。

git并未使用模块的概念进行设计,每个git存储库在CVS术语中仅限于一个模块。创建分支时,该分支对整个存储库均有效。

因此,如果要在git中导入具有多个模块的CVS存储库,则最好为每个模块创建一个存储库,尤其是当模块具有或多或少的独立生活,并且不共享分支和标签之类的内容。 (由于CVS和git中分支的使用模式不同,您甚至可以研究每个CVS分支具有一个存储库的有用性;但是对于从CVS到git的迁移,您的工作流程一开始可能会与一个值得付出痛苦的CVS工作流程)。

#6 楼

如果您愿意和他们一起打球以安抚,则可以通过这种方式进行设置。还是这种方法。除此之外,我认为他们只是期望进入系统的单个入口来访问资产。

根据访问需求,分离的GIT仓库可能仍然是更好的方法,因为“ John Smith”可能需要访问某些数据,但不需要访问其他数据。虽然“ Suzy Que”可能是需要访问所有内容的系统管理员。

如果使用单个存储库,则可能会遇到内部访问需求的问题。如果这是“每个人都可以完全访问”的类型,那么我可能会看到他们的观点。

评论


如果您总结链接中的方法,将会是一个更好的答案。

–钻机
13年7月31日在15:40

目前,每个开发人员都可以访问唯一的CVS存储库中的任何源代码。因此,他们并不关心开发人员可以访问唯一的Git存储库中的任何源代码。但是,这是切换到多个Git存储库的一个很好的优势,谢谢;-)但是,由于每个应用程序都有自己的分支/标签,所以我不明白您对分支模型的含义。干杯

– oHo
13年7月31日在15:47

嗨,威尔。再次阅读您的答案后,我会更好地理解您的意思(我指的是最后两段)。这是基础+1的一个好提示。请您在第一段中提供更多说明,而不要放置此链接?或者,您可以删除第一段...;)干杯

– oHo
13年11月18日在8:37



#7 楼

Eclipse的Git迁移帮助页面建议将CVS / SVN目录树重新组织到多个Git存储库中:现在是重构代码结构的好时机。
将当前CVS / SVN目录,模块,插件等映射到它们在Git中的新主目录。
通常,为每个逻辑代码组创建一个Git存储库(.git)。 -项目,组件等。


参数:


这里的权衡是,每个额外的Git存储库
给开发过程增加了额外的开销-
所有Git命令和操作都在单个Git存储库级别进行。
另一方面,每个存储库用户将拥有存储库历史记录的完整副本
,这使得非常大的存储库变得不方便
供临时贡献者使用。


#8 楼

Git可以一次在整棵树上运行,而不仅仅是在您所在的子目录上。 >并且假设这两个文件已更改:

C:\MyCode\ProjectABC


当您在项目根目录中并且处于git状态时,您将看到这些文件具有更改为:

C:\MyCode\ProjectABC\stuff.txt
C:\MyCode\ProjectABC\Stuff\MoreStuff\morestuff.txt


如果将cd转到MoreStuff目录,则只会看到morestuff.txt文件吗?否。相对于您的位置,您仍然会看到两个文件:

stuff.txt
Stuff\MoreStuff\morestuff.txt


因此,如果将所有项目集中在一起放在一个大的Git存储库中,那么每次您进行检入时,都必须从每个项目的更改中进行选择。

现在可以找到减轻这种情况的方法了;例如,您可以尝试确保至少要暂时提交更改,然后再切换到其他项目。但是,与简单地以正确的方式进行操作相比,团队中的每个人都必须处理大量的开销:每个项目一个Git存储库。

评论


谢谢您的支持,我同意;)但是,大多数习惯CVS的开发人员不同意这种行为:他们希望WinCVS在所有项目中显示其更改,而不是记住自己所做的更改是什么(如果您更改多个目录中有关同一修订的几个文件,则可能会忘记提交这些文件之一)。 AOSP的仓库工具允许混合多个Git仓库,仓库状态显示所有项目的变化;)

– oHo
13年11月18日在8:30



git diff和git add之类的命令带有目录参数,可以解决这个问题,如果这对您来说是个问题。通常,尽管如此,我发现自己遇到了相反的问题,因为有些不可知的变化使我感到困惑。

–杰克·奥康纳(Jack O'Connor)
15年3月28日在22:28