🐛 fix(vscode): 实施启动自动丢掉残留 worktree 再新建
This commit is contained in:
1 parent
23ebdc0509
commit
afdb98ad55
3 files changed
+36
-32
No files matched your search
+14
-23
@@ -7,6 +7,7 @@ import { execFile } from 'node:child_process'
|
||||
import { promises as fsp, readdirSync, readFileSync, readlinkSync } from 'node:fs'
|
||||
import * as os from 'node:os'
|
||||
import * as path from 'node:path'
|
||||
import { deleteLocalBranch } from './branchSync'
|
||||
|
||||
/**
|
||||
* 把开头的 `~` 展开为用户 home 目录。execFile 不走 shell,传给它的命令/路径
|
||||
@@ -28,7 +29,7 @@ export function resolveWorktreePath(stored: string, workspaceRoot: string): stri
|
||||
|
||||
export interface WorktreeOpts {
|
||||
workspaceRoot: string
|
||||
/** 模板 path;① 已有 live worktree 时返回值可能与此不同。 */
|
||||
/** 模板 path;返回值即此路径。 */
|
||||
worktreePath: string
|
||||
branch: string
|
||||
}
|
||||
@@ -104,43 +105,33 @@ async function findLiveWorktreeForBranch(workspaceRoot: string, branch: string):
|
||||
return undefined
|
||||
}
|
||||
|
||||
async function localBranchExists(workspaceRoot: string, branch: string): Promise<boolean> {
|
||||
try {
|
||||
await runGit(workspaceRoot, ['show-ref', '--verify', '--quiet', `refs/heads/${branch}`])
|
||||
return true
|
||||
}
|
||||
catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保证这个 feature 有一个可用 worktree。优先复用 live,绝不删 feature 分支
|
||||
* —— 拖到「进行中」是开始实施,不是销毁上次进度。
|
||||
* 拖到「进行中」= 从当前 HEAD 全新实施:清 leftover worktree / 本地分支,再 `add -b`。
|
||||
*/
|
||||
export async function ensureWorktree(opts: WorktreeOpts): Promise<string> {
|
||||
const { workspaceRoot, branch } = opts
|
||||
const worktreePath = path.resolve(opts.worktreePath)
|
||||
|
||||
// ① 该 branch 已在某个 live worktree → 原路返回(path ≠ 模板也不搬,避免丢未提交改动)
|
||||
// ① 该 branch 的 live worktree 可能不在模板 path → kill + 整目录删掉
|
||||
const live = await findLiveWorktreeForBranch(workspaceRoot, branch)
|
||||
if (live) {
|
||||
console.log(`[superpowers] 复用已有 worktree ${live} (${branch})`)
|
||||
return live
|
||||
killProcessesUsingWorktree(live)
|
||||
await removeWorktreeDir(workspaceRoot, live)
|
||||
}
|
||||
|
||||
// ② 模板 path 被垃圾占着(存在,但不是本仓库该 branch 的 live worktree)
|
||||
// ② 模板 path 仍被垃圾目录占着 → 同样 kill + remove,否则 ④ add 撞路径
|
||||
if (await pathExists(worktreePath)) {
|
||||
killProcessesUsingWorktree(worktreePath)
|
||||
await removeWorktreeDir(workspaceRoot, worktreePath)
|
||||
console.log(`[superpowers] 已清模板路径垃圾 ${worktreePath}`)
|
||||
}
|
||||
|
||||
const branchExists = await localBranchExists(workspaceRoot, branch)
|
||||
const addArgs = branchExists
|
||||
? ['worktree', 'add', worktreePath, branch] // ③ 有分支无 live worktree → 不加 -b,挂上已有分支,保留 commit
|
||||
: ['worktree', 'add', worktreePath, '-b', branch] // ④ 分支也不存在 → -b 新建
|
||||
await runGit(workspaceRoot, addArgs, 'git worktree add')
|
||||
// ③ leftover 本地分支必须删掉;失败不能静默,否则 ④ `add -b` 撞同名分支
|
||||
const deleted = await deleteLocalBranch(workspaceRoot, branch)
|
||||
if (!deleted.ok)
|
||||
throw new Error(`删除本地分支失败 ${branch}: ${deleted.stderr || deleted.stdout}`)
|
||||
|
||||
// ④ 始终 -b 从当前 HEAD 新建,不挂旧分支
|
||||
await runGit(workspaceRoot, ['worktree', 'add', worktreePath, '-b', branch], 'git worktree add')
|
||||
return worktreePath
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user