Day04 git 知己知彼


內容標題

  1. 四大物件
  2. blob 和 tree
  3. commit
  4. 之後的 commit
  5. 小結語
  6. 參考資料

四大物件

git 裡有四個很重要的物件,分別是 blobtreecommittag。但我要分享的內容暫且不包括的 tag 物件。如果要深入討論的話,我們首先要到之前介紹過的 .git 目錄!首先,我們先創立一個新的資料夾並輸入 git init 來初始化。接著我們要進到 .git 這個目錄。在進入之前,我們先用 ls 來看 .git 有沒有成功創立。

$ ls

結果卻看不到任何東西!原因是 .git 目錄是隱藏檔,所以使用者一般是看不到的。如果我們想要看到這個檔案的話,要用到我們之前講到的 [option]。指令如下:

$ ls -a

其中 -a 代表的是 all,這時就會列出所有檔案,包括 隱藏檔。這時就會看到 .git 目錄了。現在,我們進入到 git 目錄:

$ cd .git

這裡我直接開資料夾給大家看 <br/>
<img src="https://static.coderbridge.com/img/Justin900429/566a8ed1483740039eed07bf95a495e1.png" alt="drawing" width="700"/>
這個資料夾裡有一個 objects 資料夾,是存放我們檔案資訊的地方,等等我們要進行的東西都會在這裡面!

blob 和 tree

我們可以看到 objects 目錄裡面只有 infopack,因為我們還沒 commitadd 任何東西進去。此時我們在 新資料夾 創立一個 test.cpp。我們先 add 這個檔案。接著我們回到 .gitobjects 目錄,會發現資料夾底下多一個目錄同時底下還有一個檔案。<br/>

我們可以發現這個資料夾和其檔案的名字都很奇怪。事實上,兩個名字合起來就是我們之前提到的 SHA-1 (讀者和我的可能會有不同,隨檔案內容和其他因素而變!)。現在我們要用這個 SHA-1 來看看更多內容。我們先介紹一個新的指令:

$ git cat-file [option] [SHA-1]

這個指令可以用來查看 SHA-1的更多資訊,其中 -t 可以用來查看 檔案的種類-p 可以用來查看 檔案的內容。我們直接操作一次!

$ git cat-file -t 7a8f31216c572273b492d941f359aba22d203a92
blob

結果顯示這個檔案的種類是 blob 物件。

$ git cat-file -p 7a8f31216c572273b492d941f359aba22d203a92
std::cout << Hello World << std::endl;

內容則是 std::cout << Hello World << std::endl;。接著我們在原資料夾創立一個目錄hello 且目錄底下有一個 test.py 檔。同樣將檔案 test.py 加到 git裡:

$ git add hello/test.py

其中 hello/ 代表在 hello 的目錄底下。此時我們在 .git/objects 裡確實有多了一個目錄! <br/>

做完這些後我們來 commit 吧!這時我們發現,除了 7ab3 外,多了 3d95f0。我們先來看看 f0

$ git cat-file -t f0aaab3baacbfe0ac7c1b8fc0ec3655c68fca405
tree

我們發現這是一個新物件 tree。我們接著看一下他的內容:

$ git cat-file -p f0aaab3baacbfe0ac7c1b8fc0ec3655c68fca405
040000 tree 3dd16ef17d4831946a45d03d7069524613f9c964    hello
100644 blob 7a8f31216c572273b492d941f359aba22d203a92    test.cpp

我們可以看到這個 tree 物件連著兩個物件,第一個是檔案資料夾 hello,另一個是檔案是 test.cpp。我們又知道,檔案是 blob 物件,現在我們來看看資料夾 hello 是什麼:

$ git cat-file -t 3dd16ef17d4831946a45d03d7069524613f9c964
tree

我們發現 hellogit 裡是一個 tree 物件!他的內容是:

$ git cat-file -p 3dd16ef17d4831946a45d03d7069524613f9c964
100644 blob b376c9941fda362c8d2c5c8ddb35db3e0b003402    test.py

指向了資料夾裡面的 test.py

我們可以從上面做一個小結論,tree 物件會指向 blob 物件和 tree 物件。另外,當我們 commit 的時候,git 會為原目錄做一個 tree 物件,我們暫時稱它為 原目錄 tree,他指向目錄裡的東西!這裡的角色是 f0

這裡我做了一個簡單的圖讓大家更清楚檔案的關係,其中 藍色 代表 tree黃色 代表 blob
<img src="https://static.coderbridge.com/img/Justin900429/b8c444d9c8e14735ac1511503a209903.png" alt="drawing" width="500"/>

commit

剛剛我們還留了一個 95 沒看,現在我們來看一下:

$ git cat-file -t 9536cf16258f9d5451f735137e3679c8e8177cd7 
commit

這是一個 commit 物件,我們接著看他的內容:

$ git cat-file -p 9536cf16258f9d5451f735137e3679c8e8177cd7 
tree f0aaab3baacbfe0ac7c1b8fc0ec3655c68fca405
author Justin <justin900429@gmail.com> 1581931210 +0800
committer Justin <justin900429@gmail.com> 1581931210 +0800

First commit

首先,他連結到 tree 物件,也顯示時間作者資訊以及紀錄。也就是我們第一次的commit!所以目前的完整圖是:
<img src="https://static.coderbridge.com/img/Justin900429/8521b1807f0345e48ada7db9867b5ef4.png" alt="drawing" width="500"/>

之後的 commit

今天的最後一部分就是要來看一下之後的 commit 會變成什麼樣子!這裡我新增一個 test.js 並修改 test.cpp 的內容。之後 add 這些物件。這裡我輸入 git status 查看狀態,他會提示我們還沒 commit 進去!(我們之前有提過,但還沒示範 XD) <br/>
<img src="https://static.coderbridge.com/img/Justin900429/a93c60e6a73b444a96e3030ea78b7363.png" alt="drawing" width="700"/>
接著我們同樣 commit,並查看 .git/objects 的檔案有什麼變化:<br/>
<img src="https://static.coderbridge.com/img/Justin900429/040bede33c9a4996b37bea7321a3d7d2.png" alt="drawing" width="600"/>
這裡多了 1d2755e4。這裡我們就不一個一個看了,1d 是一個 tree 物件,指向 hellotest.jstest.cpp。但有一點要注意!因為我們剛剛改過 test.cpp 的內容,所以 git 會創立新的 SHA-1,因此新的 test.cpp 是由 e4 所代表,不再是 7a。另外,55 是我們新的 test.js。接著我們來看最後的 27

$ git cat-file -p 27f1e3e8264a97374afa1a78613a0274e6d76929
tree 1d5aee817d6fb6d2ec393997e564e7f50b7e9593
parent 9536cf16258f9d5451f735137e3679c8e8177cd7
author Justin <justin900429@gmail.com> 1582014575 +0800
committer Justin <justin900429@gmail.com> 1582014575 +0800

Modified test.cpp and create test.js

這是一個 commit物件,指向了 1d 這個目錄 tree。特別的是有一個 parent,那是我們前一個 commit!所以我們又可以知道新的 commit 會指向舊的 commit。因此我們現在的圖應該是,其中 ./ 代表的是當前目錄 (原目錄):
<img src="https://static.coderbridge.com/img/Justin900429/62091e0f4b154855a9f25aa532a7c537.png" alt="drawing" width="500"/>

小總結

今天我們討論了 commit 的真面目,希望這個部分可以讓更多人理解 commit 是怎麼運作的!明天我們會講解在不同的 commit 間切換,以及介紹分支

參考資料

  1. 為你自己學 Git [高見龍 著]
  2. missing semester lectures from MIT
#Git





你今天 git 了嗎?
這七天的介紹是希望能讓大家認識 git 是什麼以及基礎操作 git 的模式,同時也會包含 git 運作的流程與內容,最後幾天也會分享 GitHub 是什麼,以及如何使用 GitHub 的功能等。

留言討論