🐛 fix(vscode): worktree 清理改 rm -rf + prune,绕开 gitignored 产物导致的目录非空
git worktree remove 只删跟踪文件+admin 注册,不删 .next/node_modules 等 gitignored 产物,删完残留把目录撑住、最后 rmdir 撞 ENOTEMPTY。新增 removeWorktreeDir(带路径护栏的递归强删 + git worktree prune),替换 3 处 worktree remove 调用点。
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { execFile } from 'node:child_process'
|
||||
import { promises as fsp } from 'node:fs'
|
||||
import * as os from 'node:os'
|
||||
import * as path from 'node:path'
|
||||
|
||||
@@ -65,3 +66,38 @@ export async function createWorktree(opts: WorktreeOpts): Promise<void> {
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个 worktree 目录并清掉 git 侧注册。
|
||||
*
|
||||
* 为什么不用 `git worktree remove`:它只删自己跟踪的文件 + admin 注册,
|
||||
* 不删 gitignored 的构建产物(如 .next / node_modules)。删完后这些残留把目录
|
||||
* 撑住,git 最后一步 rmdir 撞 ENOTEMPTY(目录非空)而整体失败——`--force`
|
||||
* 只解决"工作树脏",救不了这个。故直接递归强删目录,再 `worktree prune` 抹掉
|
||||
* git 侧可能残留的死注册。
|
||||
*
|
||||
* rm -rf 危险,删前用护栏挡住明显异常的路径:非绝对、根、home、workspaceRoot
|
||||
* 本身或其祖先、层级过浅——任一命中直接抛错、绝不删。
|
||||
*/
|
||||
export async function removeWorktreeDir(workspaceRoot: string, absWorktreePath: string): Promise<void> {
|
||||
const abs = path.resolve(absWorktreePath)
|
||||
const wsAbs = path.resolve(workspaceRoot)
|
||||
const shallow = abs.split(path.sep).filter(Boolean).length < 3
|
||||
const isRootOrHome = abs === path.parse(abs).root || abs === os.homedir()
|
||||
// abs 等于 workspaceRoot 本身、或是它的祖先目录,都会把主仓库一起端走。
|
||||
const engulfsWorkspace = abs === wsAbs || wsAbs.startsWith(abs + path.sep)
|
||||
if (!absWorktreePath || !path.isAbsolute(absWorktreePath) || shallow || isRootOrHome || engulfsWorkspace)
|
||||
throw new Error(`拒绝删除可疑的 worktree 路径: ${absWorktreePath}`)
|
||||
|
||||
await fsp.rm(abs, { recursive: true, force: true })
|
||||
|
||||
// git 侧可能还留着指向已删目录的死注册;prune 抹掉它。目录已删是主目标,
|
||||
// prune 失败只是 `worktree list` 里留一条死记录,非致命。
|
||||
await new Promise<void>((resolve) => {
|
||||
execFile('git', ['-C', workspaceRoot, 'worktree', 'prune'], { timeout: 30_000 }, (err) => {
|
||||
if (err)
|
||||
console.warn(`[superpowers] git worktree prune 失败(非致命): ${err.message}`)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user