最近在學習git的設計思想,看到了這個問題,說說自己的理解

git 的快照是對該版本所有檔案狀態的一種“描述”,每次提交 commit 時 git 會生成

快照

來記錄這次commit 時整個專案所有檔案的資訊。

首先

這個快照並不是這次 commit 時專案中所有檔案的複製,而是一種索引,透過這個索引可以找到這次 commit 時的所有檔案,而 git 在每次 commit 時對專案中所有檔案進行掃描,如果某檔案發生變化則會對應生成一個新的檔案 blob,記錄當前 commit 時該檔案的檔案內容,而檔名是對檔案內容的一次 SHA-1 運算得到的 40 位字串,如果該檔案內容沒有發生變化,就不會產生新的 blob 物件(因為相同內容的 SHA-1 hash值唯一),而快照就是記錄所有這次提交 commit 時 blob 檔名 SHA-1 hash 字串集合,所以就可以透過某次 commit 的快照找到當時所有檔案的 blob 物件檔案 hash 字串集合從而找到所有的檔案,載入所有檔案後就還原到了當時 commit 的專案狀態。

快照

因此得來。

例如有三個版本 版本 2 改動了檔案 A ,版本 3 改動了檔案 B

A B A1 B1 可以理解成 blob 檔案

如何理解git的快照?

如何理解git的快照?

其次

如果專案久了後產生的 blob 物件檔案越來越多,而每個 blob 物件檔案是當前檔案的一次全複製記錄,並非是基於原始檔案的差異性記錄,這樣對記憶體的佔用就會比較大,git 權衡時間和空間利用率會進行最佳化儲存,儲存當前最新版本的整個檔案,時間久遠或者不經常使用的版本只儲存diff,這樣就達到了儲存空間和讀取載入速度的平衡。