練習 1:完整初始化流程
從零開始建立一個 Git 專案:
$ mkdir practice-repo
$ cd practice-repo
$ git init
$ git config user.name "Student"
$ git config user.email "student@school.edu"
$ cat .git/config
一切從 git init 開始。這個指令看似簡單,但它在背後建立了一整套物件資料庫與追蹤機制。本章帶你看清楚它到底做了什麼。
git init 的作用是:在當前目錄(或指定目錄)中建立一個新的 Git 版本庫。執行後,這個目錄就從「普通資料夾」變成了「Git 追蹤的專案」。
兩種常見的初始化方式。
# 進入你已有的專案資料夾
$ cd my-project
# 初始化 Git
$ git init
Initialized empty Git repository in /Users/you/my-project/.git/
Git 會在 my-project/ 下建立 .git 隱藏目錄。
# 直接指定新目錄名稱
$ git init my-new-project
Initialized empty Git repository in /Users/you/my-new-project/.git/
$ cd my-new-project
Git 會自動建立 my-new-project 資料夾,並在裡面初始化版本庫。
git init 不會影響目錄中已有的檔案。它只是加上了 .git 資料夾,讓 Git 開始追蹤這個目錄。已有的檔案需要用 git add 加入追蹤。
當你執行 git init,Git 實際上在背後完成了以下步驟:
讓我們逐一檢視 .git 目錄中的每個項目:
初始化後,用 ls 或 tree 指令查看結構。
$ ls -la .git/
total 24
drwxr-xr-x 9 user staff 288 3 19 19:00 .
drwxr-xr-x 3 user staff 96 3 19 19:00 ..
-rw-r--r-- 1 user staff 23 3 19 19:00 HEAD
-rw-r--r-- 1 user staff 137 3 19 19:00 config
-rw-r--r-- 1 user staff 73 3 19 19:00 description
drwxr-xr-x 15 user staff 480 3 19 19:00 hooks
drwxr-xr-x 3 user staff 96 3 19 19:00 info
drwxr-xr-x 4 user staff 128 3 19 19:00 objects
drwxr-xr-x 4 user staff 128 3 19 19:00 refs
.git/
├── HEAD ← 指向目前所在的分支
├── config ← 本地版本庫的設定
├── description ← GitWeb 用的描述(通常不用)
├── hooks/ ← Git 事件鉤子腳本
│ ├── pre-commit.sample
│ ├── post-commit.sample
│ └── ...
├── info/
│ └── exclude ← 本地排除規則(類似 .gitignore)
├── objects/ ← 物件資料庫(blob, tree, commit)
│ ├── info/
│ └── pack/
└── refs/ ← 分支與標籤的參考指標
├── heads/ ← 本地分支
└── tags/ ← 標籤
| 項目 | 類型 | 用途 |
|---|---|---|
HEAD |
檔案 | 記錄目前所在的分支。內容通常是 ref: refs/heads/main,表示你正在 main 分支上。 |
config |
檔案 | 這個 Repo 的專屬設定,例如 remote URL、merge 策略等。優先順序高於全域設定。 |
objects/ |
目錄 | 物件資料庫。所有的 blob、tree、commit 物件都存在這裡,用 SHA-1 前 2 字元做子目錄。 |
refs/heads/ |
目錄 | 每個本地分支是一個檔案,內容是該分支最新 commit 的 SHA-1。 |
refs/tags/ |
目錄 | 每個標籤是一個檔案,指向特定的 commit。 |
hooks/ |
目錄 | Git 事件的鉤子腳本。例如在 commit 前自動執行程式碼檢查。預設提供 .sample 範例。 |
info/exclude |
檔案 | 功能同 .gitignore,但不會被 commit,只在本地生效。 |
HEAD 是 Git 中最重要的指標之一。它告訴 Git「你目前在哪裡」。
$ cat .git/HEAD
ref: refs/heads/main
正常情況下,HEAD 指向一個分支名稱(如 main)。當你 commit 時,這個分支的指標會自動往前移動。
$ git checkout c3a2f1b
$ cat .git/HEAD
c3a2f1b4e5d6f7a8b9c0d1e2f3a4b5c6d7e8f9a0
如果你直接 checkout 到某個 commit(而非分支),HEAD 就會進入「分離狀態(Detached HEAD)」,直接指向一個 commit SHA-1。
從執行指令到開始工作的完整流程:
.git 的目錄再次執行 git init 是安全的。Git 不會刪除任何已有的物件或參考,只會重新初始化設定。
執行 git init 後,通常你還需要做以下設定:
# 全域設定(適用所有 Repo)
$ git config --global user.name "你的名字"
$ git config --global user.email "your@email.com"
# 本地設定(僅限此 Repo)
$ git config user.name "專案特定名字"
$ git config user.email "project@email.com"
# 將預設分支改為 main(而非舊版的 master)
$ git config --global init.defaultBranch main
.gitignore 告訴 Git 哪些檔案不需要追蹤:
# .gitignore 範例
node_modules/
.DS_Store
*.log
.env
dist/
__pycache__/
.gitignore 範本,你可以在 github/gitignore 找到。
從零開始建立一個 Git 專案:
$ mkdir practice-repo
$ cd practice-repo
$ git init
$ git config user.name "Student"
$ git config user.email "student@school.edu"
$ cat .git/config
觀察初始化後的各個檔案內容:
$ cat .git/HEAD
$ ls .git/objects/
$ ls .git/refs/heads/
$ cat .git/config
試著用你自己的話描述每個檔案的作用。
git init 會建立 .git/ 目錄及其子結構。.git/objects/ 是物件資料庫的所在位置。HEAD 檔案指向你目前所在的分支。.git/refs/ 存放分支和標籤的 commit 指標。git add 與 git commit 的完整流程。git log 查閱提交歷史。