2014-01-17 85 views
2

我知道Git不會將數據存儲爲一系列變更集或增量,而是將其作爲一系列快照存儲。所以沒有一個文件的兩個版本之間的直接關係,如圖所示:Git的「日誌文件名」如何在內部實現

git commits

當我使用命令:

git log test.txt 

如何GIT中找到「版本1和版本2'登錄其文件系統?

在我看來:

Git會遍歷所有提交的對象(與父母的引用),然後樹木等,讓每一個記錄對特定文件的信息。

但是,這似乎不是很有效; Git是否有一些特定的算法來提取日誌信息或存儲一些額外的信息來獲取它?

+2

您是否考慮過下載git源代碼並查找? –

+1

來源可以在這裏找到:https://github.com/git/git – x29a

+0

什麼似乎效率低下?比較一下,例如,在三個不同的目錄「v1/test.txt」,「v2/test.txt」,「v3/test.txt」中查找文件'test.txt'。 – torek

回答

5

你的假設是正確的。對於最簡單的情況下(限制由路徑名的輸出日誌),它的工作原理完全一樣:從

  • 獲取樹犯
  • 是否路徑樹存在嗎?
  • 與此路徑相關聯的blob的SHA1與以前的提交不同嗎? - >輸出它
  • 獲取下一個(父)提交。重複。
4

這比您想象的要高效得多。由於git寫包的方式,這些事情的實際數據被讀入很少的I/O中 - 類似大小的東西是相鄰的,所以每棵樹的歷史很可能被順序存儲並且壓縮得非常好,因爲當地。 I/O比解壓縮慢很多,這是一個勝利。然後,由於樹的SHA是自身及其所有子樹的SHA,因此git可以輕易地檢測到子樹與其父母是否相同,並採取提前措施。這經常發生,因爲很少有文件在每次提交時都會改變。

總而言之,它的速度足以在實踐中不成問題。