解釋 Git 中的 BLOB 物件和樹物件。


Git 使用一系列 BLOB 和樹物件來儲存專案工作目錄的內容。每當我們執行提交操作時,Git 內部會建立一系列樹和 BLOB,這是專案資料夾結構在提交時的二進位制表示。

什麼是 BLOB?

BLOB 代表 **Binary Large Object**(大型二進位制物件)。Git 中每個版本的檔案都表示為一個 BLOB。BLOB 儲存檔案的資料,但不包含任何關於檔案的元資料,甚至不包含檔案名稱。

為了理解 BLOB,讓我們來看一個例子。

  • 建立 3 個文字檔案:“file1.txt”、“file2.txt” 和 “file3.txt”。前兩個檔案將包含相同的內容,而第三個檔案將有不同的內容。

$ git init                    // initialize a repo
$ echo hello>file1.txt        // create a file and enter some content
$ echo hello>file2.txt        // create a file and enter the same content
$ echo hello world>file3.txt  // create a file and enter some content
  • 讓我們將這些檔案新增到暫存區。暫存這些檔案將在“.git\objects”資料夾下建立 BLOB。在這個例子中,我們每次暫存檔案時都會列出“.git\objects”資料夾中的內容。

$ git add file1.txt    // stage the file
$ ls .git/objects/     // list contents
$ git add file2.txt
$ ls .git/objects/
$ git add file3.txt
$ ls .git/objects/

ls 命令的輸出如下所示。

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add filel.txt

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ Is .git/objects/
ce/ info/ pack/

dell@DESKTOP-N96LNR5 MINGW64 /e/tut_repo (master)
$ git add file2.txt

dell@DESKTOP-N961NR5 MINGw64 /e/tut_repo (master)
$ Is .git/objects/
ce/ info/ pack/

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add file3.txt

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ Is .git/objects/
3b/ ce/ info/ pack/

當“file1.txt”和“file3.txt”被暫存時,建立了名為“ce”和“3b”的資料夾。但是,當“file2.txt”被暫存時,沒有建立新的資料夾。這是因為“file1.txt”和“file2.txt”的內容相同。

  • 現在讓我們看看“ce”和“3b”資料夾的內容。

$ ls .git/objects/ce
$ ls .git/objects/3b

輸出顯示這些資料夾包含表示為 SHA1 雜湊的 BLOB 物件。

dell@DESKTOP-N961NRS MINGW64 /e/tut_repo (master)
$ Is .git/objects/ce
013625030ba8dba906f756967f9e9ca394464a

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ Is .git/objects/3b
18e512dba79e4c8300dd08aeb37f8e728b8dad

現在讓我們驗證檔案的型別及其內容。

$ git cat−file −t ce01
$ git cat−file −p ce01
$ git cat−file −t 3b18
$ git cat−file −p 3b18

從輸出中可以看出,儘管我們添加了 3 個檔案,但 Git 建立了 2 個 BLOB。這是因為前兩個檔案的內容相同。從輸出中可以看出,BLOB 只儲存檔案的內容,而不儲存檔名。

//output of cat−file −t ce01
blob
//output of cat−file −p ce01
hello
//output of cat−file −t 3b18
blob
//output of cat−file −p 3b18
hello world

什麼是樹?

樹就像一個目錄。Git 中的每個提交都指向一個樹物件,該物件又引用 BLOB。樹物件記錄以下內容:

  • BLOB 識別符號

  • 路徑名稱

  • 該目錄中所有檔案的元資料

樹可以遞迴地引用其他樹物件或子樹。因此,樹構建了檔案和子目錄的完整層次結構。就像 BLOB 一樣,樹也可以在“.git/objects”資料夾下檢視。

讓我們透過之前的例子來理解樹。我們建立了三個檔案並將它們全部新增到暫存區。讓我們使用**git status**命令來驗證這一點。讓我們也將所有更改提交到儲存庫。

$ git status -s // verify status
$ git commit -m 'initial commit' // commit to the repo

狀態指示已暫存 3 個檔案。發出 git commit 命令後,將建立一個雜湊值為“84a00db”的提交。

dell@0ESKTop-N961NR5 MINGW64 /e/tut_repo (master)
$ git status -s
A fiIe1.txt
A file2.txt
A file3.txt
dell@DESKTOP-N961NR5 MINGW64 /e/tut—repo (master)
$ git commit -m 'initial commit'
[master (root-commit) 84aOOdb) initial commit
3 files changed, 3 insertions(+)
create mode 100644 file1. txt
create mode 100644 file2. txt
create mode 100644 file3.txt

我們例子的內部結構可以表示如下:

上圖顯示提交“84a0”指向一個樹,它是專案的根資料夾。根資料夾有 3 個作為 BLOB 儲存的檔案。前 2 個檔案指向同一個 BLOB,因為它們的內容相同。樹物件儲存對所有 BLOB 的引用。如果我們在當前專案中建立新的資料夾,則這些資料夾將作為根專案樹“e115”的子樹建立。

讓我們驗證 objects 資料夾以檢視是否建立了任何提交物件或樹物件。這可以使用 ls 命令來檢視。

$ ls .git/objects
$ ls .git/objects/84
$ ls .git/objects/e1

輸出顯示資料夾“84”表示一個提交,“e1”將是與其關聯的樹。這些資料夾有一個由 SHA1 雜湊表示的指標檔案。

dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ Is .git/0bjects/84
aOOdb87bb5c69926b3343a564db1b3a96a389d
dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ Is .git/objects/el
1588b4a639bb90b18268b7e26f243ba31706fd

現在讓我們使用**cat-file**命令驗證這些指標檔案中的內容。

$ git cat−file −p 84a0
$ git cat−file −p e115

從輸出中可以看出,提交 (84a0) 指向一個樹,它是專案的根資料夾。

tree e11588b4a639bb90b18268b7e26f243ba31706fd
author Kiran 1612777422+0530
committer Kiran 1612777422+0530
initial commit

專案的根資料夾包含三個作為 BLOB 儲存的檔案。

dell@DESKTop-N961NR5 MINGW64 /e/tut_repo (master)
$ git cat
−file −p e115
100644 blob ce013625030ba8dba906f756967f9e9ca394464a file1.txt
100644 blob ce013625030ba8dba906f756967f9e9ca394464a file2.txt
100644 blob 3b18e5L2dba79e4c8300dd08aeb37f8e728b8dad file3.txt

更新於:2021年2月20日

2K+ 次瀏覽

啟動你的 職業生涯

完成課程獲得認證

開始
廣告