GVFS協(xié)議與工作原理

最近微軟開源了一個新的項目GVFS——Git Virtual File System,這是一個很棒的項目檐什,也已經(jīng)有很多相關的報道了漾峡。出于興趣,我也通過閱讀文檔與源碼鄙陡,理解了GVFS的協(xié)議與工作原理冕房。

一、環(huán)境要求

GVFS的客戶端趁矾,必須在Windwos 10下編譯耙册。而且還必須是最新的版本。Win+R -> winver.exe查看一下毫捣,如果版本號不是1703(或以上)详拙,就無法正確的運行。

下載免費的Visual Studio 2017社區(qū)版蔓同,就能夠編譯饶辙。GVFS的Reame里面“Building GVFS”一節(jié),介紹得還是很清楚的斑粱,照做即可弃揽。

二、如何測試GVFS

目前服務器端對GVFS的支持则北,只有微軟自家的平臺才行矿微,不過Visual Studio Online也是免費的,可以自己注冊一個咒锻。在創(chuàng)建的項目中冷冗,記得添加.gitattributes文件,還要包含一行* -text惑艇。

編譯出來的SetupGVFS.exe蒿辙,執(zhí)行一下拇泛,就可以在git bash里用了。記住思灌,要以管理員的身份運行git bash俺叭!

三、執(zhí)行過程

在執(zhí)行完成之后泰偿,當前目錄下熄守,會出現(xiàn)一個MyFirstProject目錄,但是在這個目錄下的src文件夾耗跛,才是實際的git倉庫裕照。

類似于執(zhí)行以下命令:

# mkdir MyFirstProject
# cd MyFirstProject
# git clone https://zhuangbiaowei.visualstudio.com/_git/MyFirstProject src

四、執(zhí)行細節(jié)

1. GET /gvfs/config

按照文檔的說法调塌,還挺像那么回事的晋南,事實上,微軟自己的服務器羔砾,返回的內(nèi)容很簡單负间。

{"AllowedGvfsClientVersions":null}

所以,客戶端也表示WARNING: Unable to validate your GVFS version

新版本的Visual Studio Online加了一個屬性:

{"AllowedGvfsClientVersions":null,"CacheServers":[]}

2. GET /info/refs?service=git-upload-pack

這是標準的Git via HTTP姜凄,為了取得這個倉庫的相關的refs政溃。返回的內(nèi)容大概是這樣的:

001e# service=git-upload-pack
000000a551292cea1631238803732c7e89b78243f5f8d6c9 HEAD multi_ack thin-pack side-band side-band-64k no-progress multi_ack_detailed no-done shallow allow-tip-sha1-in-want
003f51292cea1631238803732c7e89b78243f5f8d6c9 refs/heads/master
0000

其中51292cea1631238803732c7e89b78243f5f8d6c9,就是master分支最新的一次commit id

3. POST /gvfs/objects

按照上一條命令獲取的commit id态秧,客戶端向服務器提交了一組對象請求董虱。而服務器返回了一個pack文件。這個pack文件包含的objects的規(guī)則如下:

objectIds.each do |object_id|
  if  object_id.type == "commit"
    commit_ids = `git rev-list -${CommitDepth} object_id` #取出所需深度的commit_id
    tree_ids = get_all_tree_id(commit_ids)  #只要tree對象屿聋,不要blob對象
    object_ids << commit_ids 
    object_ids << tree_ids 
  else
    object_ids << object_id
  end
end

最后空扎,調(diào)用git自身的pack-objects命令,將這些對象打包成一個文件润讥,就可以返回了转锈。

如果我們將請求得到的數(shù)據(jù)保存為一個文件file-name.pack,可以用以下兩條命令楚殿,查看這個pack


# git index-pack file-name.pack
# git verify-pack -v file-name.pack
1a17720ebf1ed29cc384feda3f6b254f71634902 tree   79 86 12
14cc2f21152b7655d869fd8eef97996e54b935f0 commit 232 173 98
......
d2246ca4db84bb71793d1529064f8bd46b283005 tree   63 72 9490
non delta: 86 objects
chain length = 1: 3 objects
objects.pack: ok

4. GET /gvfs/prefetch[?lastPackTimestamp={secondsSinceEpoch}]

在第一次調(diào)用時撮慨,lastPackTimestamp會等于-1,相當于請求所有歷史上曾經(jīng)在服務器端打包過的文件脆粥。之后這個lastPackTimestamp砌溺,會變成最近一次的請求時間。

根據(jù)我的推斷变隔,服務器端應該根據(jù)時間戳规伐,將所有這個時間點之后打包的文件,全部計算出來匣缘,再打包一次猖闪,發(fā)送給客戶端鲜棠。

如果將這個獲取到的二進制文件打開,我們會看到這樣的數(shù)據(jù)結構:

4750 5245 2001 0100 ddaa 5759 0000 0000
# 'GPRE '開頭的5個字母
# 無符號整數(shù)代表版本號培慌,目前為1
# 2個字節(jié)豁陆,代表包數(shù)量,目前始終是0100吵护,表示只有一個包
# 8個字節(jié)盒音,代表一個時間戳,0x5957aadd轉換成十進制數(shù)是1498917597馅而,是一個UNIX時間戳
# Time.at(1498917597) = '2017-07-01 21:59:57 +0800'
ffff ffff ffff ff7f ffff ffff ffff ffff
# 根據(jù)文檔祥诽,前8個字節(jié)代表包的長度,后8個字節(jié)代表包的索引用爪,但是目前看來原押,始終不變。大概因為只有一個包的緣故
5041 434b 0000 0002 0000 005b a502 789c # 從這里開始偎血,后續(xù)都是原始的pack的內(nèi)容
3334 3030 3331 5108 7275 74f1 75d5 cb4d
6160 f46b 4c6f 0ddf 364d 8c49 2570 c752
998f d521 4adf 00bf a40c 3a93 0b78 9c2b

5. Mounting File Tree

至此,Clone+Fetch commit & tree的操作盯漂,全部完成颇玷。客戶端將會執(zhí)行mount的操作就缆,利用已經(jīng)獲取到的tree數(shù)據(jù)帖渠,構造出一個FUSE(用戶空間文件系統(tǒng)、Filesystem in Userspace竭宰,簡稱FUSE)空郊,在過去只有類UNIX操作系統(tǒng)才能支持,現(xiàn)在Windows 10也能夠很好的支持了切揭。

有了FUSE狞甚,用戶看起來就已經(jīng)獲取到了整個git代碼倉庫,但事實上廓旬,客戶端只獲取到了全部的目錄樹信息哼审,當用戶需要真正需要訪問這些文件時,才去服務器端獲取孕豹。

6. POST /gvfs/sizes

在客戶端執(zhí)行cd src操作之后涩盾,用戶首次想要查看已經(jīng)clone下來的git倉庫的內(nèi)容,這時励背,事實上倉庫的內(nèi)容并不存在春霍。因此,客戶端會發(fā)起一個sizes請求叶眉,在POST的body中提交一堆的對象ID址儒。

[
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
]

而服務器端芹枷,則返回每個對象的大小。這種操作离福,在git操作倉庫時可以通過以下命令獲取git cat-file -s obj_id杖狼。返回的格式如下:

[
    {
        "Id" : "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
        "Size" : 123
    },
    {
        "Id" : "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
        "Size" : 456
    }
]

7. GET /gvfs/objects/{objectId}

在客戶端,如果需要打開某一個具體的文件時妖爷,客戶端才需要真正獲取這個文件的內(nèi)容蝶涩,通過一個GET gvfs/objects/obj_id,就可以獲取到絮识,服務端的處理也很簡單绿聘,唯一需要注意的時:HTTP頭的內(nèi)容包括:Content-Type: application/x-git-loose-object

五、深入?yún)⒖?/h2>

想要更加深入的理解GVFS次舌,可以參考我最近放出的一個開源項目熄攘,是基于ruby語言的gitlab-grack,添加了幾個接口彼念,初步能夠在任何一種操作系統(tǒng)(不必是Windows)運行一個支持GVFS的git http server挪圾,歡迎大家來圍觀。Grack-with-GVFS

關鍵的修改逐沙,在lib/grack/server.rblib/grack/gvfs_helper.rb這兩個文件里哲思。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吩案,隨后出現(xiàn)的幾起案子棚赔,更是在濱河造成了極大的恐慌,老刑警劉巖徘郭,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靠益,死亡現(xiàn)場離奇詭異,居然都是意外死亡残揉,警方通過查閱死者的電腦和手機胧后,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冲甘,“玉大人绩卤,你說我怎么就攤上這事〗迹” “怎么了濒憋?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長陶夜。 經(jīng)常有香客問我凛驮,道長,這世上最難降的妖魔是什么条辟? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任黔夭,我火速辦了婚禮宏胯,結果婚禮上,老公的妹妹穿的比我還像新娘本姥。我一直安慰自己肩袍,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布婚惫。 她就那樣靜靜地躺著氛赐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪先舷。 梳的紋絲不亂的頭發(fā)上艰管,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音蒋川,去河邊找鬼牲芋。 笑死,一個胖子當著我的面吹牛捺球,可吹牛的內(nèi)容都是我干的缸浦。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼氮兵,長吁一口氣:“原來是場噩夢啊……” “哼餐济!你這毒婦竟也來了?” 一聲冷哼從身側響起胆剧,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎醉冤,沒想到半個月后秩霍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡蚁阳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年铃绒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片螺捐。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡颠悬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出定血,到底是詐尸還是另有隱情赔癌,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布澜沟,位于F島的核電站灾票,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茫虽。R本人自食惡果不足惜刊苍,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一既们、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧正什,春花似錦啥纸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莹妒,卻和暖如春名船,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旨怠。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工渠驼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鉴腻。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓迷扇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親爽哎。 傳聞我的和親對象是個殘疾皇子蜓席,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)课锌,斷路器厨内,智...
    卡卡羅2017閱讀 134,715評論 18 139
  • 本片內(nèi)容轉自CSDN http://blog.csdn.net/ithomer/article/details/7...
    五娃兒閱讀 4,934評論 2 88
  • 點火送君歸化外, 殘軀傴僂世間囚渺贤。 白頭年少三張嘴雏胃, 黑冢妻哀一地愁。
    迷蝴莊生閱讀 271評論 0 13
  • 2017年7月11日 天氣晴 因為臨時被放了鴿子志鞍,飯后獨自跑到濱江散步瞭亮。沿著江邊走了接近一個小時,聽了三個路邊“...
    鐘小笛閱讀 355評論 0 0
  • 突然間想到了外公他老人家,時間怎么樣都會逼著我往前走此洲,我很想能早點遂了他們的愿望厂汗。歉疚已經(jīng)隨時間越來越加深嚴重了。...
    囫圇思閱讀 185評論 0 0