Skip to content

程式碼審查基礎:使用 /plannotator-review 審查 Git Diff

學完你能做什麼

  • ✅ 使用 /plannotator-review 指令審查 Git Diff
  • ✅ 在 side-by-side 和 unified 檢視間切換
  • ✅ 點擊行號選取程式碼範圍,新增行級註解
  • ✅ 新增不同類型的註解(comment/suggestion/concern)
  • ✅ 切換不同的 diff 類型(uncommitted/staged/last commit/branch)
  • ✅ 將審查回饋傳送給 AI Agent

你現在的困境

問題 1:用 git diff 檢視程式碼變更時,輸出在終端機裡捲動,難以全面理解改動內容。

問題 2:想給 Agent 回饋程式碼問題時,只能用文字描述「第 10 行有問題」、「修改這個函式」,容易產生歧義。

問題 3:不知道 Agent 具體改了哪些檔案,在大量改動中難以聚焦關鍵部分。

問題 4:審查程式碼後,想把結構化回饋傳送給 Agent,讓它根據建議重新修改。

Plannotator 能幫你

  • 視覺化 Git Diff,支援 side-by-side 和 unified 兩種檢視
  • 點擊行號即可選取程式碼範圍,精確標註問題位置
  • 新增行級註解(comment/suggestion/concern),附帶建議程式碼
  • 一鍵切換 diff 類型(uncommitted、staged、last commit、branch)
  • 註解自動轉換為 Markdown,Agent 準確理解你的回饋

什麼時候用這一招

使用情境

  • Agent 完成程式碼修改後,你需要審查改動內容
  • 提交程式碼前,想全面檢查自己的變更
  • 與團隊協作時,需要結構化回饋程式碼問題
  • 想在多個 diff 類型間切換(未提交 vs 已暫存 vs 上次提交)

不適用情境

  • 審查 AI 產生的實施計畫(使用計畫審查功能)
  • 直接在終端機中使用 git diff(不需要視覺化介面)

🎒 開始前的準備

前置條件

  • ✅ 已安裝 Plannotator CLI(詳見 快速開始
  • ✅ 已設定 Claude Code 或 OpenCode 外掛(詳見對應安裝指南)
  • ✅ 目前目錄在 Git 儲存庫中

觸發方式

  • 在 Claude Code 或 OpenCode 中執行 /plannotator-review 指令

核心思路

程式碼審查是什麼

程式碼審查是 Plannotator 提供的視覺化 Git Diff 審查工具,讓你在瀏覽器中檢視程式碼變更並新增行級註解。

為什麼需要程式碼審查?

AI Agent 完成程式碼修改後,通常會用終端機輸出 git diff 內容。這種純文字方式難以全面理解改動,也不方便精確標註問題位置。Plannotator 提供視覺化介面(side-by-side 或 unified),支援點擊行號新增註解,並將結構化回饋傳送給 Agent,讓它根據建議重新修改程式碼。

運作流程

┌─────────────────┐
│  使用者        │
│  (執行指令)    │
└────────┬────────┘

         │ /plannotator-review

┌─────────────────┐
│  CLI          │
│  (執行 git)    │
│  git diff HEAD │
└────────┬────────┘

         │ rawPatch + gitRef

┌─────────────────┐
│ Review Server  │  ← 本機伺服器啟動
│  /api/diff     │
└────────┬────────┘

         │ 瀏覽器開啟 UI

┌─────────────────┐
│ Review UI     │
│                 │
│ ┌───────────┐  │
│ │ File Tree  │  │
│ │ (檔案清單) │  │
│ └───────────┘  │
│       │         │
│       ▼         │
│ ┌───────────┐  │
│ │ DiffViewer │  │
│ │ (程式碼對比) │  │
│ │ split/     │  │
│ │ unified   │  │
│ └───────────┘  │
│       │         │
│       │ 點擊行號
│       ▼         │
│ ┌───────────┐  │
│ │ 新增註解   │  │
│ │ comment/   │  │
│ │ suggestion/│  │
│ │ concern    │  │
│ └───────────┘  │
│       │         │
│       ▼         │
│ ┌───────────┐  │
│ │ 傳送回饋   │  │
│ │ Send       │  │
│ │ Feedback   │  │
│ │ 或 LGTM    │  │
│ └───────────┘  │
└────────┬────────┘

         │ Markdown 格式回饋

┌─────────────────┐
│  AI Agent     │
│  (根據建議修改) │
└─────────────────┘

檢視模式

檢視模式描述適用情境
Split (Side-by-side)左右分割,舊程式碼在左,新程式碼在右對比大段改動,清晰看到修改前後
Unified上下合併,刪除和新增在同一欄檢視小改動,節省垂直空間

註解類型

Plannotator 支援三種程式碼註解類型:

註解類型用途UI 表現
Comment評論某行程式碼,提出問題或說明紫色/藍色邊框標記
Suggestion提供具體的程式碼修改建議綠色邊框標記,附帶建議程式碼區塊
Concern標記需要關注的潛在問題黃色/橙色邊框標記

註解類型的區別

  • Comment:用於提問、說明、一般性回饋
  • Suggestion:用於提供具體的程式碼修改方案(附帶建議程式碼)
  • Concern:用於標記需要修復的問題或潛在風險

Diff 類型

Diff 類型Git 指令描述
Uncommittedgit diff HEAD未提交的變更(預設)
Stagedgit diff --staged已暫存的變更
Unstagedgit diff未暫存的變更
Last commitgit diff HEAD~1..HEAD上次提交的內容
Branchgit diff main..HEAD目前分支與預設分支的對比

跟我做

第 1 步:觸發程式碼審查

在 Claude Code 或 OpenCode 中執行 /plannotator-review 指令:

使用者:/plannotator-review

CLI:正在執行 git diff...
      瀏覽器已開啟

你應該看到

  1. 瀏覽器自動開啟 Plannotator 程式碼審查介面
  2. 左側顯示檔案清單(File Tree)
  3. 右側顯示 Diff Viewer(預設為 split 檢視)
  4. 頂部有檢視切換按鈕(Split/Unified)
  5. 底部有「Send Feedback」和「LGTM」按鈕

第 2 步:瀏覽檔案清單

在左側的 File Tree 中檢視改動的檔案:

  • 檔案按路徑分組顯示
  • 每個檔案顯示變更統計(additions/deletions)
  • 點擊檔案切換到對應的 diff 內容

你應該看到

src/
  auth/
    login.ts          (+12, -5)  ← 點擊檢視這個檔案的 diff
    user.ts          (+8, -2)
  api/
    routes.ts        (+25, -10)

第 3 步:切換檢視模式

在頁面頂部點擊「Split」或「Unified」按鈕切換檢視:

Split 檢視(Side-by-side):

  • 舊程式碼在左(灰色背景,紅色刪除線)
  • 新程式碼在右(白色背景,綠色新增線)
  • 適合對比大段改動

Unified 檢視(合併):

  • 舊程式碼和新程式碼在同一欄
  • 刪除的行用紅色背景,新增的行用綠色背景
  • 適合檢視小改動

你應該看到

  • Split 檢視:左右分割,清晰對比修改前後
  • Unified 檢視:上下合併,節省垂直空間

第 4 步:選取程式碼行,新增註解

新增 Comment 註解

  1. 將滑鼠懸停在程式碼行上,行號旁會出現 + 按鈕
  2. 點擊 + 按鈕,或直接點擊行號選取該行
  3. 選取多行:點擊起始行號,按住 Shift 點擊結束行號
  4. 在彈出的工具列中輸入評論內容
  5. 點擊「Add Comment」按鈕

新增 Suggestion 註解(附帶建議程式碼)

  1. 按照上述步驟新增註解
  2. 在工具列中點擊「Add suggested code」按鈕
  3. 在彈出的程式碼框中輸入建議的程式碼
  4. 點擊「Add Comment」按鈕

你應該看到

  • 註解顯示在程式碼行下方
  • Comment 註解:紫色/藍色邊框標記,顯示評論內容
  • Suggestion 註解:綠色邊框標記,顯示評論內容和建議程式碼區塊
  • 右側側邊欄會顯示所有註解清單

第 5 步:切換 Diff 類型

在頁面頂部選擇不同的 diff 類型:

  • Uncommitted changes(預設):未提交的變更
  • Staged changes:已暫存的變更
  • Last commit:上次提交的內容
  • vs main(如果不在預設分支):與預設分支的對比

你應該看到

  • Diff Viewer 更新為新選擇的 diff 內容
  • 檔案清單重新整理顯示新的變更統計

第 6 步:傳送回饋給 Agent

Send Feedback(傳送回饋)

  1. 新增必要的註解(Comment/Suggestion/Concern)
  2. 點擊頁面底部的「Send Feedback」按鈕
  3. 如果沒有註解,會彈出確認對話框詢問是否繼續

LGTM(Looks Good To Me)

如果程式碼沒有問題,點擊「LGTM」按鈕。

你應該看到

  • 瀏覽器自動關閉(1.5 秒延遲)
  • 終端機顯示回饋內容或「LGTM - no changes requested.」
  • Agent 收到回饋後開始修改程式碼

第 7 步:檢視回饋內容(可選)

如果你想檢視 Plannotator 傳送給 Agent 的回饋內容,可以在終端機中檢視:

# Code Review Feedback

## src/auth/login.ts

### Line 15 (new)
這裡需要新增錯誤處理邏輯。

### Line 20-25 (old)
**Suggested code:**
```typescript
try {
  await authenticate(req);
} catch (error) {
  return res.status(401).json({ error: 'Authentication failed' });
}

src/api/routes.ts

Line 10 (new)

這個函式缺少輸入驗證。


**你應該看到**:
- 回饋按檔案分組
- 每個註解顯示檔案路徑、行號、類型
- Suggestion 註解附帶建議程式碼區塊

## 檢查點 ✅

完成以上步驟後,你應該能夠:

- [ ] 執行 `/plannotator-review` 指令,瀏覽器自動開啟程式碼審查介面
- [ ] 在 File Tree 中檢視改動的檔案清單
- [ ] 在 Split 和 Unified 檢視間切換
- [ ] 點擊行號或 `+` 按鈕選取程式碼行
- [ ] 新增 Comment、Suggestion、Concern 註解
- [ ] 在註解中新增建議程式碼
- [ ] 切換不同的 diff 類型(uncommitted/staged/last commit/branch)
- [ ] 點擊 Send Feedback,瀏覽器關閉,終端機顯示回饋內容
- [ ] 點擊 LGTM,瀏覽器關閉,終端機顯示「LGTM - no changes requested.」

**如果某一步失敗**,詳見:
- [常見問題](../../faq/common-problems/)
- [Claude Code 安裝指南](../../start/installation-claude-code/)
- [OpenCode 安裝指南](../../start/installation-opencode/)

## 踩坑提醒

**常見錯誤 1**:執行 `/plannotator-review` 後,瀏覽器沒有開啟

**原因**:可能是連接埠佔用或伺服器啟動失敗。

**解決**:
- 檢查終端機中是否有錯誤訊息
- 嘗試手動在瀏覽器中開啟顯示的 URL
- 如果問題持續,詳見 [故障排除](../../faq/troubleshooting/)

**常見錯誤 2**:點擊行號後,沒有彈出工具列

**原因**:可能是因為選取的是空行,或者瀏覽器視窗太小。

**解決**:
- 嘗試選取包含程式碼的行
- 放大瀏覽器視窗
- 確保沒有停用 JavaScript

**常見錯誤 3**:新增註解後,註解沒有顯示在程式碼下方

**原因**:可能是因為選取的是空行,或者瀏覽器視窗太小。

**解決**:
- 嘗試選取包含程式碼的行
- 放大瀏覽器視窗
- 確保沒有停用 JavaScript
- 檢查右側側邊欄是否顯示了註解清單

**常見錯誤 4**:點擊 Send Feedback 後,終端機沒有顯示回饋內容

**原因**:可能是網路問題或伺服器錯誤。

**解決**:
- 檢查終端機中是否有錯誤訊息
- 嘗試重新傳送回饋
- 如果問題持續,詳見 [故障排除](../../faq/troubleshooting/)

**常見錯誤 5**:Agent 收到回饋後,沒有按照建議修改程式碼

**原因**:Agent 可能沒有正確理解註解的意圖。

**解決**:
- 嘗試使用更明確的註解(Suggestion 比 Comment 更明確)
- 使用 Comment 新增詳細說明
- 在 Suggestion 中提供完整的建議程式碼
- 如果問題持續,可以再次執行 `/plannotator-review` 審查新的改動

**常見錯誤 6**:切換 diff 類型後,檔案清單為空

**原因**:可能是因為選取的 diff 類型沒有變更內容。

**解決**:
- 嘗試切換回「Uncommitted changes」
- 檢查 git 狀態,確認是否有變更
- 使用 `git status` 檢視目前狀態

## 本課小結

程式碼審查是 Plannotator 提供的視覺化 Git Diff 審查工具:

**核心操作**:
1. **觸發**:執行 `/plannotator-review`,瀏覽器自動開啟 UI
2. **瀏覽**:在 File Tree 中檢視改動的檔案清單
3. **檢視**:在 Split(side-by-side)和 Unified 檢視間切換
4. **註解**:點擊行號選取程式碼行,新增 Comment/Suggestion/Concern 註解
5. **切換**:選擇不同的 diff 類型(uncommitted/staged/last commit/branch)
6. **回饋**:點擊 Send Feedback 或 LGTM,回饋傳送給 Agent

**檢視模式**:
- **Split(Side-by-side)**:左右分割,舊程式碼在左,新程式碼在右
- **Unified**:上下合併,刪除和新增在同一欄

**註解類型**:
- **Comment**:評論某行程式碼,提出問題或說明
- **Suggestion**:提供具體的程式碼修改建議(附帶建議程式碼)
- **Concern**:標記需要關注的潛在問題

**Diff 類型**:
- **Uncommitted**:未提交的變更(預設)
- **Staged**:已暫存的變更
- **Unstaged**:未暫存的變更
- **Last commit**:上次提交的內容
- **Branch**:目前分支與預設分支的對比

## 下一課預告

> 下一課我們學習 **[新增程式碼註解](../code-review-annotations/)**。
>
> 你會學到:
> - 如何精確使用 Comment、Suggestion、Concern 註解
> - 如何新增建議程式碼並格式化顯示
> - 如何編輯和刪除註解
> - 註解的最佳實踐和常見情境
> - 如何在 side-by-side 檢視中選擇 old/new 側

---

## 附錄:原始碼參考

<details>
<summary><strong>點擊展開檢視原始碼位置</strong></summary>

> 更新時間:2026-01-24

| 功能              | 檔案路徑                                                                                              | 行號    |
|--- | --- | ---|
| 程式碼審查伺服器     | [`packages/server/review.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/server/review.ts#L1-L302)           | 1-302   |
| 程式碼審查 UI       | [`packages/review-editor/App.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/App.tsx#L1-L150) | 1-150   |
| DiffViewer 元件    | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L1-L349) | 1-349   |
| Git 工具         | [`packages/server/git.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/server/git.ts#L1-L148)                 | 1-148   |
| Hook 入口(review) | [`apps/hook/server/index.ts`](https://github.com/backnotprop/plannotator/blob/main/apps/hook/server/index.ts#L46-L84)         | 46-84   |
| 程式碼註解類型定義    | [`packages/ui/types.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/ui/types.ts#L53-L83)                  | 53-83   |

**關鍵類型**:
- `CodeAnnotationType`:程式碼註解類型列舉(comment、suggestion、concern)(`packages/ui/types.ts:53`)
- `CodeAnnotation`:程式碼註解介面(`packages/ui/types.ts:55-66`)
- `DiffType`:Diff 類型列舉(uncommitted、staged、unstaged、last-commit、branch)(`packages/server/git.ts:10-15`)
- `GitContext`:Git 上下文介面(`packages/server/git.ts:22-26`)

**關鍵函式**:
- `startReviewServer()`:啟動程式碼審查伺服器(`packages/server/review.ts:79`)
- `runGitDiff()`:執行 git diff 指令(`packages/server/git.ts:101`)
- `getGitContext()`:取得 Git 上下文(分支資訊和 diff 選項)(`packages/server/git.ts:79`)
- `parseDiffToFiles()`:將 diff 解析為檔案清單(`packages/review-editor/App.tsx:48`)
- `exportReviewFeedback()`:將註解匯出為 Markdown 回饋(`packages/review-editor/App.tsx:86`)

**API 路由**:
- `GET /api/diff`:取得 diff 內容(`packages/server/review.ts:118`)
- `POST /api/diff/switch`:切換 diff 類型(`packages/server/review.ts:130`)
- `POST /api/feedback`:提交審查回饋(`packages/server/review.ts:222`)
- `GET /api/image`:取得圖片(`packages/server/review.ts:164`)
- `POST /api/upload`:上傳圖片(`packages/server/review.ts:181`)
- `GET /api/agents`:取得可用 agents(OpenCode)(`packages/server/review.ts:204`)

**業務規則**:
- 預設檢視未提交的 diff(`apps/hook/server/index.ts:55`)
- 支援切換到 vs main diff(`packages/server/git.ts:131`)
- 回饋格式化為 Markdown(`packages/review-editor/App.tsx:86`)
- 批准時傳送「LGTM」文字(`packages/review-editor/App.tsx:430`)

</details>