Git
是一个被广泛使用的版本控制系统,但在规模扩展上有些不尽如人意。随着项目和代码库的增长,其性能也会受到很大的影响,一个常见的小任务,都有可能耗费数小时去执行。不过今天,微软已经给出了解决这个问题的答案
—— Git 虚拟文件系统。GVFS 的诞生,源于微软自身的 Git 使用体验。Windows
代码库的庞大规模,意味着一个简单的操作(比如检验)都可能花费 3
个小时或以上。

原文链接:
https://www.infoq.com/news/2017/02/GVFS
InfoQ翻译:http://www.infoq.com/cn/news/2017/02/GVFS?utm_source=infoq_en&utm_medium=link_on_en_item&utm_campaign=item_in_other_langs

澳门新葡萄京官网首页 1

虽然Git被广泛认为是最好用的版本管理软件,但它并不是完美无暇的。它的一些缺陷可以通过第三方的工具来弥补,但微软公司在尝试从本地将300GB的代码仓库迁移到Git时,却发现整个代码仓库复制的方式存在着致命的问题。为了解决这个难题,微软自行开发“Git虚拟文件系统”(GVFS)。

图片来自 Twitter 网友 Ittai Zeidman(@ittaiz)

在2000年前后那段时间,微软内部主要使用的是一个名叫Source Depotde
系统,它是Perforce的一个分支。后来越来越多的团队开始转向使用TFS中的版本控制软件TFVC。但那些庞大的团队却无法让所有的人都同时将代码转出Source
Depot,以及另外一些团队则在使用TFS的同时,需要通过很多第三方工具和非TFS团队协作。

“GVFS”中的“V”字,表明其解决方案是一套在文件系统级别上运行的虚拟化系统,这样可以节省遍历所有文件的下载时间。

为了简化这样复杂的工作环境,微软决定将所有团队统一成使用Visual Studio
Team Services
(即云端的TFS)来规划工作,自动构建以及代码管理,并选择了使用在VSTS搭建Git的方案来实现代码版本控制。

由于这是一个文件系统级的解决方案,所以我们无需改动集成开发环境(IDE)或构建新的工具,这是开发者们最喜闻乐见的事情了。

为什么选择Git?在微软工作的reddit 用户 jeremyepling提到了以下三个原因:

澳门新葡萄京官网首页 2

1.Git和GitHub几乎已经提供了开源软件开发的标准形式。微软在开源软件开发中作出了很多尝试,并且我们也需要像TFS
和Team Service这样属于自己的DevOps工具来更好的管理那些工作流程。
2.我们一个独立的版本控制系统来管理微软的上上下下。标准化的流程使得大家可以更好的兼顾多个工程并且更专注与开发。由于开源软件已经和Git紧密联系,并且我们做了很多开源的工程,这一切让Git瞬间成为主流。
3.我们想更好得支持开发社区和DevOps用户。Git对于当前的版本控制系统来说无疑是最主流的。

GabeAul:我们将 SCM 迁移到了 Git,并且引入了新技术。

澳门新葡萄京官网首页 ,但这样还有些问题,Brian Harry 解释道:

虚拟系统意味着不用下载整个代码树,运气好的话,只需下载和克隆 100 KB
的数据;检查和获取状态的操作也只需极少量的时间即可完成。

事实上还存在许多反对选择Git的观点,其中一个就是怀疑在微软这样的代码规模下,Git未必会有良好的表现。并不是所有的公司都和我们一样有如此庞大的代码规模。尤其是Windows和Office这两个项目,原始代码体积非常巨大。成千的工程师,上万的文件,以及持续构建着工程的上千台机器,实在是难以想象的规模。生命一下,我在这里提到的Windows包括了运行在PC,手机,服务器,HoloLens,Xbox,IOT上的系统。Git作为一个分布式版本管理系统,他会将整个仓库和所有的历史操作复制到每个人的本地机器上。对Windows这个工程做这样的操作实在是有点搞笑(是的我们已经被人笑话过很多次了)。TFVC和Source
Depot都小心翼翼地优化这庞大的代码结构和团队之间的关系,Git则从来没有考虑过这样的问题,所以很多人认为Git并不能正常的应用在这么大的工程上。

值得一提的是,微软选择了将客户端代码开源,并且会持续改进其性能,感兴趣的网友可以移步至该项目的
GitHub 页面了解更多细节。

将Windows代码库拆分成合适大小的子库并不是特别的合适。也许他们在之前就开始着手拆分的话,现在可能已经成功了。但是在如此庞大和年代救援的代码面前,再想回到过去并将它拆分已经是不可能的了。Brian继续道:

稿源:cnBeta.com

这意味着我们必须要增强Git所能处理的规模,让它可以在现有的代码和成千上万的文件让上千个开发者可以正常工作。话说回来,即便是Source
Depot也没有规模大到直接覆盖整个Windows代码库。它是被分成40多个depots之后,再通过加上一个抽象曾来使得我们在大多数情况下可以将这些堪称一个整体。然而这样的抽象并不完美而且也带了一些问题。

在各种尝试失败之后,微软开始开发Git虚拟文件系统:

我们尝试用一种方法来将Git虚拟化。一般来说Git会在你克隆代码库的时候将所有东西都下载到本地。但如果我们不这么做呢?如果我们将存储虚拟化,并只下载你所需要的文件呢?这样克隆一个巨大的300G的代码库将变得非常快。当我们使用Git的命令或者读写文件时,系统则会从云端将需要的文件下载下来并存储到本地。不过这样做的缺点之一是你在断网的情况下无法正常使用。如果你必须要在这样的环境下工作,则需要尝试“触碰”所有的文件。对于我们这样巨大的代码库,这个方法行之有效。

微软对Git作出的贡献

如果想让GVFS更好的运行,那微软必须要提升Git在访问文件方面的性能。早前版本的Git并没有太在意本地代码库的存储性能,有时会做一些不必要的文件扫描。这就是为什么微软在前几年向Git的开源工程中提交了他们的性能提升代码。

Jeremyepling 写道:

我们微软Git团队已经对Git在Linux、Mac和Windows上的性能提升作出了很多贡献。在Git的2.10版本中,我们为提升rebase的性能做了很多事,并最终使得它在Windows、MacOSX、Linux上分别提高了5、4、3倍的运行速度。

列举一些对Git作出的改进:

sha1: 在mingw上使用 openssl sha1
https://github.com/git-for-windows/git/pull/915
preload-index: 对skip-worktree的文件不使用Istat
https://github.com/git-for-windows/git/pull/955
memihash perf
https://github.com/git-for-windows/git/pull/964
add: 使用 preload-index 和 fscache 来提高性能
https://github.com/git-for-windows/git/pull/971
read-cache: 在后台线程执行verify_hdr()
https://github.com/git-for-windows/git/pull/978
read-cache: 在切换分支时提高 add_index_entry
的速度https://github.com/git-for-windows/git/pull/988
string-list: 使用ALLOC_GROW macro的方式重新为 string_list申请内存
https://github.com/git-for-windows/git/pull/991
diffcore-rename: 加速register_rename_src
https://github.com/git-for-windows/git/pull/996
fscache: 在 fscache 中添加not-found路径的缓存
https://github.com/git-for-windows/git/pull/994

Git Virtual File System

Git Virtual File
System
(GVFS)的原型实现了一个在客户端的文件系统和集成了GVFS功能的Git。这可以在十周年甚至更长远的一段时间内,看作是Windows的最杰出的功能升级。当你的Git代码库集成了GVFS之后,普通的Git命令仍然可以正常使用,GVFS则会默默得在文件系统后台下载你所需要的文件。
GVFS客户端代码的开源,可以让任何人都有机会认识到如何实现一个Windows下的虚拟文件系统驱动。
相对应的,服务端需要实现 GVFS
协议。目前只有Visual
Studio Team
Services提供这样的服务。但因为这项服务协议是开源的,所以任何服务提供商都可以实现相应的功能。同时GVFS协议也非常的简单,只包含了四个类似REST风格的访问端点。