你把progit繼續讀到blob的部分, 可能就會覺得那個快照的圖示不抽象了.
git做的事大致是這樣的:
----------
在創建Version 1時:
計算A B C的sha1, 然後在.git/object中, 創建以下文件 (即"快照")
- 文件名 sha1(A), 內容A
- 文件名 sha1(B), 內容B
- 文件名 sha1(C), 內容C
最後把這幾個sha1寫到一個新文件, 這個新文件就是Version 1.
----------
在創建Version 2時
計算A1 B C1的sha1, 然後發現sha1(B)這個文件名已經有了, 所以只需要再創建兩個文件:
- 文件名 sha1(A1), 內容A1
- 文件名 sha1(C1), 內容C1
最後把A1 B C1的sha1寫到新文件, 這個新文件就是Version 2
----------
以下略
(這不是一個精確例子, 實際上git還要在文件中保存一些元數據, 這不影響你的理解)
"快照" 經常指概念上的複製 + 物理上的引用.而不是真的有兩份.
這種快照往往和 copy-on-write 機制共用來減少數據存儲. 比如 btrfs/zfs 可以給一個文件系統快照.
有此概念的不止文件系統, 比如virtualbox可以給一個虛擬機快照, Linux的內存管理也有 copy-on-write.
除了节约空间外, 快照可以用來實現回滾等功能.
另外多說一句
有不少人认为git存储的是每次文件相对于基本文件的差异,其实这是很多人的误区。
git 可能 會使用diff來存儲 ("delta compression"), 比如把多個blob壓縮成git pack的時候.
這是git底層存儲系統的細節, 不影響其原理. 既然每個blob是不變的, 而且可以隨時還原出來, 邏輯上認為這些快照同時 "存在" 沒有什麼問題.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…