我用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非常簡單,你一開始就會感到驚訝,然後當你把頭圍在它上面時,你會感到印象深刻。只有真正的天才程序員才能寫出如此簡單的東西,但效果非常好,因爲他們可以看到大多數程序員只能看到複雜性的簡單性。
尼爾
http://github.com/git/git/blob/master/builtin/pack-objects.c – 2012-02-21 15:08:15
@JoshLee我(現在)的代碼擡頭看了一眼,而不能輕鬆搞清楚發生了什麼事。感謝您的指針,雖然:) – 2012-02-22 10:04:53