回答我自己的問題。我發現了一個可接受的(儘管幾乎沒有文件)的答案。我不得不挖掘很多C代碼來解決這個問題。
首先,使用git-upload-packfile
無法實現上述要求,因爲這根本不是該程序設計的目的。我懷疑的正確答案是git-upload-archive
。可悲的是,協議幾乎沒有記錄在ALL中。所以這裏是我的筆記,以防其他人有類似的要求。
基本上我想在這裏模擬(中階)是下面的命令:
git archive --format=tar --remote=ssh://[email protected]/cornballer.git \
> master plans/documents/cornballer-blueprint.pdf | tar -x
除了在軟件,希望用JGit。可悲的是JGit不支持(還)支持git歸檔命令。所以這裏有一個關於如何添加支持的非常高層次的概述(我可以分叉JGit並在稍後添加)。
讓我們來看看協議(來自Documentation/technical/pack-protocol。TXT):
git-proto-request = request-command SP pathname NUL [ host-parameter NUL ]
request-command = "git-upload-pack"/"git-receive-pack"/
"git-upload-archive" ; case sensitive
pathname = *(%x01-ff) ; exclude NUL
host-parameter = "host=" hostname [ ":" port ]
所以部分協議的一個是這樣的:
- 建立傳輸與遠程(或SSH,然後運行
git-upload-archive
或使用匿名Git協議)
- 發送
git-upload-archive /cornballer.git\0host=ssh.mycompany.com\0
(作爲分組行)
此時連接已建立。如果命令不受支持或者有任何問題,GIt可能會返回錯誤。我還沒有想出如何檢查這個。
接下來是未公開的部分。我們基本上通過電線發送git-archive
的命令行參數。它們與git-archive
命令完全相同,只有一個例外:它們的前綴都是argument[SPACE]
。每個參數都被寫入(至少在參考實現中)作爲單獨的分組行。因此,對於上面的例子:
- 發送
argument --format=tar
(作爲數據包線)
- 發送
argument master
(作爲數據包線)
- 發送
argument plans/documents/cornballer-blueprint.pdf
(作爲數據包線)
- 寄沖洗分組(
0000
)
在這一點上,我們已經給出了遠程git-archive進程的整個命令。現在我們閱讀迴應。我們從服務器讀取,這將是下列響應一一包線回:
ACK
(意味着成功 - 準備發送存檔)
NACK [message]
- 某種錯誤,才發現「無法產卵子」
ERR [message]
- - 它的使用的一個實例出現錯誤
如果ACK
被髮送時,它隨後將沖洗分組(0000
),然後將原始t AR數據。此時您重複讀取邊帶#1(主數據通道)上的數據包行。當你到達一個沖洗包,你停止閱讀。很簡單。
所以,現在你有遠程文件,但如果你想做一些聰明的緩存呢?我使用git-upload-packfile
的原因之一是,它允許我記錄提交ID,從而將其緩存在本地,並只根據需要進行刷新。 tar文件不會告訴我們這些信息是正確的嗎?錯誤!
從GIT-歸檔的手冊頁:
另外提交ID被存儲在全局擴展PAX頭如果使用焦油格式 ;它可以使用git get-tar-commit-id來提取。在ZIP文件中,它被存儲爲 文件評論。
那麼這是個好消息!這幾乎是我想要的一切。如果你想知道的標題是什麼樣子,下面是一個示例(不,我不打算解剖PAX頭):
pax_global_header00006660000000000000000000000064121002672560014513gustar00rootroot0000000000000052 comment=326756f834865880c9832b64238e7665632e9b67
從我的角度
所以,我只需要自動建立一個管道運行上述步驟,通過untar步驟(編程方式)運行它以執行所需的「從git獲取單個文件」功能。
我想任何答案都必須以「'git'不能這樣工作」... – twalberg
@twalberg本地回購確實。只是好奇,如果我能通過電線做到這一點。 –
是的,您可以從本地回購中提取單個對象。有線協議並沒有設計成這樣做。我認爲,通過克隆/獲取(即使使用淺克隆來避免完整的回購,但你仍然會獲得commit + trees + blob)到本地回購並提取對象,你可以完成最終目標,但是我不要以爲你可以通過網線來完成(雖然如果你有ssh訪問遠程的話,你可以將它僞造)。 – twalberg