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>
61 lines
2.4 KiB
JavaScript
61 lines
2.4 KiB
JavaScript
#!/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 };
|
||
});
|