generate-commitlisted
Install: claude install-skill CloudyWing/ai-dotfiles
# 產生 Git Commit 訊息
當使用者的意圖是「建立一個 git commit」時,無論措辭為何,都必須透過本技能執行,不得直接用 Bash 執行 git 指令。涵蓋但不限於以下語意:
- 明確提及 commit:「幫我 commit」「commit 一下」「commit 這些變更」「建立 commit」「產生 commit 訊息」。
- 提交動作:「幫我提交」「把這些提交上去」「存成一個版本」。
- 詢問 commit 訊息寫法:「commit message 怎麼寫」「這段變更的 commit 訊息」。
## 執行步驟
### 1. 取得全量變更(強制)
在產生 commit 訊息前,**必須**先看過真實的變更內容,不得僅憑對話記憶:
1. 執行 `git status --short` 一次掌握所有變更(staged、unstaged、untracked 一併呈現)。
2. 對**所有**有變更的檔案逐一取得實際差異(追蹤中的檔案用 `git diff HEAD -- <file>`,untracked 檔直接讀內容),不得因「檔名已能說明意圖」而略過。不分檔案是否已 staged,全部都要看。
3. **若無任何變更**,告知使用者目前沒有可 commit 的內容,流程終止,不產生 commit 訊息。
🚨 **此規則只約束「訊息措辭」,不約束「commit 範圍」。** Subject 與 Body 中對「改了什麼」的描述必須 100% 來自 `git diff` 的實際輸出,**絕對禁止**根據對話或記憶推斷、編造 diff 以外的變更。對話上下文僅可用於補充 Body 的動機說明(為什麼改),且須與當次 diff 直接關聯;若無把握,略去動機即可。
範圍判定見步驟 2,與本條無關,不得因某變更「沒在對話提過」就排除它。
### 2. 判定 commit 範圍(預設全包,減去雜訊)
預設將**所有實際變更**納入本次 commit,再扣除雜訊,而非只挑對話提過的檔案:
- **高信心雜訊自動排除**:`*.bak`、`*.tmp`、`CONTEXT.local.md`、明確的除錯或一次性暫存腳本,直接不納入,不需逐一詢問。被自動排除的項目須在最後一併列出,讓使用者可推翻。
- **模糊檔案才提示確認**:無法判定是否為過渡產物時,列出並請使用者裁決,不自行決定。
- **對話未提及不等於要排除**:只要某變更的內容與本次工作主題一致,即使對話沒談到也一律納入並如實描述。對話只決定「動機怎麼寫」,不決定「該 commit 哪些檔」。
- **手動 staged 是縮範圍的訊號,但不可默默丟**:若使用者已自行 stage 一個子集,視為刻意指定範圍;仍須列出未 staged 的相關變更並問一句是否一併納入,不得直接忽略。
### 3. 評估是否拆分 Commit
依「語意關聯」判斷:
1. 所有變更圍繞同一主題(功能、修正、重構)→ **單一 commit**,進入步驟 4。
2. 變更明顯涵蓋兩個以上**不相關**主題,且可依檔案切開(無單一檔案橫跨多主題)→ 建議**檔案級拆分**,輸出拆分計畫後依序執行。
3. 使用者選擇不拆分 → 合併為單一 commit,標題涵蓋主要變更。
**hunk 級拆分**(同一檔案內含不相關主題、需 `git add -p` 逐塊 stage)成本高且需使用者來回操作,**僅在使用者明確要求時才執行**,預設不主動提出。
檔案級拆分計畫格式:
```te