概要

VFS for Gitがどういうものかは、本家サイトを見てなんとなくわかったつもりになっていたのですが、実際に触ってみないとよくわからない所も多いので、実際に触ってみました。

VFS for Gitとは

VFS for Gitは “Virtual Filesystem for Git” の略で、Gitリポジトリを仮想化してファイルの実体が実際に必要になるまではダウンロードしないようなファイルシステムです。MicrosoftのAzure DevOpsチームによって開発されているようです。ちなみにもともとは “GVFS” という名前で呼ばれていましたが、何かの事情で途中で名前が変更になったようです。

Gitリポジトリの仮想化を行うことで、Gitが苦手とされてきた

  • 巨大なヒストリを持つリポジトリ
  • バイナリファイルを多数持つリポジトリ

といったリポジトリ上でもcloneやstatus、commit等の操作を高速に実行できるようにするというのがVFS for Gitの狙いです。実際、MicrosoftはWindowsを単一のGitリポジトリに移行したらしく、そこでVFS for Gitを実際に使っているようです。下図がVFS for Gitのサイトに載っているWindowsリポジトリでの通常のGitとVFS for Gitの処理時間の比較です。これを見るとかなり期待が高まりますね。

Windowsリポジトリでの処理時間の比較

今回は、そのVFS for Gitが実際にどういう挙動をするのか試してみました。Azure DevOpsチームが開発しているだけあって、Azure DevOpsの中のGitリポジトリサービスであるAzure ReposはVFS for Gitに対応しています。なので今回はAzure Repos上にバイナリファイルを多数持つリポジトリを作ってみました。

なお、今回作ったリポジトリはパブリックにしているので、興味ある方は自由に試してみて下さい。

https://dev.azure.com/yutanaka0884/_git/huge-repo

インストールできる環境

現状、VFS for GitはWindowsとMacで使うことができます。Windows版はインストーラが用意されていますが、Macの場合は自前でビルドする必要があります。面倒だったので、今回はVM上のWindowsにインストールして試しました。WindowsのバージョンはWindows 10 Anniversary Update (Windows 10 version 1607)以上とのことです。

Windowsでのインストール

インストーラがあるので非常に簡単です。VFS for GitのGitHubリポジトリReleasesから最新のアーカイブを取得します。ここで注意が必要なのは、このリポジトリにあるGVFSクライアントとGitクライアントの両方をインストールする必要があるという点です。今回は VFS for Git 1.0.19060.1 というバージョンをインストールしたのですが、その際にはこのReleaseにある “Git-2.20.1.vfs.1.1.102.gdb3f8ae-64-bit.exe” と “SetupGVFS.1.0.19060.1.exe” の両方をインストールする必要があります。

インストールが終わると、無事にgvfs.exeコマンドが使えるようになります。自分の環境の場合は C:\Program Files/GVFS/GVFS.exe と C:\Program Files/Git/bin/git.exe にそれぞれインストールされてました。

gvfsコマンドを試してみる

では、実際に試してみます。試し方はVFS for GitのREADMEの中に記載がありました。

今回は、おそらく現状では唯一VFS for Gitに対応しているであろうAzure Repos上にサンプルのリポジトリを用意しました。このリポジトリにはランダムな内容の10MBのファイルが100個あり、それらのファイルは全て2回同じサイズのランダムな内容で更新されています。

https://dev.azure.com/yutanaka0884/_git/huge-repo

cloneしてみる

実際にcloneしてみます。gvfs clone (URL)で実行できます。gvfsコマンドは現状ではhttpsのみに対応しているようです。

C:\Users\yuichielectric> gvfs clone https://yutanaka0884@dev.azure.com/yutanaka0884/huge-repo/_git/huge-repo
Clone parameters:
  Repo URL:     https://yutanaka0884@dev.azure.com/yutanaka0884/huge-repo/_git/huge-repo
  Branch:       Default
  Cache Server: Default
  Local Cache:  C:\.gvfsCache
  Destination:  C:\Users\yuichielectric\huge-repo
Authenticating...Succeeded
Querying remote for config...Succeeded
Using cache server: None (https://yutanaka0884@dev.azure.com/yutanaka0884/huge-repo/_git/huge-repo)
Cloning...Succeeded
Fetching commits and trees from origin (no cache server)...Succeeded
Attaching ProjFS to volume...Succeeded
Validating repo...Succeeded
Mounting...Succeeded
Registering for automount...Succeeded

cloneが完了すると、huge-repoディレクトリが作成されますが、その下にはgit.cmdというファイルとsrcというディレクトリがあるだけです。どうも、VFS for Gitではこのsrcというディレクトリの下に実際のGitリポジトリが置かれるようです。cloneするのにかかった時間は自分の環境で13.646秒。

リポジトリの実際のサイズを見てみるとおよそ250KB。

C:\Users\yuichielectric\huge-repo\src>dir /S
...
     Total Files Listed:
              36 File(s)        251,052 bytes

比較のために普通のgitでcloneをしてみると、かかった時間が389.85秒でリポジトリのサイズは4.9GBでした。 28.6倍速でディスク容量はおよそ2万分の1でした。これは素晴らしいですね。

gvfsコマンドでcloneしたリポジトリでは、例えばファイルにtouchしたりするとその時点でそのファイルのみダウンロードしているようです。

その他の操作の比較

その他の操作も幾つか試してみて、かかった時間を比較してみました。

コマンド 普通のGit VFS for Git
clone 389.85 sec 13.65 sec 28.6倍速
clone --depth 1 ※1 143.28 sec NA ※2 10.5倍速
checkout 12.55 sec 0.52 sec 24.1倍速

※1 –depthオプションをつけることで取得する履歴の数を限定することが出来ます。Shallow Cloneとも呼ばれます。

※2 gvfsコマンドには–depthオプションやそれに相当するオプションが無いようでした。

まとめ

VFS for Gitを実際にインストールして試してみました。まだ簡単なコマンドを実行してみただけですが、実際にファイルの実体は必要になるまでダウンロードされない挙動になっており、各種操作がかなり高速化されていることが確認できました。Linux対応が待ち遠しいですね。

ただ、.git以下のファイルの扱いがどうなっているのかはまだよく把握できていないので引き続きあれこれいじってみたいと思います。