1、Commit物件介紹
現在來介紹最後一種Git物件commit
物件,也叫提交物件。
提交物件可以理解為是對樹物件的一層封裝,提交資訊包括基於當前暫存區中索引檔案生成的tree
物件,還有包含了提交時間,提交者資訊,作者資訊,以及提交備註等內容,更重要的是裡面還包含了父提交的ID,由此就可以形成Git提交的有向無環圖。(是鏈式的關係,把所有commit
物件關聯起來)
即:commit
物件通常指向一個 tree
物件,並且封裝了檔案的提交時間,提交者資訊,作者資訊,提交備註,以及父提交引用等資料。
下面是commit
物件的儲存結構:
2、Commit物件說明
我們通過練習來說明commit
物件,接著用前面Tree
物件的本地版本庫。
(1)建立一個commit
物件
我們可以通過呼叫commit-tree
命令建立一個提交物件,為此需要指定一個樹物件的SHA-1
值,以及該提交的父提交物件。
說明:使用
commit-tree
命令來建立提交物件,一般都需要和父提交進行關聯,如果是第一次將暫存區的檔案索引資料提交到本地版本庫,那麼該提交操作就不需要指定父提交物件。
1)我們可以先檢視一下此時Git本地庫中的物件,如下:
.git/objects/01/ab2a43b1eb150bcf00f375800727df240cf653 # 第三個tree樹物件
.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547 # test.txt第二個版本(blob物件)
.git/objects/16/3b45f0a0925b0655da232ea8a4188ccec615f5 # 第二個tree樹物件
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt第一個版本(blob物件)
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # 第一個tree樹物件
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt第一個版本(blob物件)
2)我們通過第一個樹物件,建立一個commit
物件
# 1.做提交操作,建立一個commit物件
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/git_learning (master)
$ echo 'first commit' | git commit-tree d8329f
3ceba95d3cd9cce982d31e41e3b995ece72f755d
# 2.確定該物件型別
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/git_learning (master)
$ git cat-file -t 3ceba95d3c
commit
# 3.檢視該物件內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/git_learning (master)
$ git cat-file -p 3ceba95d3c
tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579
author sun_wk <sun_wk@126.com> 1618190880 +0800
committer sun_wk <sun_wk@126.com> 1618190880 +0800
first commit
說明:
tree
:表示該commit
物件所指向的tree
物件的索引author
:表示該檔案的作者。committer
:表示該檔案的提交者。first commit
:這段文字是提交備註。(備註與前面留空一行)- 因為是第一次進行
commit
提交操作,所以沒有父提交資訊。 1618190880 +0800
:表示時間,一個時間戳。
即:
commit
物件的格式很簡單:指明瞭該時間點專案快照的頂層樹物件、作者/提交者資訊(從 Git 設定的user.name
和user.email
中獲得),以及當前時間戳、留空一行,最後是提交註釋。
提示:
git commit-tree
命令不但生成了提交物件,而且會將對應的快照(樹物件)提交到本地庫中。
(2)建立第二個commit
物件
根據第二個tree
物件和第一個commit
物件,來建立第二個commit
物件。
通過-p
選項指定父提交物件。
# 1.建立第二個commit物件
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/git_learning (master)
$ echo 'second commit' | git commit-tree 163b45f0a09 -p 3ceba95d3cd9cc
60e1c209e9de87314ec47cf28e61de8df5362fe6
# 2.檢視該物件內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/git_learning (master)
$ git cat-file -p 60e1c209e9de8
tree 163b45f0a0925b0655da232ea8a4188ccec615f5
parent 3ceba95d3cd9cce982d31e41e3b995ece72f755d
author sun_wk <sun_wk@126.com> 1618193286 +0800
committer sun_wk <sun_wk@126.com> 1618193286 +0800
second commit
提交物件的格式很簡單:
它先指定一個頂層樹物件,代表當前專案快照;
然後是可能存在的父提交;
之後是作者/提交者資訊(依據你的
user.name
和user.email
配置來設定,外加一個時間戳);留空一行,最後是提交註釋。
第三個commit
提交,同上,這裡就不演示了。
3、本地庫中物件之間的關係
我們可以檢視一下此時Git本地庫中的物件
.git/objects/01/ab2a43b1eb150bcf00f375800727df240cf653 # 第三個tree樹物件
.git/objects/0c/1e7391ca4e59584f8b773ecdbbb9467eba1547 # test.txt第二個版本(blob物件)
.git/objects/16/3b45f0a0925b0655da232ea8a4188ccec615f5 # 第二個tree樹物件
.git/objects/3c/eba95d3cd9cce982d31e41e3b995ece72f755d # 第一個commit提交物件
.git/objects/46/ab608799a0e65e970b67b9b52f6c1407c39036 # 第三個commit提交物件
.git/objects/60/e1c209e9de87314ec47cf28e61de8df5362fe6 # 第二個commit提交物件
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30 # test.txt第一個版本(blob物件)
.git/objects/d8/329fc1cc938780ffdd9f94e0d364e0ea74f579 # 第一個tree樹物件
.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 # new.txt第一個版本(blob物件)
可以從上面看到,此時的本地版本庫中共有9個物件,三個blob
物件,三個tree
物件,三個commit
物件。
他們之間的關係如下圖:
4、總結
- 提交是我們經常使用的Git動作,每次提交操作都指向一個樹物件,同時會產生一個
commit
物件。
即:一個commit
物件包含了一個tree
物件,這個tree
物件記錄了在那個時間點,專案包含了什麼資料夾和什麼檔案。 - 一個提交物件可以有一個或者多個父提交。
- 每次
commit
操作都會基於當前索引檔案index新建tree
物件。那麼當前索引檔案,是在上次提交的基礎上更新來的,所以每次提交產生的commit
物件,與其他的commit
物件,都有前後關係或者稱為父子關係。 - 對於我們來說,不需要直接訪問
blob
物件和tree
物件,我們直接訪問commit
物件就可以了。
即:commit
物件對應的tree
物件下面,又包含了小的tree
物件和blob
物件,子的tree
物件一層層展開,最後葉子節點就是一個個blob
物件,也就是一個個檔案。
到這裡,我們就能夠清楚的瞭解,什麼叫一個Git版本。
tree
物件才是一次專案版本的快照,提交物件是對tree
物件的一次封裝。即:
- 專案的快照就是一個樹物件。
- 專案的版本就是一個提交物件。
而且Git的每一個版本,儲存的不是增量,而儲存的是當前專案的快照。同時
objects
目錄中相當於存放了專案的所有歷史記錄,回滾就相當的方便了,找到對應的commit
物件的hash就可以了。
5、練習
請問下圖中包含多少個tree
物件和blob
物件?
一共包含兩個tree
物件,一個blob
物件,一個commit
物件。
說明:
- 一個
commit
物件一定對應一個tree
物件(這個tree
物件應該是一個完整專案倉庫的快照) doc
目錄下有一個blob
物件,也就是readme
檔案。
6、本文用到的命令總結
Git底層命令:
git commit-tree
:生成一個commit
物件。git cat-file -t 鍵
:檢視Git物件的型別。git cat-file -p 鍵
:檢視Git物件的內容。
參考: