✨ feat(vscode): 手动删除 worktree 时连同 feature 分支一起删(本地+远程)

抽出共享 cleanupFeatureBranch(handlers/branchCleanup.ts):受保护分支跳过、
远程走 gitea API、本地强删(git branch -D),全程 best-effort 只记日志。
「拖到完成」的分支清理改为复用它(71 行 → 12 行);handleDeleteWorktree 在
删完 worktree 目录后同样调用它,确认框与完成提示带上分支名。

放在 handlers 层而非 git/branchSync.ts:后者刻意不依赖 vscode(有单测覆盖
deleteLocalBranch),本函数需 logger(→vscode)+ gitea API。
This commit is contained in:
cruldra committed 2026-07-08 19:05:48 +08:00
1 parent 045e203590
commit f39e61aa7f
3 files changed
+108 -71

No files matched your search

+11 -66
View File
@@ -13,7 +13,7 @@ import { buildCcCommand } from '../../cc/ccCommand'
import { getBrainstormPrompt } from '../../cc/prompts'
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
import { spawnClaude } from '../../cc/spawnClaude'
import { deleteLocalBranch, gitFetch } from '../../git/branchSync'
import { gitFetch } from '../../git/branchSync'
import { detectRepo } from '../../git/remote'
import {
addDependency,
@@ -33,6 +33,7 @@ import { getSettings } from '../../settings/store'
import { webhookCoordinator } from '../../webhook/coordinator'
import { pickRandomIssueColor, themeColorIdToIconUri } from '../issueColor'
import { DEFAULT_PROFILE_PATH, makeNonce, PR_DIFF_SUMMARY_PROFILE_PATH } from '../KanbanPanel'
import { cleanupFeatureBranch } from './branchCleanup'
import * as sessions from './sessions'
export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber: number, toColumn: IssueColumn): Promise<void> {
@@ -509,71 +510,15 @@ export async function handleColumnChange(panel: KanbanWebviewPanel, issueNumber:
if (featureBranch) {
const settingsForBranchCleanup = getSettings(panel.context)
const protectedBranches = new Set(
['main', 'master', settingsForBranchCleanup.devBranch, settingsForBranchCleanup.autoBuildBranch]
.filter((branch): branch is string => Boolean(branch)),
)
if (protectedBranches.has(featureBranch)) {
logger.add({
level: 'warn',
source: 'panel',
message: `跳过受保护分支清理 ${featureBranch} (issue #${issueNumber})`,
})
}
else {
try {
await deleteBranch({
host: remote.host,
token,
owner: remote.owner,
repo: remote.repo,
branch: featureBranch,
})
logger.add({
level: 'info',
source: 'panel',
message: `已删除远程 feature 分支 ${featureBranch} (issue #${issueNumber})`,
})
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'warn',
source: 'panel',
message: `删除远程 feature 分支失败 ${featureBranch} (issue #${issueNumber})`,
details: message,
})
}
try {
const deleted = await deleteLocalBranch(workspaceRoot, featureBranch)
if (deleted.ok) {
logger.add({
level: 'info',
source: 'panel',
message: `已删除本地 feature 分支 ${featureBranch} (issue #${issueNumber})`,
details: deleted.stdout || deleted.stderr,
})
}
else {
logger.add({
level: 'warn',
source: 'panel',
message: `删除本地 feature 分支失败 ${featureBranch} (issue #${issueNumber})`,
details: deleted.stderr || deleted.stdout,
})
}
}
catch (err) {
const message = err instanceof Error ? err.message : String(err)
logger.add({
level: 'warn',
source: 'panel',
message: `删除本地 feature 分支抛错 ${featureBranch} (issue #${issueNumber})`,
details: message,
})
}
}
await cleanupFeatureBranch({
workspaceRoot,
branch: featureBranch,
issueNumber,
devBranch: settingsForBranchCleanup.devBranch,
autoBuildBranch: settingsForBranchCleanup.autoBuildBranch,
remote,
token,
})
}
// 6. 全部成功 → 增量推 done + 清掉 worktreePath + 标记 prMerged。