2013-10-14 30 views
33

我們使用git to distribute an operating system and keep it upto date。由於它太大(> 2GB),我們無法分發完整的存儲庫,所以我們一直使用淺層克隆(〜300M)。但recently when fetching from a shallow clone, it's now inefficiently fetches the entire >2GB repository。這對於部署的帶寬來說是不能承受的浪費。如何從淺度克隆中高效獲取

git文檔說你不能從淺倉庫中獲取,儘管這是嚴格的不正確的。是否有任何解決方法使git clone --depth 1能夠從中獲取更改的內容?或者其他一些策略,以保持分佈大小盡可能小雖然有所有的位git需要做更新?

我已經嘗試過失敗從--depth 20克隆,看它是否會更有效地升級,沒有工作。我也看過http://git-scm.com/docs/git-bundle,但這似乎創造了巨大的捆綁。

+0

「但這似乎創造了巨大的捆綁」:只爲第一個。之後,您可以創建增量包。 – VonC

+0

我的初始分佈不能很大...... – hendry

+3

您將不得不再次嘗試使用Git 1.9/2.0(2014年第1季度)獲取淺層克隆:這些操作現在效率更高。請參閱[我的答案](http://stackoverflow.com/a/21217326/6309) – VonC

回答

28

--depthgit fetch選項。我看到該文檔並沒有真正突出顯示git clone進行抓取。

當你抓取時,兩個回收交換信息是誰從遠程的頭部開始並向後搜索fetched refs歷史記錄中最近的共享提交,然後填充所有缺失的對象以完成最近的共享提交和新提取的提交之間的新提交。

一個--depth=1取剛剛得到的枝梢,無病史。進一步提取這些歷史記錄將通過上述過程獲取新的所有內容,但如果先前提取的提交不在新提取的歷史記錄中,則提取將檢索所有內容 - 除非您用--depth限制提取。

您的客戶從一個回購庫中取得了深度= 1的回收,並將網址轉換爲不同的回購。在這個新的回購協議中,至少有一條很長的祖先路徑顯然與您當前的回購協議中的任何內容不分享。這可能是值得調查的,但無論哪種方式,除非有某種特定的原因,你的客戶可以做每個取指--depth=1

+0

正如你可以在我的[測試](https://github.com/Webconverger/webc/issues/174)中看到的,我很難重置爲遠程https://github.com/Webconverger/webc/中的a26424提交/主。所以我不明白爲什麼它只是不提取新的東西。我如何比較遠程參考? 'git ls-remote'只顯示標籤/分支... – hendry

+1

您切換回購。你在這個新回購庫中有10個分支和17個標籤,並且至少有一個標籤引用了一個很長的祖先,它沒有與你目前回購中的任何歷史記錄相同的提交。 – jthill

+0

所以..IIUC,我應該修剪http://github.com/webconverger/webc(新回購)上的分支機構/標籤,以確保一切與「a26424」相同? – hendry

1

我不知道這是否是五星級的設置,但我用的是有一個回購公頃完整克隆一個單獨的目錄。然後我從遠程倉庫引用本地淺表克隆。

git clone --depth 1 --reference /path/to/local/clone [email protected]/group/repo.git 

這種方式實際上只提取與參考存儲庫和遠程設備的不同之處。爲了使它更快,您可以使用--shared選項,但請務必閱讀git文檔中的限制(這可能很危險)。

我還發現,在某些情況下,當遠程發生了很大變化時,克隆開始獲取太多數據。這是很好的,然後更新參考回購(這奇怪地需要比它在第一位的帶寬少得多),然後再次啓動克隆。

+0

我嘗試了你的命令有和沒有幾個選項,我得到像'fatal:reference repository'[email protected]/group/ repo.git'淺'。 – user2284570

+0

您不能將淺倉庫/克隆用作參考。它必須是全面的深度克隆。 – Rajish

+0

你的意思是我不能使用' - 深度1'? – user2284570

22

剛剛做了g clone github.com:torvalds/linux,花了那麼多時間,所以我只是跳過了CTRL+C

然後做了g clone github.com:torvalds/linux --depth 1它確實克隆得很快。我只有一個提交git log

所以clone --depth 1應該工作。如果您需要更新現有存儲庫,則應使用git fetch origin branchname:branchname --depth 1。它也可以工作,它只提取一個提交。

總結:

初始克隆:

git clone git_url --depth 1 

代碼更新

git fetch origin branch:branch --depth 1 
+4

+1代碼更新 –

+0

我想添加深度的東西到配置,所以我可以做git獲取原點,而不需要記住深度過濾器。那可能嗎? – artfulrobot

+0

是的,你可能想創建一個別名。以下是git中的別名手冊:http://git-scm.com/book/en/v2/Git-Basics-Git-Aliases – Waterlink

10

注意,GIT中1.9/2.0(Q1 2014)可以在獲取了淺克隆是更有效的。
commit 82fba2b,從Nguyễn Thái Ngọc Duy (pclouds)

現在的git從或到淺克隆支持數據傳輸,這些限制都不是真的了。

所有的細節都在「shallow.c: the 8 steps to select new commits for .git/shallow」。

你可以看到像0d7d285f2c681c在提交的結果,而c29a7b8支持克隆,送包/接收包從淺克隆/。
smart-http now supports shallow fetch/clone too
您可以even clone form a shallow repo

2015年更新:git 2.5+(2015年第2季度)將甚至允許單提交提取!請參閱「Pull a specific commit from a remote git repository」。

更新2016(10月):混帳2.11+(Q4 2016)允許抓取:

7

如果你可以選擇一個特定的分支,它可以更快。這裏使用的Spark主分支和最新標籤是一個例子:

初始克隆

git clone [email protected]:apache/spark.git --branch master --single-branch --depth 1 

更新至特定的標籤

git fetch --depth 1 origin tags/v1.6.0 

它變得非常快速切換標籤/支這樣。