處理 GitLab MR 審查評論
概覽
GitLab MR 上的內嵌審查評論以討論串(錨定於某個檔案和行數)的形式存在。完整的流程(獲取位置 → 修復 → 回覆 → 解析)都透過 glab api 執行。此技能提供了經過驗證的指令序列;常見陷阱是直覺的指令(glab mr view --comments)僅提供評論文字,不包含檔案/行數位置,因此無法得知每條評論參照的內容。
必要背景: 使用 superpowers:receiving-code-review 處理判斷部分:以技術嚴謹性評估每條評論,並在套用前確認其正確性。此技能僅涵蓋 GitLab 的操作機制。
設定
MR=511 # MR 的 iid
PROJ="<group>%2F<subgroup>%2F<project>" # URL 編碼的完整路徑
API="projects/$PROJ/merge_requests/$MR"
對路徑進行 URL 編碼(/ → %2F)。如果不確定,可從 glab repo view 取得。
1. 擷取含位置的評論
glab mr view $MR --comments 不包含行數位置,因此不要用於內嵌評論。應呼叫討論 API 並解析 position。--paginate 是必需的:端點每次回傳 20 個討論串,若無此參數,其餘討論串會無聲地遺失。已解析的討論串會被跳過:
glab api --paginate --output ndjson "$API/discussions" | python3 -c '
import sys, json
for line in sys.stdin:
d = json.loads(line)
n = d["notes"][0]
if n.get("system") or n.get("resolved"): continue
p = n.get("position") or {}
print(d["id"], "|", n["author"]["username"], "|", n["body"])
if p: print(" ->", p.get("new_path"), "new_line:", p.get("new_line"), "old_line:", p.get("old_line"))
'
new_line= 在目前(修改後)檔案中的行數 → 這是你閱讀以理解評論應用的目標。- 針對已修改行數的評論會同時帶有
old_line和new_line;應以new_path+new_line為錨點。 - 若無
position→ 表示是全域(非內嵌)評論。
2. 在每個 new_path:new_line 處閱讀程式碼,然後修復
開啟指定行數的檔案,以便在上下文中理解評論。僅在評估後(參見 receiving-code-review)才套用修復。提交為一個 review-fix commit 並推送:
git add <files>
git commit -m "fix(<scope>): address review on <thing>" # Conventional Commits,正文包含 ticket ID
git fetch origin <target> && git rebase origin/<target>
git push --force-with-lease # 若 rebase 為無操作,則僅 `git push` 即可
3. 回覆並解析每個討論串
向討論串的 notes 端點發文會自動形成討論串回覆(不需要 in_reply_to_id)。然後 PUT resolved=true:
DISC="<步驟 1 中的討論串 id>"
glab api -X POST "$API/discussions/$DISC/notes" -f "body=Done: <你變更的內容>."
glab api -X PUT "$API/discussions/$DISC?resolved=true"
切勿將 glab 包裝在 shell 函數中:權限允許規則僅匹配字面指令,因此每個討論串都必須完整地編寫兩個呼叫。
撰寫回覆
僅說明變更的內容與原因。審查者想知道的是差異,而非調查過程。
- 已套用:一兩句話。你變更了什麼、是否將範圍擴大到引述行之外、commit 的 SHA。
Done, block style everywhere: all six components, not just this line. Rendered output unchanged. f6511f29 - 不同意或暫緩:先提出決定性的事實,再提出選項,最後將球交回審查者手中。最多兩個段落。刪去保留意見、第三個支持論點以及「樂於討論」的結語。
- 切勿敘述自己修正的過程順序,也切勿重述審查者的評論。
應解析哪些討論串
僅解析你實際已處理完畢的討論串。
- 已套用變更 -> 回覆 + 解析。
- 已回答問題且答案已定案 -> 回覆 + 解析。
- 非你所能決策的事項(目標環境、範圍、優先級)-> 回覆,不要解析。解析一個仍需審查者仲裁的討論串,會給人一種草率帶過的感受,並且該討論串會從他們的審查清單中消失。
快速參考
| 步驟 | 指令 |
|---|---|
| 列出內嵌評論及其位置 | glab api --paginate --output ndjson "$API/discussions" → 解析 .notes[].position.{new_path,new_line,old_line} |
| 回覆討論串 | glab api -X POST "$API/discussions/<id>/notes" -f "body=..." |
| 解析討論串 | glab api -X PUT "$API/discussions/<id>?resolved=true" |
常見錯誤
- 對內嵌評論使用
glab mr view --comments:僅提供文字而無檔案/行數;你無法定位它們。請使用討論 API。 - 憑空發明
glab mr note resolve:請透過glab api -X PUT ".../discussions/<id>?resolved=true"解析。 - 讀取
old_line而非new_line:對於已變更行數上的評論,當前程式碼位於new_line。 - 忘記
--paginate:超過 20 個討論串時,討論 API 會無聲地僅回傳第一頁。 - rebase 後使用裸
--force:應使用--force-with-lease,以免覆蓋審查者同時推送的 commit。 - 盲目套用評論:先進行評估(receiving-code-review)。回覆時說明你實際變更的內容,然後解析。
- 列出討論串時截斷討論串 id:API 需要完整的 40 字元 id,8 字元前綴會回傳
404 Discussion Not Found。請完整輸出d["id"]。 - 回覆中過度解釋:見「撰寫回覆」。推理過程應放在 MR 描述或 ticket 中。
- 解析待決策的討論串:如果審查者仍需選擇,請保持討論串開啟。