Files
tea-sdlc/scripts/worktree-ensure.js
T
jiantw83andClaude Opus 5 2562555058 feat(worktree-ensure): 定位工作包的工作樹,不在就重建
處理 PR 留言的人不必先手動 cd 到正確的目錄:路徑由 owner/repo/分支名 純函式推導,
問這一支就知道該在哪裡動手。

「不在就重建」是常態不是防禦性程式設計。進度完全不寫在本機——換一台機器或換一個
agent 接手時,工作樹本來就不存在,而重建的成本就是一次 git worktree add。

兩種情況明確中止而不是硬幹:分支在本機與遠端都不見時報 BRANCH_NOT_FOUND(憑空長一棵
空的工作樹只會讓人以為進度還在),推導出的路徑上是別的東西時報 WORKTREE_PATH_TAKEN。

議題 #42

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

66 lines
2.5 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 {
ScriptError,
createWorktree,
main,
openGitRepo,
parseFlags,
parseRepo,
planWorktree,
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);
if (!git('remote').split('\n').includes('origin')) {
throw new ScriptError(
'NO_ORIGIN',
`${path} 沒有 origin 遠端;重建工作樹要先能讀到 origin/${branch},請先設定 origin`,
);
}
// 不給 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 };
});