『現學現忘』Git分支 — 39、Git中分支與對象的關係
- 2022 年 10 月 21 日
- 筆記
- 基礎技能 - Git基礎
1、Git對象之間的關係
我們之前學了Git的三個對象:提交對象
、樹對象
、數據對象
。
我們假設現在有一個工作目錄,裏面進行了三次提交,包括一次新增文件和兩次對文件的修改。
- 每次一把工作區中的文件添加到暫存區時,暫存操作會為每一個文件計算校驗和,然後會把當前版本的文件快照(即文件的內容)保存到 Git 倉庫中 (Git 使用
blob
對象來保存它們),最後將校驗和加入到暫存區域等待提交。 - 每一次使用
git commit
命令進行提交操作時,Git會先計算每一個子目錄的校驗和, 然後在 Git 倉庫中這些校驗和保存為樹對象。
隨後,Git 便會創建一個提交對象, 它除了包含上面提到的那些信息外,還包含指向這個樹對象的指針。 如此一來,Git 就可以在需要的時候重現此次保存的快照。
此時的Git倉庫中就會有五個Git對象:三個 blob
對象(保存着文件快照)、一個 樹 對象 (記錄著目錄結構和 blob
對象索引)以及一個 提交 對象(包含着指向前述樹對象的指針和所有提交信息)。
這個對象之間的關係,如下圖:
總結提交對象
、樹對象
、數據對象
之間的關係:
- 一個提交操作生成一個提交對象。
- 一個提交對象包含一個(暫存區)生成
Tree
對象。(對Tree
對象的封裝,單方向一對一) - 一個(暫存區)生成
Tree
對象,裏面包含子Tree
對象和Blob
對象。子Tree
對象還可以繼續包含子Tree
對象和Blob
對象。
這樣子Tree
對象對應文件系統中的目錄+文件名
,Blob
對象對應着文件中的內容,這就是Git中數據存儲的形式。 - 一個
Blob
對象對應着一個文件某一時刻的版本。
三種對象之間的關係如下圖:
那麼問題來了:每一個Commit
對象,是怎樣的組合到一起的呢?
2、提交對象與分支的關係
(1)提交對象與分支的關係
Git版本管理系統是以時間線來對版本進行管理的,這條時間線上會有很多的時間節點,這些時間節點就是一個個的Commit
對象。
即:Git的每次提交,都會自動把它們串成一條時間線,這條時間線就是一個分支。
如下圖所示:每一次提交產生的提交對象,會包含一個指向上次提交對象(父對象)的指針,這樣就形成了一條鏈狀結構,就相當於一條線。
(2)分支說明
Git的分支,其實本質上僅僅是指向提交對象的可變指針。
Git倉庫初始化之後,會默認創建一個master
分支,即主分支。
如果沒有新建分支,那麼就只有一條時間線,即只有一個分支,master
分支(主分支)。
每次提交操作之後,會生成新的提交對象(如上圖), master
分支會在每次提交時自動向前移動。(也就是自動指向最新的提交對象)
(3)HEAD與分支的關係
我們在學習Git的時候,常常會看到HEAD
這個名稱,它指的是什麼呢?
Git中維護一個名為HEAD
的引用變量,我們將此變量稱為指針,它的目的是引用或指向本地版本庫中的特定提交。
當我們進行新的提交時,指針將改變或移動,以指向新的提交。
HEAD
始終指向Git本地版本庫中當前正在工作的分支的尖端(即最新一次提交)。
概括來說:HEAD
是對當前分支中,最後一次提交的引用。(可以將HEAD
想像為是,當前分支最後一次提交的別名。)
再繼續:
HEAD
嚴格來說不是指向提交,而是指向master
(分支),master
(分支)才是指向具體的提交,所以,HEAD
指向的就相當於是當前分支的最新一次提交。
如下圖所示:
Git用master
指向最新的提交,再用HEAD
指向master
,就能確定當前分支,以及當前分支的提交點。
(當然HEAD
還有一種分離的狀態,我們以後單說,關於HEAD
就先理解到這裡就很詳細了)