Files
tea-sdlc/scripts/worktree-ensure.js
T
jiantw83andClaude Opus 5 66064a751e fix(lib): 補回搬家時掉了的 rmSync,並讓 origin 檢查只有一份
review 抓到一個沉默的失效:rollback 最後那一手「git 清不乾淨時把目錄本身也清掉」呼叫
rmSync,但把這段從 branch-prep 搬進 lib 時,import 留在了原處。那一行落在自己的
try/catch 裡,所以 ReferenceError 被吞掉——註解承諾的事從來沒發生過,而且測試全綠。
下一次重跑會撞上 WORKTREE_PATH_TAKEN,人看到的是一句與真正原因無關的錯誤。

順手收掉兩支腳本各寫一次的 origin 檢查(只有「為什麼需要它」那一句不同,由呼叫端給),
並把 lib 檔頭「負責六件事」改成七件——工作樹的一生現在整個住在這裡。

正本三處跟著改:
- 查現況那一行補上 --dry-run。pr-watch 在 PR 已終止時會順手清掉工作樹,而「我想看一下
  留言」不該把清理順便做掉——清不清理是使用者的決定。
- 拿掉「使用者堅持要繼續就繼續」:它與同一份正本的邊界(已合併或關閉時不繼續處理留言)
  直接矛盾,而在一棵該被清掉的工作樹上改東西,那些改動不會進到任何 PR 裡。
- worktree-ensure 的指令補上 --path:目標專案多半不是當前目錄,而「不必先手動 cd」
  正是這一步要解決的問題。

議題 #42

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 17:33:44 +08:00

61 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* 定位一顆工作包的工作樹,不在就重建。
*
* 處理 PR 留言的人不必先手動 `cd` 到正確的目錄:路徑由 `owner/repo/分支名` 純函式推導
* (見 lib 的 `worktreePath`),問這一支就知道該在哪裡動手。
*
* **「不在就重建」是常態,不是防禦性程式設計。** 進度完全不寫在本機——換一台機器或
* 換一個 agent 接手時,工作樹本來就不存在,而重建的成本就是一次 `git worktree add`。
*
* 重建與建立走同一套(lib 的 `planWorktree`/`createWorktree`):一樣先 `git fetch`
* 更新遠端引用,一樣不設 upstream,分支已經存在就接上去而不是長一棵空的。兩邊各寫
* 一份,遲早會在「起點取自哪裡」這種地方分岔,而那種分岔要等到有人的進度不見了
* 才會被發現。
*
* 分支在本機與遠端都不存在時明確中止:憑空長一棵空的工作樹,只會讓人以為進度還在。
* 推導出的路徑上是別的東西時也中止,不盲目拿來用。
*
* 用法:
* node scripts/worktree-ensure.js --repo owner/name --branch <分支名>
* [--path <目標專案>] [--dry-run]
*/
import {
createWorktree,
main,
openGitRepo,
parseFlags,
parseRepo,
planWorktree,
requireOrigin,
worktreePath,
} from './lib.js';
main(async () => {
const flags = parseFlags(process.argv.slice(2), {
required: ['repo', 'branch'],
optional: ['path'],
booleans: ['dry-run'],
});
const repo = parseRepo(flags.repo);
const branch = flags.branch;
const path = flags.path ?? process.cwd();
const worktree = worktreePath(repo, branch);
const git = openGitRepo(path);
requireOrigin(git, path, `重建工作樹要先能讀到 origin/${branch}`);
// 不給 source:這裡只重建既有分支的工作樹,沒有「從來源長一支新的」那條路,
// 那是 branch-prep 的事——在這裡憑空開一支新分支,等於把 PR 的進度扔掉
const plan = planWorktree(git, { branch, worktree });
const 報告 = { path, repo, branch, worktree, 動作: plan.動作 };
if (flags['dry-run']) {
return { dryRun: true, ...報告, commands: plan.commands.map((args) => `git ${args.join(' ')}`) };
}
createWorktree(git, plan, { worktree, branch });
return { ...報告, 重建: plan.commands.length > 0 };
});