71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
import type { ForgeContext } from '../../forge/context'
|
||
import { deleteLocalBranch } from '../../git/branches'
|
||
import { logger } from '../../logging/logger'
|
||
|
||
/**
|
||
* 清理一个 feature 分支(远程 + 本地),供「拖到完成」和「手动删除 worktree」两处共用。
|
||
*
|
||
* - 受保护分支(main/master/devBranch)直接跳过,绝不删。
|
||
* - 远程删除走代码托管接口,需 remote + 凭据;缺任一则只删本地,不阻断。
|
||
* - 本地删除是强删(deleteLocalBranch 内部 `git branch -D`):调用方语义是「连分支一起删」,
|
||
* 未合并也照删。
|
||
* - 全程 best-effort:远程 / 本地各自 try/catch,失败只记日志——分支清理从不回滚已完成的主流程
|
||
* (worktree 已删、PR 已合并)。branch 为空直接返回。
|
||
*
|
||
* 放在 handlers 层而非 `git/branches.ts`:后者刻意不依赖 `vscode`(有单测覆盖
|
||
* deleteLocalBranch),而本函数要用 logger(→ vscode)和代码托管接口。
|
||
*/
|
||
export async function cleanupFeatureBranch(opts: {
|
||
workspaceRoot: string
|
||
branch: string
|
||
issueNumber: number
|
||
devBranch?: string
|
||
/** 没有代码托管仓库时跳过远程删除,只删本地。 */
|
||
forge?: ForgeContext
|
||
}): Promise<void> {
|
||
const { workspaceRoot, branch, issueNumber, devBranch, forge } = opts
|
||
if (!branch)
|
||
return
|
||
|
||
const protectedBranches = new Set(
|
||
['main', 'master', devBranch].filter((b): b is string => Boolean(b)),
|
||
)
|
||
if (protectedBranches.has(branch)) {
|
||
logger.add({ level: 'warn', source: 'panel', message: `跳过受保护分支清理 ${branch} (issue #${issueNumber})` })
|
||
return
|
||
}
|
||
|
||
if (forge) {
|
||
try {
|
||
await forge.provider.deleteBranch(branch)
|
||
logger.add({ level: 'info', source: 'panel', message: `已删除远程 feature 分支 ${branch} (issue #${issueNumber})` })
|
||
}
|
||
catch (err) {
|
||
logger.add({
|
||
level: 'warn',
|
||
source: 'panel',
|
||
message: `删除远程 feature 分支失败 ${branch} (issue #${issueNumber})`,
|
||
details: err instanceof Error ? err.message : String(err),
|
||
})
|
||
}
|
||
}
|
||
|
||
try {
|
||
const deleted = await deleteLocalBranch(workspaceRoot, branch)
|
||
logger.add({
|
||
level: deleted.ok ? 'info' : 'warn',
|
||
source: 'panel',
|
||
message: `${deleted.ok ? '已删除' : '删除失败'}本地 feature 分支 ${branch} (issue #${issueNumber})`,
|
||
details: deleted.stderr || deleted.stdout,
|
||
})
|
||
}
|
||
catch (err) {
|
||
logger.add({
|
||
level: 'warn',
|
||
source: 'panel',
|
||
message: `删除本地 feature 分支抛错 ${branch} (issue #${issueNumber})`,
|
||
details: err instanceof Error ? err.message : String(err),
|
||
})
|
||
}
|
||
}
|