互聯(lián)網(wǎng)協(xié)議 — TCP — 擁塞控制(網(wǎng)絡(luò)質(zhì)量保障)">互聯(lián)網(wǎng)協(xié)議 — TCP — 擁塞控制(網(wǎng)絡(luò)質(zhì)量保障)
1291
2022-05-30
一、環(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里用了。記住,要以管理員的身份運行g(shù)it 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}
所以,客戶端也表示W(wǎng)ARNING: Unable to validate your GVFS ?version
新版本的Visual Studio Online加了一個屬性:
{"AllowedGvfsClientVersions":null,"CacheServers":[]}
2. GET /info/refs?service=git-upload-pack
這是標準的Git via HTTP,為了取得這個倉庫的相關(guān)的refs。返回的內(nèi)容大概是這樣的:
001e#?service=git-upload-pack000000a551292cea1631238803732c7e89b78243f5f8d6c9?HEAD?multi_ack?thin-pack?side-band?side-band-64k?no-progress?multi_ack_detailed?no-done?shallow?allow-tip-sha1-in-want003f51292cea1631238803732c7e89b78243f5f8d6c9?refs/heads/master0000
其中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?<
最后,調(diào)用git自身的pack-objects命令,將這些對象打包成一個文件,就可以返回了。
如果我們將請求得到的數(shù)據(jù)保存為一個文件file-name.pack,可以用以下兩條命令,查看這個pack
#?git?index-pack?file-name.pack#?git?verify-pack?-v?file-name.pack1a17720ebf1ed29cc384feda3f6b254f71634902?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ù)結(jié)構(gòu):
4750?5245?2001?0100?ddaa?5759?0000?0000#?'GPRE?'開頭的5個字母#?無符號整數(shù)代表版本號,目前為1#?2個字節(jié),代表包數(shù)量,目前始終是0100,表示只有一個包#?8個字節(jié),代表一個時間戳,0x5957aadd轉(zhuǎn)換成十進制數(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ù),構(gòu)造出一個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)⒖?/p>
想要更加深入的理解GVFS,可以參考我最近放出的一個開源項目,是基于ruby語言的gitlab-grack,添加了幾個接口,初步能夠在任何一種操作系統(tǒng)(不必是Windows)運行一個支持GVFS的git http server,歡迎大家來圍觀。Grack-with-GVFS
關(guān)鍵的修改,在lib/grack/server.rb與lib/grack/gvfs_helper.rb這兩個文件里。
TCP/IP Git
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。