🐛 fix(vscode): 实施启动改为复用已有 feature 分支

This commit is contained in:
2026-08-25 14:45:53 +08:00
parent 0db43f4cc3
commit 24b1ae2ecf
3 changed files with 297 additions and 78 deletions
+5 -44
View File
@@ -16,7 +16,7 @@ import { resolveProfilePath } from '../../cc/profiles'
import { getBrainstormContinuePrompt, getImplementPlanPrompt } from '../../cc/prompts'
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
import { detectRepo } from '../../git/remote'
import { createWorktree, resolveWorktreePath } from '../../git/worktree'
import { ensureWorktree, resolveWorktreePath } from '../../git/worktree'
import { updateIssueAssignees } from '../../gitea/api'
import { logger } from '../../logging/logger'
import { getSettings } from '../../settings/store'
@@ -766,45 +766,7 @@ export async function handleImplement(
// 留空时回退到默认 ~/Sources/worktree/<项目>/<slug>。
const worktreeTemplate = getSettings(panel.context).worktreeDirectory
|| '~/Sources/worktree/$project_name/$feature_name'
const worktreePath = resolveWorktreeDir(worktreeTemplate, workspaceRoot, slug)
// Pre-flight: refuse if either the directory or the branch already
// exists, since `git worktree add -b` would fail and we'd have to
// unwind partial state.
let worktreeExists = false
try {
await fsp.stat(worktreePath)
worktreeExists = true
}
catch {
// ENOENT — good.
}
let branchExists = false
try {
branchExists = await new Promise<boolean>((resolve) => {
execFile(
'git',
['-C', workspaceRoot, 'branch', '--list', branch],
{ timeout: 10_000 },
(err, stdout) => {
if (err) {
resolve(false)
return
}
resolve((stdout ?? '').trim().length > 0)
},
)
})
}
catch {
branchExists = false
}
if (worktreeExists || branchExists) {
void window.showErrorMessage(
`feature ${slug} 的 worktree 或分支已存在,请先清理`,
)
return
}
let worktreePath = resolveWorktreeDir(worktreeTemplate, workspaceRoot, slug)
// 工单级 profilePath > 默认 fallback。工单的 profile 锁定可在工单详情面板里覆盖。
const effectiveProfilePath = panel.resolveImplementProfilePath(profilePath)
@@ -834,20 +796,19 @@ export async function handleImplement(
return
}
// Create the worktree before anything else, so a worktree-add failure
// doesn't leave half-written state behind.
// 先保证 worktree 可用:后面写 state / 开终端都依赖实际 path。
try {
// worktree 现在建在工作区外(~/Sources/worktree/<项目>/...),父目录可能不存在;
// git worktree add 不会创建多层父目录,先补齐。
await fsp.mkdir(path.dirname(worktreePath), { recursive: true })
await createWorktree({ workspaceRoot, worktreePath, branch })
worktreePath = await ensureWorktree({ workspaceRoot, worktreePath, branch })
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'error',
source: 'implement',
message: 'git worktree add 失败',
message: 'ensureWorktree 失败',
details: message,
})
void window.showErrorMessage(message)