在前面三篇文章中,我們快速用上層瓷器指令走過 git 的常用功能,而這一切的根本,在於以下指令:
git init
如果沒有下這道指令去初始化 git 資料夾,會發生什麼事?
未經 git init
,直接跑 git 指令會出現的訊息
根本沒辦法進行跟 git 有關的操作!
那問題來了,為什麼下 git init
後就可以,這當中到底發生了什麼事?
要找到這問題的答案,最簡單的方式是:親自做實驗觀察!
註:以下使用 Windows 11 作業系統,其他作業系統使用指令或看到的畫面可能不同,但大同小異。
現在我們在一個空的資料夾中打 git init
,最明顯的變化是可發現多了一個名為 .git/
的隱藏資料夾:
好,所以,要有這個 .git/
資料夾,我才能做一切跟 git 有關的操作,對吧?所以這個 .git/
資料夾到底是什麼?
第一次學 git 時,我們根本不會在意,直接 git init
完就開始做專案開發、下 git add
跟 git commit
了,但在這系列的文章裡面,我們要比以前更深入一點,看看下這些指令後,git 到底幫我們做了哪些事情,而這些秘密,就藏在 .git/
資料夾裡面。
點開 .git/
資料夾,會發現如下的結構:
.git/
├── hooks/
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ └── ...
│
├── info/
│ └── exclude
│
├── objects/
│ ├── info/
│ └── pack/
│
├── refs/
│ ├── heads/
│ └── tags/
│
├── config
├── description
└── HEAD
共有四個資料夾、三個檔案,原來裡面藏有這麼多東西!那這些東西是什麼呢?
hooks/
:字面意思是「鉤子」,裡面有好多附檔名為 .sample
的檔案,看起來是要做什麼事情的範例。info/
:看起來是放什麼資訊,裡面還有個 exclude
檔案。objects/
:名字是「物件」,是 Day 3 文章提到的「git 物件」嗎?裡面還有個 info/
跟 pack/
資料夾。refs/
:意思是「參考」,裡面還有 heads/
跟 tags/
資料夾,好像是會指向 commit 的東東。config
:看起來是個設定檔,內文如下:[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
description
:感覺是要描述什麼的檔案,內文為:Unnamed repository; edit this file 'description' to name the repository.
HEAD
:看內文好像指著 main
分支:ref: refs/heads/main
還記得我們在前三篇複習上層瓷器指令的文章嗎?當我們下那三篇文章提到的指令,其實 /objects
、refs/
、HEAD
等檔案與資料夾都會發生變化,而且甚至可能產生新的檔案與資料夾。
就拿 Day 3 提到的三種 git 物件 blob、tree 與 commit 來說,這三者就通通都存在 objects/
資料夾;我們在分支間切換來切換去、合併來合併去時,HEAD
跟 refs/
也都會有對應變化;在完成某個版本時,也可以在 commit 上加上 tag 物件,但這個物件並不存在 objects/
資料夾裡,而是在 /refs/tags
……
在接下來的所有文章中,我們將在完成每項 git 操作後,仔細觀察這個 .git/
資料夾裡面的變化,看看當中藏著怎麼訊息,git 又是如何在背後幫我們完成其最核心的功能:版本控管。
待一步一步觀察完,我們對 git 的了解將會深入到另一層次,是之前用瓷器指令搭配 git status
、git log
都不會看到的新世界!