『現學現忘』Git分支 — 39、Git中分支與物件的關係

2022-10-21 12:00:59

1、Git物件之間的關係

我們之前學了Git的三個物件:提交物件樹物件資料物件

我們假設現在有一個工作目錄,裡面進行了三次提交,包括一次新增檔案和兩次對檔案的修改。

  • 每次一把工作區中的檔案新增到暫存區時,暫存操作會為每一個檔案計算校驗和,然後會把當前版本的檔案快照(即檔案的內容)儲存到 Git 倉庫中 (Git 使用 blob 物件來儲存它們),最後將校驗和加入到暫存區域等待提交。
  • 每一次使用 git commit 命令進行提交操作時,Git會先計算每一個子目錄的校驗和, 然後在 Git 倉庫中這些校驗和儲存為樹物件
    隨後,Git 便會建立一個提交物件, 它除了包含上面提到的那些資訊外,還包含指向這個樹物件的指標。 如此一來,Git 就可以在需要的時候重現此次儲存的快照。

此時的Git倉庫中就會有五個Git物件:三個 blob 物件(儲存著檔案快照)、一個 物件 (記錄著目錄結構和 blob 物件索引)以及一個 提交 物件(包含著指向前述樹物件的指標和所有提交資訊)。

這個物件之間的關係,如下圖:

總結提交物件樹物件資料物件之間的關係:

  1. 一個提交操作生成一個提交物件。
  2. 一個提交物件包含一個(暫存區)生成Tree物件。(對Tree物件的封裝,單方向一對一)
  3. 一個(暫存區)生成Tree物件,裡面包含子Tree物件和Blob物件。子Tree物件還可以繼續包含子Tree物件和Blob物件。
    這樣子Tree物件對應檔案系統中的目錄+檔名Blob物件對應著檔案中的內容,這就是Git中資料儲存的形式。
  4. 一個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就先理解到這裡就很詳細了)