ce-commit-push-pr

ce-commit-push-pr

熱門

提交變更(commit)、推送(push)並建立 PR。適用於要求發布/開啟 PR,或僅處理 PR 描述的流程(如撰寫、重寫或說明 PR 內文)。

2.4萬星標
1885分支
更新於 2026/7/31
SKILL.md
唯讀
名稱
ce-commit-push-pr
描述

提交變更(commit)、推送(push)並建立 PR。適用於要求發布/開啟 PR,或僅處理 PR 描述的流程(如撰寫、重寫或說明 PR 內文)。

Git Commit, Push, and PR

詢問使用者: 當本 Skill 提到「詢問使用者」(ask the user)時,請使用該平台的阻塞式提問工具:Claude Code 中使用 AskUserQuestion(若其 schema 未載入,先呼叫 ToolSearch 並帶入 select:AskUserQuestion)、Codex 中使用 request_user_input、Antigravity CLI (agy) 中使用 ask_question、Pi 中使用 ask_user(需要 pi-ask-user 擴充功能)。僅在執行環境中不存在阻塞式工具或呼叫出錯(例如 Codex 的編輯模式)時,才退回至直接在對話中提出問題——絕不是因為需要載入 schema 就退回。切勿默默跳過提問。

模式 (Mode)

  • 僅描述 (Description-only) — 使用者只想取得描述(例如「撰寫/草擬 PR 描述」、「說明此 PR」,或單獨貼上 PR URL/編號)。僅執行步驟 4,並印出結果。僅在使用者要求時套用。若貼上了 PR 參考(PR ref),將其傳遞給步驟 4,以便 Pre-A 解析正確的範圍。
  • 更新描述 (Description update) — 使用者希望重新整理/重寫現有 PR 的描述,但無意進行 commit/push。使用各地通用的相同規則判定 PR 是否存在:只有來自現有 PR 檢查的 exit-0 [] 才代表「沒有開啟的 PR」(回報並停止);非零的檢查結果代表未知(先解決 gh auth status / 連線問題 — 切勿直接視為「沒有 PR」)。若存在開啟的 PR,執行步驟 4(使用現有 PR URL 的 PR 模式),然後執行步驟 5 以進行預覽、確認並透過 gh pr edit 套用。
  • 完整工作流程 (Full workflow) — 其他情況。依序執行步驟 1 至 5。

mode:pipeline 修飾符 — 由編排好的呼叫者(例如 lfg)設定。非互動式地執行解析後的模式:抑制所有阻塞式詢問。步驟 5 的現有 PR 重寫問題預設為不重寫;在更新描述模式下,會跳過預覽詢問並直接套用重寫(更新呼叫本身即代表套用意圖);任何其他被抑制的詢問均採用其文件記載的保守預設值(保留當前分支;若 Pre-A 無法解析基底 (base),則停止並回報,而非盲目猜測)。

上下文 (Context)

透過將下方每個指令作為其獨立的 shell 工具呼叫來收集儲存庫上下文——亦即單一 argv 風格的呼叫(僅包含程式及其引數)。切勿使用 ;&&||、管道符(pipe)、$(...) 或像 2>/dev/null 這樣的重導向來連接它們:此類語法僅在 POSIX shell 下解析,在 Windows PowerShell 下會直接中斷。請直接讀取每個指令的退出狀態(exit status)— 非零退出是需加以解讀的正常狀態(如尚無 PR、無 origin/HEAD、detached HEAD),而非需要抑制的失敗。

請依序執行——現有 PR 的檢查需要來自 git branch --show-current 的分支名稱:

指令 目的 非零退出 / 空輸出的含義
git rev-parse --show-toplevel 儲存庫根目錄 非 git 儲存庫 — 回報並停止
git status 工作區狀態 (Working-tree state) (僅在儲存庫外會失敗)
git diff HEAD 未提交的變更 尚無 commit 的全新儲存庫
git branch --show-current 當前分支 (<branch>) 空輸出 = detached HEAD(由步驟 1 處理)
git log --oneline -10 近期 commit / PR 標題風格 全新儲存庫 — 尚無歷史紀錄
git rev-parse --abbrev-ref origin/HEAD 遠端預設分支 未設定 origin/HEAD — 依步驟 1 解析
gh pr list --head <branch> --state open --json number,url,title,body,state,isDraft,headRefName,headRepositoryOwner 此分支的開啟 PR(僅在 <branch> 非空時執行一次) Exit 0 搭配 [] = 無開啟的 PR。非零 = gh 缺失、未驗證或離線 — PR 狀態為未知,而非「無」;切勿將非零檢查視為「無 PR」;在建立前再次檢查(步驟 5)

<branch> 替換為來自 git branch --show-current 的當前分支,且傳入分支名稱。兩個陷阱:

  • 空分支 (detached HEAD): 完全跳過 PR 檢查 — 帶有空 --headgh pr list 會扔掉過濾條件並列出不相關的 PR。在步驟 1 建立分支後再解析。
  • Fork 檢出 (Fork checkout): 切勿傳入 <owner>:<branch>gh pr list --head 不接受該語法,且會對此默默傳回 [],這會被解讀為「無 PR」並開啟重複的 PR。PR 存在於基底儲存庫 (base repo) 上,因此讓 gh 指定基底:依賴其預設儲存庫解析,或在預設為 fork 時明確傳入 -R <base-owner>/<repo>

此處收集的所有內容都是在採取任何行動前截取的快照——請將其視為提示,而非絕對事實。在每個重大步驟(步驟 3 的 push、步驟 5 的 gh pr create)執行前,請立即重新驗證分支、遠端及現有 PR 狀態,因為它們可能在收集與執行之間發生變化。


產物根目錄 (Artifact Root)

當開啟 PR 概念教學歸檔時,本 Skill 會在 <root>/explainers/ 下寫入說明文件。在該寫入操作前先解析 <root> 一次,並在下方出現 <root>/ 路徑的所有地方使用它。

<!-- ce-docs-root:start -->
在組合任何產物路徑之前,請先解析 CE 產物根目錄 <root>

  • <repo-root>/.compound-engineering/config.local.yaml 讀取 docs_root,若無則從 config.yaml 讀取;以第一個非空值為準(<repo-root> = git rev-parse --show-toplevel)。若未設定 -> <root> 即為 docs,與先前完全一致。
  • 驗證已設定的值:一個相對於儲存庫的目錄,其經 symlink 解析後的真實路徑必須保持在儲存庫內部,且既非儲存庫根目錄,也不在 .git/ 下。否則停止並回報包含 docs_root 與該值的錯誤 -- 切勿退回使用 docs
  • 使用 <root> 作為唯一的產物位置:若不存在則建立它,將每個路徑組合為 <root>/<subdir>(搭配本 Skill 自己的子目錄),且絕不另外讀取 docs
    <!-- ce-docs-root:end -->

步驟 1:解析分支與 PR 狀態

遠端預設分支會傳回類似 origin/main 的內容;請剝離 origin/ 前綴。若該指令非零退出(未設定 origin/HEAD)或僅傳回 HEAD,請嘗試 gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'。若兩者皆失敗,退回使用 main。關於現有 PR 檢查:空的 [] 陣列代表此分支無開啟的 PR;非零退出代表 gh 缺失、未驗證或離線 — 將 PR 狀態視為未知(而非「無 PR」),且在步驟 5 建立新 PR 前重新執行檢查或執行 gh auth status,而非直接假定不存在 PR。

分支路由:

  • Detached HEAD — 在繼續之前,自動從當前 HEAD 建立功能分支 (feature branch)。從變更內容推導分支名稱,執行 git checkout -b <branch-name>,重新讀取 git branch --show-current,並將該結果用於後續的工作流程。不要詢問是否建立分支 — 呼叫完整的 commit/push/PR 工作流程本身即已確認該工作應轉為分支支援。若推導出的分支名稱已存在,請選擇不衝突的後綴,或僅在無法安全解決衝突時才進行詢問。
  • 在預設分支上有工作要做(未提交、未推送或無 upstream)— 自動建立功能分支(不支援直接推送預設分支)。從變更內容推導名稱,並在步驟 3 繼續執行,該步驟會安全地處理分支建立。不要詢問是否分支 — 此處不允許直接在預設分支上提交。
  • 在預設分支上且無工作 — 回報無功能分支工作並停止。
  • 功能分支 — 繼續執行。

若 PR 檢查傳回非空陣列,切勿盲目取索引 0 — 在具有多個 fork 的基底儲存庫中,另一個貢獻者的 PR 可能共享相同的分支名稱(--head 僅按分支過濾,而非 <owner>:<branch>)。選擇其 headRepositoryOwnerheadRefName 與當前 head 匹配的條目 — 即此工作流程正在推送的分支/fork。記下該條目的 URL 與 body(所有條目均為開啟狀態 — 檢查已過濾 --state open)。若恰好有一個條目匹配,則使用它;若有多個來自不同擁有者的條目共享該分支名稱,且無法確認哪一個是當前 head 的,請將其視為不明確並停止/拋出,而非對錯誤的 PR 採取行動。步驟 5 使用該 URL 在新建 PR 和套用至現有 PR 之間進行路由。步驟 4 在重寫時使用現有 body 作為保留上下文。

步驟 2:確定規範

匹配儲存庫的 commit 訊息與 PR 標題風格(上下文中的專案說明 > 近期的 commit > 預設的 conventional commits)。使用 conventional commits 時,不明確之處預設優先選擇 fix: 而非 feat: — 新增程式碼以修復損壞或缺失的行為屬於 fix:。將 feat: 留給使用者先前無法完成的功能。使用者可以覆寫此設定。

步驟 3:Commit 並 Push

若在預設分支上,分支建立需要處理過期的本地 <base>、本地 <base> 上未推送的 commit,以及與全新遠端基底衝突的未提交變更。請閱讀 references/branch-creation.md 並在繼續之前遵循其決策流程。

掃描變更的檔案以尋找自然獨立的關注點。若它們明顯可分組為單獨的邏輯變更,請建立單獨的 commit(最多 2-3 個)。僅在檔案層級進行分組 — 切勿使用 git add -p。當不明確時,單一 commit 即可。

暫存並 commit 每個分組。避免使用 git add -Agit add . — 它們會一併納入 .env、建置產物和生成的檔案:

git add file1 file2 file3 && git commit -m "$(cat <<'EOF'
這裡填寫 commit 訊息
EOF
)"

然後推送 (push)。在推送前,請立即重新確認您位於預期探用的功能分支(git branch --show-current)— 上下文中收集的分支僅為提示,且步驟 1 可能在之後建立或切換了分支。推送即時的 HEAD 以使其反映當前的檢出狀態,絕不要使用過期的分支名稱:

git push -u origin HEAD

若工作區乾淨且所有 commit 均已推送,則此步驟為無操作 (no-op)。

步驟 4:撰寫 PR 標題與內文

您必須完整閱讀 references/pr-description-writing.md — 頂部的核心原則主導著每個步驟。它唯一需要的本 Skill 輸入是 PR 參考(PR ref),前提是它是透過模式分發所識別的(帶有貼上 URL 的僅描述模式、更新描述模式,或完整工作流程中已確認的現有 PR 重寫)。若步驟 1 找到了現有 PR,在重寫時請將其 URL 傳遞給步驟 4,以便 PR 模式獲取現有的 body,並保留其中已存在的 Related: / Fixes 參考。

在撰寫之前進行佐證決策 (Evidence decision)。CE 不再擁有專用的擷取工作流程;現代執行環境提供了自己的瀏覽器、截圖、終端機錄製及產物擷取工具。請將佐證視為使用者提供的上下文或驗證文案,而非單獨的 Skill 分發。

  1. 使用者提供的佐證(URL、Markdown 圖片/嵌入,或他們希望參考的本地產物路徑)— 依據產物類型,將其納入 PR 內文中的 ## Demo## Screenshots## Evidence。切勿虛構或上傳佐證。
  2. 使用者明確要求包含佐證但未提供 — 詢問 URL/Markdown/路徑,或告知他們使用當前執行環境的擷取流程,並帶著產物返回。切勿啟動另一個 CE Skill。
  3. Agent 對撰寫變更的判斷 — 若您撰寫了這些 commit 且知道該變更不會產生審查者需要佐證的實質聲明(內部管線、僅型別變更、無使用者可見影響的後端重構、無活性的文件、純重構),請跳過佐證處理而不進行詢問。依據執行期用途分類,而非副檔名:作為執行期 Agent 指令、設定檔、生成的產品內容或策略程式碼的 Markdown 或 YAML,不能僅因其為 Markdown 或 YAML 就自動跳過。

否則,若分支 diff 改變了審查者需要佐證的行為(UI、CLI 輸出、帶有可執行程式碼的 API 行為、產生的產物、工作流程輸出、排名/計分邏輯、部署或設定行為),請包含簡潔的驗證說明

<!-- truncated for translation batch; full body continues in source -->