2012-02-21 102 views
22

當我通過我的Git存儲庫運行git gcgit repack時,它會在完成後輸出「總計」行。這些數字意味着什麼?git gc/git repack輸出的「Total」行中的數字是什麼意思?

從一個相當小倉庫一對夫婦的例子:

$ git gc 
... 
Total 576 (delta 315), reused 576 (delta 315) 

$ git repack -afd --depth=250 --window=250 
... 
Total 576 (delta 334), reused 242 (delta 0) 

,一個來自一個更大的倉庫:

$ git gc 
... 
Total 347629 (delta 289610), reused 342219 (delta 285060) 
... 

我可以猜測,第一個「總」號碼是什麼:數存儲庫中的Git對象(如提交,樹和文件)。其他所有人都意味着什麼?

我已經看過git-gc(1)git-repack(1)手冊頁,並仔細閱讀了他們的「另請參見」,而我在Google上的嘗試只會產生無關結果。

+0

http://github.com/git/git/blob/master/builtin/pack-objects.c – 2012-02-21 15:08:15

+0

@JoshLee我(現在)的代碼擡頭看了一眼,而不能輕鬆搞清楚發生了什麼事。感謝您的指針,雖然:) – 2012-02-22 10:04:53

回答

22

我用dulwich做了一些工作,這是一個純粹的Git的python實現。這裏我要說的是反映了我與德威git實施的經驗,而不是經典的git源,因此可能會有差異。

Git非常簡單 - 我的意思是,它很簡單,它混亂!這個名字非常適合它的設計,由於其愚蠢而非常聰明。

當你提交任何東西時,git會獲取索引(staging區域)中的內容並創建SHA摘要項目,這樣每個文件都會得到SHAed,並且每個目錄中的文件都會被作爲blob對象進行SHA處理,當然目錄結構會獲得SHAed樹對象和所有綁定到同樣具有SHA的提交對象的對象。 Git只是在處理提交時直接將它們引入.git/objects中的文件系統。如果它成功地將它們全部放在那裏,它只是將最新的提交對象的SHA寫入.git/refs/heads /中。

有時候提交可能會中途失敗。如果某些東西無法寫入.git/objects,git在那個時候沒有清理。這是因爲通常你會修復這個問題並重做提交 - 在這種情況下,git將從之前停止的地方重新開始,即通過提交的一半。

在此處,GIT中GC用武之地它簡單地通過的.git /對象中的所有對象進行解析,標記了所有那些通過一個HEAD或BRANCH稱爲以某種方式。顯然任何剩下的東西都是孤兒,與「重要」的東西無關,所以它可以被刪除。這就是爲什麼如果你分支,在那個分支上做一些工作,但是後來放棄那個分支,並從你的git倉庫中刪除它的任何引用,運行的週期性的git gc將完全清除你的分支。這會讓一些較早的VCS用戶感到驚訝,除非它自己崩潰或損壞(通常是這樣),否則CVS永遠不會忘記任何東西。 (git-pack-objects)和git gc是完全不同的(就像git gc可能會調用git repack一樣,單獨的命令和操作也是如此)。正如我前面提到的,git只是將所有內容都引入自己的SHAed文件中。在進行光盤存儲之前,它會對它們進行gzip,但顯然這從長遠來看並不節省空間。那麼,git-pack-objects所做的就是檢查一系列SHA對象,以便在數據跨修訂版本進行復制的任何地方使用。它並不關心它是什麼樣的SHA對象 - 所有被認爲是相等的包裝。然後,它會生成有意義的二進制增量,並將整個批次作爲.pack文件存儲在.git/objects/pack中,從常規目錄結構中除去所有打包對象。

請注意,通常git-pack對象會產生新的。打包文件,而不是替換現有的.pack文件,如果最新的包文件大小小於1Mb。因此,隨着時間的推移,您會看到多個.pack文件出現在.git/objects/pack中。事實上,當你的Git獲取,只要簡單地請求遠程回購收拾所有拆包物品以及發送該取回購沒有給取回購協議.pack文件。 git repack只是簡單地調用git-pack-objects,但會告訴它合併.pack文件,因爲它認爲合適。這意味着解壓縮任何已更改的內容,重新生成二進制增量和重新壓縮。

因此,要回答你的問題,總的線是指在GIT回購對象的總數。第一個德耳塔數是那些二進制增量對象的總對象數,即git決定的對象數與其他對象有很強的相似性,並且可以存儲爲二進制增量。重複使用的數字表示來自壓縮源(即包文件)的多少對象正在被使用而沒有被重新壓縮以包括更近的改變。當你有多個包文件時,會發生這種情況,但是最近的SHA對象引用舊包文件中的某個項目作爲其基礎,然後對其應用deltas以使其變爲現代。這讓git可以使用先前壓縮的舊數據修訂版,而無需重新壓縮以包含更多新增內容。請注意,git可能附加到現有的包文件而不重寫整個包文件。

一般來說,高重用計數指示一些空間可以用一個完整的重新包裝被回收(即一個git重新包裝-a),這將始終返回重用爲零。然而,一般git會默默地爲你處理所有這些。另外,在做完整的重新包裝,可能會迫使一些git的提取,因爲包裝不同,以從頭開始 - 這取決於服務器設置(允許自定義的每個客戶端包生成是在服務器CPU價格昂貴,所以一些大GIT網站禁用它)。

希望這回答了你的問題。真的,git非常簡單,你一開始就會感到驚訝,然後當你把頭圍在它上面時,你會感到印象深刻。只有真正的天才程序員才能寫出如此簡單的東西,但效果非常好,因爲他們可以看到大多數程序員只能看到複雜性的簡單性。

尼爾

+0

根據該男子頁,'git的gc'運行'git的repack',所以說兩者是完全不同的,似乎關閉。另外,前兩個例子(兩者都有一個非零的「重用」計數)來自只有一個包的存儲庫,所以你的解釋對我來說沒有意義。 – 2012-02-27 15:13:37

+1

有git repack和git repack - git gc如果我記得做了一個「輕」重新包裝。關於重複使用的計數,我根據我的回答追蹤了一個在「這個包外部」參考文件沒有得到滿足並且德威進入無限循環的德威中的錯誤。我會毫不猶豫地承認我沒有檢查過git代碼,以確保重用真的意味着我認爲的意思。 – 2012-02-28 02:13:49

+0

關於重用計數不會爲零,請嘗試使用git repack -a強制重新打包。我編輯了我的答案,以澄清我的意思是「完全重新包裝」。另外,在完全重新包裝期間,請嘗試增加窗口和深度(請參閱http://linux.die.net/man/1/git-repack)。對於大型回購站,可能會留下一些落在窗外的重複使用的物品。 – 2012-02-28 02:23:08