2017-10-13 33 views
1

我在讀關於git炸彈的this blog post,並且遇到了git去重複blob的概念,以使存儲庫更小。不幸的是,這篇文章沒有以一種明確的方式解釋,也許沒有詳細說明它究竟意味着什麼,或者它究竟是如何工作的。什麼是「git de-duplicates blob」?

我可以請你清楚解釋一下嗎?

回答

2

如果您有Linux背景,您可以將重複數據刪除視爲硬鏈接。

git存儲庫包含一個對象數據庫。這是你所有的文件,目錄和提交信息存儲的地方。

當git在對象數據庫中存儲文件時,它使用SHA-1哈希散列文件。然後它將該文件存儲在該散列下,以便可以使用散列(40個字符的校驗和)查找該文件。

因此,所有具有相同內容的對象將產生相同的散列。由於內容相同,git只會將對象保存一次。那就是重複數據刪除


的混帳炸彈庫

的混帳炸彈庫,即在您發佈的博客中提到,利用重複數據刪除來創建一個非常小的庫,這將導致內存或存儲問題。

提交中的目錄是引用其他目錄或文件的簡單文本文件。在git中,目錄的正確名稱是樹和文件blob。

即使提交是一個簡單的文本文件。您可以使用cat-file -p來顯示它的內容。例如。

git cat-file -p HEAD 
tree c1971b07ce6888558e2178a121804774c4201b17 
parent 18ed56cbc5012117e24a603e7c072cf65d36d469 
author Kate Murphy <[email protected]> 1507821911 -0400 
committer GitHub <[email protected]> 1507821911 -0400 

Update README.md 

正如您所看到的,提交包含對父提交對象和根樹對象的引用。現在你應該能夠解釋爲什麼當你改變作者,提交者或者消息或者當你改變它的時候,提交會得到另一個id:因爲提交的內容發生了變化,因此git在git數據庫中使用了哈希。

回到git炸彈。git炸彈是一顆炸彈,因爲重複使用了樹和blob對象。

結構是:

COMMIT (c1971b07) -+-- tree (8d106ebc) -+-- tree (5849ef74) -+ tree(8f4c1eae) 
        |      |      ..... 
        |      | 
        |      | 
        |      +-- tree (5849ef74) -+ tree(8f4c1eae) 
        |      ....     .... 
        + tree (8d106ebc) 
        |      | 
        |      | 
        |      | 
        |      +-- tree (5849ef74) 
        |      ....        
        + tree (8d106ebc) -+-- tree (5849ef74) 
        ....     ... 

相同的樹對象被一次又一次地重新使用。因此,git存儲庫保持很小。

但在git的彈庫中的第一棵樹水平(根)包含10個子樹。每個子樹都包含10個子樹,依此類推。整個嵌套級別是10,每個最深的樹對象都包含10個斑點(所有相同的對象)。

因此,當您嘗試籤這個倉庫的git必須建立在文件系統中10^10 =百億目錄和每目錄這個有10個文件。所以這棵樹的葉子是100.000.000.000。我想如果你嘗試創建100.000.000.000文件+目錄,很多文件系統會投降。

結論 我真的不明白一個Git倉庫炸彈的意圖是什麼,除非找到一種方法,使存儲庫無法使用。

1

在這裏,「去重複」是一個動詞,而不是一個形容詞。重複數據刪除是指當你有兩件相同的事情時,而只是存儲一次。

在這種情況下,如果我將文件100MBFile.txt檢入Git存儲庫,那麼git會將其存儲爲blob。如果我將文件十次複製到存儲庫的十個不同部分中,即使它在工作目錄中存儲了多次,它仍然只會在.git文件夾中存儲一次。

Git還可以對樹進行重複數據刪除(它是如何表示目錄的),使您可以在不看它的情況下獲得更多副本。

這意味着你可以得到一個非常小的Git倉庫,當你真正簽出一個分支時,它會變得非常大。

有關blob,樹和重複數據刪除的更多信息,請查看the Git Book section on Git objects