第 02 章

Git Init 指令

一切從 git init 開始。這個指令看似簡單,但它在背後建立了一整套物件資料庫與追蹤機制。本章帶你看清楚它到底做了什麼。

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 init,Git 實際上在背後完成了以下步驟:

flowchart TD A["執行 git init"] --> B["建立 .git/ 目錄"] B --> C["建立 objects/ 物件資料庫"] B --> D["建立 refs/ 參考目錄"] B --> E["建立 HEAD 檔案"] B --> F["建立 config 設定檔"] B --> G["建立 hooks/ 鉤子目錄"] B --> H["建立 info/ 資訊目錄"]

.git 目錄結構詳解

讓我們逐一檢視 .git 目錄中的每個項目:

實際觀察 .git 目錄

初始化後,用 lstree 指令查看結構。

$ 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 是什麼?

HEAD 是 Git 中最重要的指標之一。它告訴 Git「你目前在哪裡」。

查看 HEAD 的內容

$ cat .git/HEAD
ref: refs/heads/main

正常情況下,HEAD 指向一個分支名稱(如 main)。當你 commit 時,這個分支的指標會自動往前移動。

flowchart LR HEAD["HEAD"] --> main["main"] main --> C3["Commit 3"] C3 --> C2["Commit 2"] C2 --> C1["Commit 1"]
$ git checkout c3a2f1b
$ cat .git/HEAD
c3a2f1b4e5d6f7a8b9c0d1e2f3a4b5c6d7e8f9a0

如果你直接 checkout 到某個 commit(而非分支),HEAD 就會進入「分離狀態(Detached HEAD)」,直接指向一個 commit SHA-1。

⚠️ Detached HEAD 下的 commit 不屬於任何分支,如果你離開這個狀態而沒有建立分支來保留它們,這些 commit 可能會遺失。

git init 的完整流程圖

從執行指令到開始工作的完整流程:

flowchart TD A["使用者執行 git init"] --> B{"目錄中是否已有 .git?"} B -->|"沒有"| C["建立 .git/ 及所有子目錄"] B -->|"已有"| D["重新初始化
(不會刪除已有資料)"] C --> E["設定 HEAD → refs/heads/main"] C --> F["建立空的 objects/ 與 refs/"] C --> G["寫入預設 config"] E --> H["版本庫就緒
可以開始 git add & commit"] F --> H G --> H D --> H
安全性:對已經有 .git 的目錄再次執行 git init 是安全的。Git 不會刪除任何已有的物件或參考,只會重新初始化設定。

初始化後的常用設定

執行 git init 後,通常你還需要做以下設定:

1. 設定使用者資訊

# 全域設定(適用所有 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"

2. 設定預設分支名稱

# 將預設分支改為 main(而非舊版的 master)
$ git config --global init.defaultBranch main

3. 建立 .gitignore

.gitignore 告訴 Git 哪些檔案不需要追蹤:

# .gitignore 範例
node_modules/
.DS_Store
*.log
.env
dist/
__pycache__/
提示:GitHub 提供了各種語言的 .gitignore 範本,你可以在 github/gitignore 找到。

🔧 動手練習

練習 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

練習 2:探索 .git 內部

觀察初始化後的各個檔案內容:

$ cat .git/HEAD
$ ls .git/objects/
$ ls .git/refs/heads/
$ cat .git/config

試著用你自己的話描述每個檔案的作用。

本章小結

知識重點

  • git init 會建立 .git/ 目錄及其子結構。
  • .git/objects/ 是物件資料庫的所在位置。
  • HEAD 檔案指向你目前所在的分支。
  • .git/refs/ 存放分支和標籤的 commit 指標。
  • 對已有 Repo 再次 init 是安全的,不會破壞資料。

下一章預告

  • 學習 git addgit commit 的完整流程。
  • 理解 commit 物件的內部結構。
  • 使用 git log 查閱提交歷史。
  • 學習版本回溯的基本方法。
學習提示: 現在你知道了 .git 目錄裡有什麼。下一章開始,我們會往裡面放入真正的內容——用 git addgit commit 建立第一筆版本紀錄。