前篇:
深刻理解Git - 一切皆commithtml
如何從稍微底層一點的角度,從底層實現理解一切皆commit ?git
配合希沃白板課件食用,效果更佳:
【希沃白板5】課件分享 : 《Git 進階 - 從使用角度深刻理解Git》
https://r302.cc/ke8XdO?platform=enpc&channel=copylink
點擊連接直接預覽課件3d
git 本質上是一個基於鍵值對的文件系統。
文件系統,最重要的兩個內容,固然就是 文件 和 文件夾 了。code
git 中的 blob object 就是文件系統中的文件,包含 鍵:一個 hash 值和校驗值的組合,值:文件內容。orm
比較特殊的是:blob object 只存內容,不存文件名,文件名在 tree object 中保存。htm
至關於文件系統中的文件夾。對象
提交對象能夠理解爲對樹對象的一層封裝,裏面包含了提交時間,提交做者等信息,更重要的,裏面包含了父提交的ID,由此就能夠造成 git 提交的有向無環圖。blog
git 的這些對象的數據,保存在 .git/objects 目錄下。three
這裏,咱們並無發現分支這些概念,回顧以前說的『一切皆 commit』的理解,分支這些,不過是某個 commit 的引用。(都是紙老虎)圖片
案例
將 t/bugfix 分支重置到 a1b2c3 提交。
可使用熟悉的 reset 命令: (@t/bugfix)git reset --hard a1b2c3
,也能夠用更底層的命令:git update-ref refs/head/t/bugfix a1b2c3
。
效果是同樣的,固然,平時使用,只推薦前者,這裏只是做爲對「分支是某個commit的引用」這句話理解的一個案例。
tag object(標籤對象)
標籤對象:指向一個特定對象的固定引用對象;
能夠給 git 中的任意對象打標籤;
標籤對象不是引用(與分支名不一樣),是一種獨立的git對象。但在使用上(針對提交的tag),體驗一致。因此「一切皆commit」這句話,對標籤而言,是不必定正確的,但實際使用中,通常只會給提交打標籤。
全部的引用,都記錄在 .git\refs 文件夾中。
在沒有壓縮時,稱 git 的存儲模式爲鬆散的對象模式,即一個文件的不一樣版本,都是保存其所有的數據。在 git gc 時,會壓縮並實現增量存儲。這個命令在執行 pull 等命令時自動觸發。
由於提交的不可變性,如圖,若是 newfile 是個大文件,即便刪除,在提交歷史中依然存在。要完全刪除,就要重寫 second 提交以及以後的每個提交,由於以後的提交都有 tree 指向這個大文件,即便刪除,提交的父提交也須要變化。
如
勘誤:這裏的 three,應該是 third 。圖片中也寫錯了,就懶得改了。
原文鏈接:http://www.javashuo.com/article/p-ustuggna-kg.html
END