尽管大家都认为Git是广为采用的最好的版本控制软件,但它仍然远远不够完美。有些问题可以用第三方工具来解决,但要把整个代码库都复制到开发者的电脑上时却可能会坏事。微软在试图将他们的300GB的代码库从内部系统迁移上Git时发现了这个问题。因此催生了Git虚拟文件系统(Git Virtual File System,GVFS)。
故事要从大概2000年左右开始讲起,当时微软是主要在使用一套名为“Source Depot”的内部系统,这是Perforce的一个分支。慢慢地,许多团队都换用了TFVC,即Team Foundation Server(TFS)里原来用的版本控制系统,但许多大型团队却没办法判断要花多少代价才能从Source Depot上迁移出来。同样,许多团队都是使用了TFS的部分功能,但具体用的是哪一部分却因团队而异,还各自混用了许多第三方工具及内部开发的工具。
为了努力简化这样复杂的环境,微软决心将用于工作计划、自动构建和源码控制等的Visual Studio团队服务(即云上TFS)相关的许多团队标准化。其中的最后一点,就是和Git一起提供的VSTS。
为什么是Git呢?根据微软员工,以及reddit的用户jeremyepling的想法,主要有三点原因:
Git和GitHub上的公共存储都是OSS开发的事实标准。微软做了许多OSS开发,我们想让我们的TFS和团队服务等DevOps工具可以和这些工作流一起工作得很好。
我们希望微软里所有团队都使用相同的版本控制系统。标准化将使得人们在项目之间转换,以及形成资深专业经验的过程变得容易。因为OSS是捆绑到Git上的,而且我们也做了许多OSS开发,那Git就自然而然的成为我们的首选了。
我们希望能响应并支持社区和我们的DevOps客户希望的方向。Git很明显就是现代版本控制系统的领头羊。
但如Brian Harry所说,这有一些问题:
关于选择Git有许多争论,最主要的一个是规模问题。没有多少公司会有我们这么大规模的代码库。特别是Windows和Office(还有一些其它的),规模非常巨大。有几千个工程师,几百万个文件,几千台构建服务器在不断的构建它——老实说,这是令人难以置信的。说得更清楚些,当我在这篇贴子中提到Window的时候,我实际说的是一个非常模糊的概念,这包括了用于PC、手机、服务器、HoloLens、Xbox、物联网等等方面的所有Windows系统。而Git是一个分布式的版本控制系统(distributed version control system,DVCS)。它会把整个代码库和所有的文件历史都拷到你自己的机器上。要是对Windows也这么做的话会被人笑话的(事实上我们也的确被别人笑话了很多次)。TFVC和Source Depot都针对大型代码库和团队做过非常专门的优化。Git在这样的问题上却从来没有过先例(哪怕类似规模的也行),所以很多人都断定这种方法肯定行不通。
Reddit用户Ruud-v-A为这个问题提供了一些参考信息:
Linux内核的代码库有1.2GB了,开发了大约12年,有5700个文件。2005年第一次提交时记录过,将整个开发历史都导入进来一共是3.2GB。3.2GB对应5700个文件,由此推算那350万个文件就会需要270GB。
Chromium的代码库(包含了Webkit从2001年开始的历史代码)大小时11GB,有24.6万个文件。由此推算要20年并且有350万个文件的话,需要196GB的空间。
将Windows代码库拆分成合适大小的子代码库这条路也行不通。假如当初一开始的时候就是这么做的,那还有可能,可是到现在代码库已经这么大了,而且又发展了这么久,要再想回头把它拆分开,这事实上并不可能了。Brian继续说:
这意味着我们必须开始着手将Git增强,让它可以支持几百万个文件,几百G的大小,可以由几千个开发者一起使用。同时提供一点参考信息,即使是Source Depot也没办法支持得了整个Windows的代码库规模。它被拆分成了40多个代码库,所以我们才能将它扩展,但必须在它们之上构建一层,这样在许多情况下,才能像使用一个代码库一样使用它们。抽象当然并不完美,有时也会造成一些冲突。
为什么不干脆把历史版本都丢掉,然后重新开始呢?SuperImaginativeName给出了一个说法:
NT内核、NT的驱动、子系统、API、硬件驱动、Win32 API等,全都被其它系统所依赖,包括客户。你觉得为什么你可以在Windows上运行一个已经开发了30年的程序呢?没有这些历史版本,以内核团队为例,他们就不会记得15年前在一款特别的CPU上必须设置一个特殊的标记位,因为它的指令集架构中有个小BUG,会导致用户无法正常运行某个旧的应用程序。如果把这些历史版本丢掉了,那也就意味着丢掉了非常大量的信息。你总不能期望每个开发者都能用脑子记住为什么一个特别的系统是那样工作的。能想像某段奇怪的代码看起来好象不怎么正确,但事实上它却能让你免于遭受文件损坏之苦吗?如果只是简单地提交一个新补丁,再注释上“解决了一个奇怪的问题,真不明白为什么以前没人发现它”,这么做的后果会是灾难性的。再想想去查看一下代码历史,然后最终恍然大悟原来这么做是有道理的,这两种行为哪个才更正确?Windows代码的开发是非常严谨的,所有东西都是要经过审核的。
在经过了若干次失败的尝试,包括尝试使用Git子模块等之后,微软开始开发Git虚拟文件系统了: