feat(分支基準): 參考與來源分支一律取遠端 origin,動作前先 fetch

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-25 11:10:55 +08:00
co-authored by Claude Opus 5
parent 082104c550
commit 543fd8c695
5 changed files with 35 additions and 15 deletions
+25 -5
View File
@@ -2,6 +2,24 @@
分析要讀對分支的程式碼,實作要寫進對的分支。兩件事都不能從「目前 checkout 的分支」推定使用者的意圖。
## 總則:一律以遠端為準,不吃本地分支
SDLC 各階段引用的參考分支與來源分支,**一律指遠端的 `origin/{分支}`**。本地分支不可作為基準。
理由:本地分支可能落後遠端、可能有沒推上去的 commit、也可能是別的工作留下的狀態。以本地為基準,分析會對著過時的程式碼做,實作會從錯誤的起點長出來,而且錯了不會有任何徵兆。
| 項目 | 規則 |
| --- | --- |
| 動作之前 | 先 `git fetch --prune origin`。**沒 fetch 就用 `origin/{分支}` 等於用快取**,遠端追蹤參照可能已經過時,連分支被刪掉都看不出來 |
| 列分支 | `git branch -r`,不看 `git branch` |
| 基準與比對 | 一律寫 `origin/{分支}`,例如 `git rev-list --count origin/master..origin/develop` |
| 建立 worktree | 從 `origin/{來源分支}` 建,不從本地同名分支建 |
| 判定預設分支 | `refs/remotes/origin/HEAD`(見〔判定遠端預設分支〕) |
**本地與遠端不一致時一律停下回報**,不自行 `pull`、不自行 `reset`、不自行切換。要不要同步是使用者的決定。
`origin` 以外的遠端名稱(例如 `upstream`):先問使用者以哪個遠端為準,不臆測。
## 先確認,再動工
| 階段 | 要確認的分支 | 確認時機 |
@@ -11,7 +29,7 @@
確認方式:
1. 先把事實攤開:目前分支、工作區是否乾淨、遠端有哪些分支(`git branch -r`)、下節判定出的遠端預設分支。
1. 先 `git fetch --prune origin`,再把事實攤開:目前分支、工作區是否乾淨、遠端有哪些分支(`git branch -r`,不看本地)、下節判定出的遠端預設分支。
2. 依 `jsc-ask:ask` 的決策樹詢問,每個選項都要標明影響範圍。分析錯分支會產出對不上程式碼的工作包;目標分支錯了則 PR 會開到錯的地方。
3. 把確認結果寫進產出(分析頁的來源分支欄、PR 的目標分支),後續步驟一律沿用同一個答案,不再自行改判。
4. 使用者沒回答就**不預設** `develop`/`master`;預設值只在使用者明確同意後才成立。
@@ -28,18 +46,20 @@
`analyze` 是 logic-only 階段:
- **工作目錄的 HEAD 必須與 `origin/{來源分支}` 指向同一個 commit**。落後、超前或分歧都代表讀到的不是遠端現況——停下來回報差距(`git rev-list --left-right --count origin/{來源分支}...HEAD`),請使用者自己處理。
- 需要換分支才能讀到正確現況時,**停下來請使用者自己切換**。
- 不代為 `switch`、不 `stash`、不動工作區、不建分支。
## 實作階段的分支選擇
- 判斷同名與否,兩邊都用遠端的分支名(`origin/{來源分支}` 與 `origin/{目標分支}`)。
- **只有來源分支與目標分支同名時才開新的工作分支**:同名就不可在該分支上直接 commit,改從已更新到最新的目標分支建立新工作分支,後續操作都以新分支為準。不同名就在目前分支處理。
- 新分支名稱要可讀且不覆蓋既有分支;本地或遠端已存在同名分支時,換一個時間戳或短 hash。
- 切換或建立分支屬不可忽略的狀態變更,要在輸出中講清楚原因與結果分支名稱。
## 實作一律在 worktree 內進行
`implement` 動任何程式碼之前,先從**分析頁記錄的來源分支**建立 git worktree。所有修改都在 worktree 內,主工作目錄的分支與工作區完全不動。
`implement` 動任何程式碼之前,先 `git fetch --prune origin`,再從**分析頁記錄的來源分支的遠端版本**(`origin/{來源分支}`)建立 git worktree。所有修改都在 worktree 內,主工作目錄的分支與工作區完全不動。
### 路徑
@@ -57,8 +77,8 @@
| 選項 | 指令 | 影響 |
| --- | --- | --- |
| 以來源分支為基準開新工作分支 | `git worktree add -b {工作分支} {路徑} {來源分支}` | commit 落在新分支,來源分支不動 |
| 直接簽出來源分支 | `git worktree add {路徑} {來源分支}` | commit 直接進來源分支;同一分支不能同時簽出於兩處 |
| 以來源分支為基準開新工作分支 | `git worktree add -b {工作分支} {路徑} "origin/{來源分支}"` | commit 落在新分支,來源分支不動 |
| 直接簽出來源分支 | `git worktree add --track -b {來源分支} {路徑} "origin/{來源分支}"` | 建立追蹤遠端的本地分支再簽出;本地已存在同名分支時指令會失敗,此時先確認它與遠端一致才可改用 `git worktree add {路徑} {來源分支}`,不一致就停下回報 |
**不得自行預設**,也不得跳過詢問。
@@ -68,7 +88,7 @@
- 找不到該存取庫的本地 clone → **停下來問使用者路徑**,不自行 clone、不臆測位置。
- 目標路徑已存在 → 不覆蓋。先確認它是不是同一份工作的 worktree(`git worktree list`),是就沿用,不是就回報並停止。
- 把 `.worktree/` 加進該存取庫的 `.git/info/exclude`(不動使用者的 `.gitignore`,那是專案共用檔)。
- 建立後在輸出中明確列出:worktree 路徑、簽出的分支、來源分支。
- 建立後在輸出中明確列出:worktree 路徑、簽出的分支、來源分支,以及 `origin/{來源分支}` 當下的 commit sha——那是這次實作的起點,要能事後追。
### 移除時機