# 【Git】head, tag, commit, branch的關係

這是一個非常關鍵的 Git 理解核心：  
**`HEAD`、`tag`、`commit`、`branch` 彼此的關係**。  
我幫你用「定義 + 關聯圖 + 對照表 + 比喻」完整整理如下：

---

## ✅ 一張圖：理解 Git 中 HEAD、分支、Tag、Commit 的關係

```
          HEAD
            ↓
        ┌────────┐
        │ branch │──┐
        └────────┘  │
                    ↓
         ┌────────────────┐
         │     commit     │◄──┐
         └────────────────┘   │
                  ▲          │
        ┌─────────┴──────┐   │
        │     another     │  │
        │     branch      │  │
        └─────────────────┘  │
                             │
                        ┌─────────┐
                        │  tag    │──► 同樣也指向 commit
                        └─────────┘

```

---

## 🧠 核心定義

<table id="bkmrk-%E5%90%8D%E7%A8%B1-%E5%AE%9A%E7%BE%A9%E8%AA%AA%E6%98%8E-commit-git-%E7%9A%84"><thead><tr><th>名稱</th><th>定義說明</th></tr></thead><tbody><tr><td>**commit**</td><td>Git 的基本單位，是一個「版本快照」，有父子連結，不會變動</td></tr><tr><td>**branch**</td><td>指向某個 commit 的「可移動指標」，像捷徑，可以新增、移動</td></tr><tr><td>**HEAD**</td><td>代表你目前工作的「游標」，通常指向一個分支（或直接指向 commit）</td></tr><tr><td>**tag**</td><td>指向某個 commit 的「不可變名稱」（常用來標記版本，如 `v1.0.0`）</td></tr></tbody></table>

---

## 🔗 它們的關係總結

<table id="bkmrk-%E9%97%9C%E4%BF%82-%E8%AA%AA%E6%98%8E-branch-%E2%9E%9D-commi"><thead><tr><th>關係</th><th>說明</th></tr></thead><tbody><tr><td>`branch` ➝ `commit`</td><td>分支就是指向某個 commit 的「指標」</td></tr><tr><td>`HEAD` ➝ `branch` or `commit`</td><td>HEAD 是你「目前所在的位置」，可以指向分支或直接指向 commit（detached HEAD）</td></tr><tr><td>`tag` ➝ `commit`</td><td>Tag 永遠指向某個 commit，是不可變的</td></tr><tr><td>commit 之間</td><td>commit 是鏈狀連結（每個有一個 parent commit）</td></tr></tbody></table>

---

## 📁 類比說明（像檔案系統）

<table id="bkmrk-git-%E6%A6%82%E5%BF%B5-%E9%A1%9E%E6%AF%94-%E8%AA%AA%E6%98%8E-commit-"><thead><tr><th>Git 概念</th><th>類比</th><th>說明</th></tr></thead><tbody><tr><td>commit</td><td>檔案版本</td><td>是實際的內容快照（不可變）</td></tr><tr><td>branch</td><td>資料夾捷徑</td><td>可以移動、可以新建、可以切換</td></tr><tr><td>HEAD</td><td>滑鼠游標</td><td>你目前的編輯焦點（在哪個捷徑/檔案上）</td></tr><tr><td>tag</td><td>唯一標籤貼紙</td><td>永久貼在某個版本上，表示這是一個重要的版本點</td></tr></tbody></table>

---

## 📌 補充：變動性比較

<table id="bkmrk-%E5%85%83%E4%BB%B6-%E6%98%AF%E5%90%A6%E5%8F%AF%E8%AE%8A%E5%8B%95-%E5%B8%B8%E8%A6%8B%E6%93%8D%E4%BD%9C-commit"><thead><tr><th>元件</th><th>是否可變動</th><th>常見操作</th></tr></thead><tbody><tr><td>commit</td><td>❌ 不可變</td><td>一旦建立就不會改變</td></tr><tr><td>branch</td><td>✅ 可變動</td><td>可以移動、刪除、重新建立</td></tr><tr><td>tag</td><td>✅ 可刪除（內容不可變）</td><td>可以刪除再重建，但本身是不可移動的指標</td></tr><tr><td>HEAD</td><td>✅ 一直在動</td><td>跟著你切換分支、commit 而變動</td></tr></tbody></table>

---

## ✅ 常見操作對應關係

<table id="bkmrk-%E6%93%8D%E4%BD%9C%E8%AA%AA%E6%98%8E-head-%E8%AE%8A%E5%8B%95-branch-"><thead><tr><th>操作說明</th><th>HEAD 變動</th><th>branch 變動</th><th>commit 變動</th><th>tag 變動</th></tr></thead><tbody><tr><td>`git switch dev`</td><td>✅</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td>`git commit`</td><td>✅</td><td>✅（會跟著 HEAD 一起動）</td><td>✅（新增）</td><td>❌</td></tr><tr><td>`git reset --hard HEAD^`</td><td>✅</td><td>✅</td><td>✅（可能丟失）</td><td>❌</td></tr><tr><td>`git tag v1.0`</td><td>❌</td><td>❌</td><td>❌</td><td>✅</td></tr><tr><td>`git checkout <commit>`</td><td>✅（分離）</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td>`git switch -c new-feature`</td><td>✅</td><td>✅（新建）</td><td>❌</td><td>❌</td></tr></tbody></table>

---

## ✅ 總結一句話：

> - **commit** 是內容
> - **branch/tag** 是「名字」，用來指向某個 commit
> - **HEAD** 是「你目前在哪裡」，通常跟著分支動，也可以離開分支進入 detached 狀態

---