转到git时,如何处理大型svn历史记录?


23

编辑:与某些类似的问题不同,例如将多GB SVN存储库移至Git/programming/540535/managing-large-binary-files-with-git 我的方案不涉及几个子项目可以很容易地转换为git子模块,也不能转换为一些非常适合git-annex的非常大的二进制文件。它是一个单一的存储库,其中的二进制文件是测试套件,与相同修订版的主要源代码紧密耦合,就像它们是编译时资产(例如图形)一样。

我正在研究从svn切换旧的中型/大型(50个用户,60k修订,80Gb历史记录,2Gb工作副本)代码存储库。随着用户数量的增加,主干中流失很多,并且功能通常分散在多个提交上,这使得代码审查变得困难。同样,如果没有分支,就无法“排除”不良代码,只有在提交到主干才能进行检查。我正在研究替代方案。我希望我们可以转到git,但遇到一些问题。

就git而言,当前仓库的问题是大小。那里有很多旧文件,转换为git时用--filter-branch清理它可以将文件大小减小一个数量级,大约为5-10GB。这仍然太大。大型存储库的最大原因是,有很多二进制文档正在输入到测试中。这些文件的大小在.5mb到30mb之间,有数百个。他们也有很多变化。我看过子模块,git-annex等,但是在子模块中进行测试感觉很不对劲,对许多想要完整历史记录的文件都有附件也是如此。

因此,git的分布式特性实际上是阻止我采用它的原因。我并不真正在乎分布式,我只想要便宜的分支和强大的合并功能。就像我假设99.9%的git用户那样,我们将使用一个有福的,裸露的中央存储库。

我不确定我是否理解为什么每个用户在使用git时都要拥有完整的本地历史记录?如果工作流不是分散的,那么该数据在用户磁盘上做什么?我知道在git的最新版本中,您可以使用仅具有最新历史记录的浅表克隆。我的问题是:将其作为整个团队的标准运作模式是否可行?可以将git配置为始终很浅,以便您只能在中央拥有完整的历史记录,但是默认情况下,用户只有1000转的历史记录?当然,可以选择仅将1000 revs转换为git,并保留svn repo用于考古。但是,在这种情况下,在对测试文档进行了数千次修订之后,我们将再次遇到相同的问题。

  • 什么是使用Git含有许多二进制文件,你大回购了良好的最佳实践希望历史?大多数最佳实践和教程似乎都避免了这种情况。他们解决了几个巨大的二进制文件的问题,或建议完全删除二进制文件。
  • 浅克隆是否可作为正常操作模式使用?还是“骇客”?
  • 子模块是否可以用于在主源版本和子模块版本之间具有严格依赖性的代码(例如,在编译时二进制依赖性或单元测试套件中)?
  • git存储库(在内部)的“太大”是多少?如果可以将其降低到4GB,我们应该避免切换吗?2GB?


我搜索了很多有关此方面的信息,但没有找到任何可以回答我的问题的信息。在链接的问题中,workaounrds(子模块,附件等)将比我的方案好得多。
Anders Forsgren 2015年


Perforce可能比git更好的选择,因为它是为应付许多大型二进制文件而设计的,因此被许多游戏开发人员使用。Plasticscm也值得一看。
伊恩

顺便说一句:尽量避免git子模块,因为它们会使构建系统过于复杂(在您的情况下这已经很复杂)。
IgorGanapolsky '16

Answers:


10

哇,这是一个很长的问题(也是一个复杂的问题)。我会尽力去做的。

我不确定我是否理解为什么每个用户在使用git时都要拥有完整的本地历史记录?

这是git的主要设计决策。出于确切的原因,您需要询问作者(Linus Torvalds),但据我所知,主要原因是速度:将所有内容都本地化(在快速磁盘上,甚至缓存在RAM中)可以使历史操作更快通过避免网络访问。

大型存储库的最大原因是,有很多二进制文档正在输入到测试中。这些文件在.5mb和30mb之间变化,并且有数百个。他们也有很多变化。

我首先要考虑的是这一点。在源代码管理中有这么多不断变化的二进制文件对我来说似乎是个问题(即使使用SVN)。您不能使用其他方法吗?想法:

  • 与源代码不同,一个3 MB的二进制文件可能不是手工编写的。如果某个工具/流程生成了它,请考虑将其集成到您的构建中,而不是存储数据。

  • 如果那不切实际,那么通常在工件存储库(例如Artifactory for Maven&co。)中最好使用二进制文件。也许这是您的选择。

我看过子模块,git-annex等,但是在子模块中进行测试感觉很不对劲,对许多想要完整历史记录的文件都有附件也是如此。

实际上,这看起来像git-annex非常合适。git-annex基本上允许您将文件内容存储在git存储库外部(该存储库包含占位符)。您可以通过多种方式存储文件内容(中央git repo,共享驱动器,云存储...),并且可以控制要本地存储的内容。

您是否可能误解了git-annex的工作原理?git-annex确实存储了它管理的所有文件的完整历史记录-它只允许您选择要在本地拥有的文件内容。

最后,关于您的问题:

将git与包含您想要历史记录的许多二进制文件的大型存储库一起使用的最佳做法是什么?

以我的经验,这些选项通常是:

  • 避免在存储库中使用二进制文件(按需生成它们,将它们存储在其他位置)
  • 使用git-annex(或类似的解决方案,例如Git LFS)
  • 与大型仓库一起使用(并非所有git操作都受大型文件影响,并且如果您有快速的计算机和驱动器,那么它可能会非常有用)

浅克隆是否可作为正常操作模式使用?还是“骇客”?

那可能是可行的。但是,我认为这不会解决您的问题:

  • 您将失去具有完整历史记录的git的好处,例如快速搜索历史记录
  • 合并可能会变得棘手,因为AKAIK必须至少将历史记录返回到分支点才能进行合并
  • 用户需要定期重新克隆,以使克隆的大小保持较小
  • 这只是使用git的一种不常见的方式,因此您可能会遇到许多工具的问题

git存储库(在内部)的“太大”是多少?如果可以将其降低到4GB,我们应该避免切换吗?2GB?

这取决于存储库的结构(少量/许多文件等),要执行的操作,计算机的功能强大以及耐心:-)。

让您快速了解一下:在我的(新的但低规格的)笔记本电脑上,提交500 MB的文件需要30到60秒。仅列出历史记录(git log等)不受大文件的影响;必须扫描文件内容的“ git log -S”之类的东西非常慢-但是,速度主要由I / O主导,因此这并不是git的错。

在具有少量修订的3 GB存储库中,“ git log -S”大约需要一分钟。

所以我想说几个GB是可以的,尽管并不理想。超过10-20 GB的空间可能会推动它,但它可能是可行的-您必须尝试一下。


感谢您的详细答复。我一定会考虑使用附件作为测试文件。“合理的性能”的门槛可能是“接近svn”,即,如果任何操作的速度都显着降低,则切换起来会产生太多摩擦。
Anders Forsgren 2015年

我认为Git LFS也可以用于大型二进制文件存储。
IgorGanapolsky '16

@IgorG .:是的,Git LFS是替代方法,还有其他方法。感谢您指出来,我编辑了帖子。
sleske '16

4

随着用户数量的增加,主干中流失很多,并且功能通常分散在多个提交上,这使得代码审查变得困难。另外,如果没有分支,就无法“排除”不良代码,只有在提交到主干后才能进行检查

迁移到git并不能解决这些问题,它们是您如何使用该工具的问题,如果您以相同的方式使用git,这些问题仍然存在。

您可以像在git中一样轻松地在svn中进行分支,并且合并通常同样容易并且具有相同的陷阱。Git是为使用内核源代码而设计的,因此它做出了一些可能并非在所有情况下都适用的假设,例如您的二进制文件过多且历史悠久。DVCS的目的是让每个用户有效地单独工作,然后才进行协作-即他们有自己的存储库(副本),按照自己喜欢的方式工作,然后将更改推给其他需要它的人。在Linux内核开发中使用的联合系统非常适合此操作-您将更改推送到链中的下一个家伙,后者将其与他的代码库合并,然后将其推送到下一个家伙,直到到达将其放入发行版的Linus。大多数团队使用git的方式相似,但只有一个上游家伙,通常是服务器端的“黄金”仓库,

因此,我将首先考虑更改您的工作流程,只有在您拥有更好的工作方式后才迁移到git。如果不重命名文件或目录,则可以在SVN中实现分支和合并。


4
“您可以在git中轻松地在svn中进行分支,并且合并通常同样容易并且具有相同的陷阱”,哇,这确实是一个有争议的主张。我认为,在git中进行合并通常很容易,而在svn中通常是一场噩梦,即使在引入半跟踪合并跟踪尝试之后的版本中也是如此(是的,我确实使用git,而不仅仅是在此repo上工作)。我们拥有的工作流程是您创建功能分支的过程,在该分支上进行代码审查/ CI。没有巨大的挫败感,SVN不可能做到这一点。
Anders Forsgren 2015年

2
不,我们一直在这里做。我只是通过SVN存储库中的157个分支来查看可以删除的分支。我们几乎每天都在这里分支,开发,审查然后合并,偶尔会遇到麻烦,但这总是可以通过从主干上撤下新分支并合并所做的更改来解决(以便以后可以轻松合并回主干) 。不过,这仅适用于古代分支。如果您有极大的挫败感,那么您将无法充分理解它。Git也会给您带来极大的挫败感。
gbjbaanb 2015年

2
我只是没有经验。当使用git时(就像我说的那样,但是在较小的回购协议中),我发现进行功能分支,重新设置基数,压缩和合并非常容易和自然。“重命名后的树冲突”等感觉很少见,可以模拟线性和简单的历史记录(通过rebase + squash等)非常重要。因此:为了使问题保持​​话题(带有大量回购的git):让我们假设svn不支持我需要的工作流程,而git支持。
Anders Forsgren 2015年

1
在以前的公司中,我们使用git,我知道那里曾经有人经常使用git失去工作,因此无论如何它都不是一个完美的系统!SVN也不是,但是SVN比git IMHO更适合您的情况,并且确实有效。在主题上,如何使git像您想要的那样工作...对不起,我真的不确定。
gbjbaanb 2015年

7
@gbjbaanb如果某人失去了与Git的合作,那就是做错了什么。
RubberDuck

2

查看GCC邮件列表。目前(2015年8月和2015年9月)讨论了将GCC编译器的源树从SVN 迁移到GIT,同时保留了GCC的历史。请参阅例如存储库以获取git转换邮件线程的转换机制接受条件;您会找到与转换相关的工具和过程的参考(这看起来并不那么简单;这么大的代码库历史记录的转换需要36个小时,大约需要64GB RAM,IIRC)


您是说要从SVN迁移到Git吗?从版本控制系统迁移到编译器套件似乎有些奇怪。此外,这读起来更像是评论,而不是答案。
8bittree

是。抱歉打错了。
Basile Starynkevitch 2015年

谢谢。36小时听起来像微风,我们的声音可以在几周内发生转变……
Anders Forsgren 2015年

2

如果将整个SVN信息库转换为Git导致巨大的信息库无法克隆,则可以尝试使用 SubGit为Subversion存储库的某些部分创建较小的Git镜像。

例如,您可以导入和同步SVN信息库的某些子目录http://domain/repos/trunk/project/src

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

有关使用SubGit的更多详细信息,请参见其 文档

一旦有了该目录的Git镜像,就可以使用Git存储库提交新更改,这些更改立即反映在SVN存储库中。由于您仅同步了SVN信息库的某些部分,这会极大地缩小转换后的Git信息库的大小,因此您仍然可以创建分支,合并它们,从Git端使用任何工作流程。

另外,您可以导入整个SVN信息库,但从同步中排除大文件:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

最终的Git存储库应具有合理的大小,并且开发人员仍可以使用Git将其更改提交到Subversion存储库。

请注意,如果您准备保持Subversion服务器运行并在SVN存储库中使用Git,则此解决方案应该对您来说效果很好。

免责声明:我是SubGit开发人员之一;SubGit是商业软件,提供许多免费选项。


1

我希望通过以下方式来处理您的情况:

1)在与SVN存储库相同的目录中初始化git存储库。执行git initgit remote add origin开始该git repo。这样,您可以继续分别在SVN和git上进行提交,而无需处理从一个到另一个的完整转换,直到准备就绪为止。

2)积极使用bfgfilter-branch工具尝试缩小您的git repo,如下所述:https : //confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3)对于大型二进制文件,请使用git-annex或Git LFS,或仅使用外部存储服务器(在构建时使用Shell脚本传输文件)。

4)一旦您对git repo中的合并/分支策略感到满意,并且对git repo的大小感到满意,就可以从svn到git进行完全迁移。

希望这可以帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.