扫码关注官方订阅号
拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...
你把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是不變的, 而且可以隨時還原出來, 邏輯上認為這些快照同時 "存在" 沒有什麼問題.
简单来说,(简化的结构,详细的慢慢补充)
当保存一个文件的时候,git 把这个文件的信息和这个文件的内容存储在一个文件里,然后求得这个文件的 sha1 作为文件名(sha1的前两位/sha1剩余部分,见.git/objects)。保存一个目录,就是把目录信息,以及其中文件通过上述方式求得的 sha1 保存在一个文件里,同样求得这个文件的sha1 作为文件名。一个提交就是,把提交的信息(比如父提交的sha1等),以及此次提交所包含的目录/文件的上述方式求得的 sha1 放在一个文件里,然后把其 sha1 作为文件名。
.git/objects
当提取某次提交的时候,需要给出某次提交的 sha1 然后 git 就可以通过sha1 找到这个保存这个提交所在的文件,然后这个文件里有其所有包含文件的 sha1 ,然后就可以找到所有文件。分支的名称其实就是某次提交 sha1 的一个别名而已(见./git/refs/heads)
./git/refs/heads
如果提交 a 和提交 b 都包含同一个文件file,那么,file 以及其信息放在一个文件里,然后 a 和 b 里面其实仅仅保存了这个文件的 sha1
在 git 里面,如果仅仅改变一个文件的文件名(包括改变目录),那么 git add ; git status 是可以看到 git 是可以检测到这个重命名的。 因为他们的 sha1 是相同的。
git add ; git status
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
你把progit繼續讀到blob的部分, 可能就會覺得那個快照的圖示不抽象了.
git做的事大致是這樣的:
(這不是一個精確例子, 實際上git還要在文件中保存一些元數據, 這不影響你的理解)
"快照" 經常指概念上的複製 + 物理上的引用.而不是真的有兩份.
這種快照往往和 copy-on-write 機制共用來減少數據存儲. 比如 btrfs/zfs 可以給一個文件系統快照.
有此概念的不止文件系統, 比如virtualbox可以給一個虛擬機快照, Linux的內存管理也有 copy-on-write.
除了节约空间外, 快照可以用來實現回滾等功能.
另外多說一句
git 可能 會使用diff來存儲 ("delta compression"), 比如把多個blob壓縮成git pack的時候.
這是git底層存儲系統的細節, 不影響其原理. 既然每個blob是不變的, 而且可以隨時還原出來, 邏輯上認為這些快照同時 "存在" 沒有什麼問題.
简单来说,(简化的结构,详细的慢慢补充)
当保存一个文件的时候,git 把这个文件的信息和这个文件的内容存储在一个文件里,然后求得这个文件的 sha1 作为文件名(sha1的前两位/sha1剩余部分,见
.git/objects
)。保存一个目录,就是把目录信息,以及其中文件通过上述方式求得的 sha1 保存在一个文件里,同样求得这个文件的sha1 作为文件名。
一个提交就是,把提交的信息(比如父提交的sha1等),以及此次提交所包含的目录/文件的上述方式求得的 sha1 放在一个文件里,然后把其 sha1 作为文件名。
当提取某次提交的时候,需要给出某次提交的 sha1 然后 git 就可以通过sha1 找到这个保存这个提交所在的文件,然后这个文件里有其所有包含文件的 sha1 ,然后就可以找到所有文件。
分支的名称其实就是某次提交 sha1 的一个别名而已(见
./git/refs/heads
)如果提交 a 和提交 b 都包含同一个文件file,那么,file 以及其信息放在一个文件里,然后 a 和 b 里面其实仅仅保存了这个文件的 sha1
在 git 里面,如果仅仅改变一个文件的文件名(包括改变目录),那么
git add ; git status
是可以看到 git 是可以检测到这个重命名的。 因为他们的 sha1 是相同的。