Help us improve
Share bugs, ideas, or general feedback.
From bb-channel
Use when 用户想把本地代码通过 PR 流程推送到远程仓库。自动检测当前目录是单仓库还是多仓库,支持批量或选择性处理。用户也可通过参数指定单个仓库目录。常见触发:"push 一下"、"提个 PR"、"代码推上去"。
npx claudepluginhub 0xbb2b/skills --plugin bb-channelHow this skill is triggered — by the user, by Claude, or both
Slash command
/bb-channel:git-push-prThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
将本地代码通过标准 PR 流程推送到远程仓库。自动识别单仓库或多仓库场景,逐仓库执行:创建分支 → 提交 → 推送 → 创建 PR → 选择处理方式(自动合并 / 已合并 / 关闭 PR)→ 清理分支。
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Compacts the current conversation into a handoff document for another agent to continue the work, with suggested skills and redacted sensitive info.
Share bugs, ideas, or general feedback.
将本地代码通过标准 PR 流程推送到远程仓库。自动识别单仓库或多仓库场景,逐仓库执行:创建分支 → 提交 → 推送 → 创建 PR → 选择处理方式(自动合并 / 已合并 / 关闭 PR)→ 清理分支。
用户可在调用时附带目录路径,直接指定处理某个仓库,例如:
/repo-push ./my-project/repo-push /absolute/path/to/repo如果未指定路径,则自动检测当前目录。
检测当前工作目录的仓库结构:
检测方式:
# 判断当前目录是否为 git 仓库
git rev-parse --git-dir 2>/dev/null
# 如果不是,扫描子目录
ls -d */ # 然后逐个检查子目录是否包含 .git
在循环或脚本里,禁止将以下名字用作自定义变量,否则可能触发 read-only variable 错误:
status、path、PATH、SECONDS、LINENO、RANDOM、PWD、OLDPWD、UID、EUID、PPID
推荐短名替代:st、p / repo_dir、br 等。
确定范围后,对每个目标仓库依次执行以下步骤。
检查当前所在分支:
git branch --show-current
main(或 master)上:必须先创建新分支再继续。分支名应基于改动内容,询问用户或根据改动自动生成一个有意义的名称。在 commit / push / PR 之前,必须至少跑一次全量测试,确保推送出去的代码是绿的。
命令选择优先级:
优先使用 Makefile:检查仓库根目录是否存在 Makefile,若存在则按顺序查找以下 target,命中即用 make <target>:
testtestscheckcitest-all检测方式:
# 列出 Makefile 中的 target(简易匹配)
grep -E '^[a-zA-Z_-]+:' Makefile | cut -d: -f1
Fallback 到项目类型推断:若无 Makefile 或无匹配 target,按项目类型选择默认命令:
go.mod):go test ./...package.json 中有 test 脚本):bun test 或 bun run testCargo.toml):cargo testpyproject.toml / pytest.ini):pytest都无法确定:停下并询问用户该用什么命令跑测试。
失败处理:
检查工作区状态:
git status --short
禁止使用 git add . 或 git add -A,必须明确暂存需要提交的文件。如有不确定是否应提交的文件(如 .env、凭据文件),必须先询问用户。
git push -u origin <branch-name>
如果推送失败,停止并报告错误。
根据远程仓库平台选择工具:
gh pr createglab mr create判断方式:
git remote get-url origin
github → 使用 ghgitlab → 使用 glab创建 PR 时:
PR 创建成功后,向用户明确询问处理方式(除非用户在调用时已显式声明,如"自动合并一下"、"我已经合了"、"建完直接关掉"):
PR 已创建:<PR 链接> 请选择处理方式:
- 自动合并:CI 通过后由平台自动 squash 合并并删除远程分支
- 已合并:你已在网页完成 review 与合并,我会校验状态后继续清理
- 关闭 PR:放弃本次改动,关闭 PR 并删除分支
多仓库场景下逐仓库分别询问,互不绑定。
设置 PR 自动合并:
# GitHub(gh 用 --auto)
gh pr merge <PR_NUMBER> --squash --auto --delete-branch
# GitLab(glab 用 --auto-merge,注意与 gh 不同名)
glab mr merge <MR_IID> --squash --auto-merge --remove-source-branch
⚠️ 易错点:GitHub
gh是--auto,GitLabglab是--auto-merge,不要混用。
自动合并 flag 让平台自行判断时机:CI 通过后立即 squash 合并并删除远程分支;若仓库未启用 auto-merge 功能,会立即报错,此时回退执行不带自动合并 flag 的同名命令做即时合并。
设置完成后,查询一次 PR / MR 状态确定后续走向:
# GitHub
gh pr view <PR_NUMBER> --json state -q .state
# GitLab
glab mr view <MR_IID> --output json | jq -r .state
状态值映射(GitHub → GitLab):MERGED ↔ merged、OPEN ↔ opened、CLOSED ↔ closed。
已合并(GitHub MERGED / GitLab merged):合并已立即完成(CI 已通过或仓库无 CI 门槛),继续步骤 8、9 做本地清理。
仍开启(GitHub OPEN / GitLab opened):进入下方「CI 状态检查」决定挂起、等待平台动作或主动介入修复,不要直接挂起跳过检查。
命令报错:先解析报错原因,按下表分流:
即时合并命令:
# GitHub
gh pr merge <PR_NUMBER> --squash --delete-branch
# GitLab
glab mr merge <MR_IID> --squash --remove-source-branch
PR 仍处 OPEN,或命令报错指向 CI 失败时,必须先查 CI / pipeline 实际状态再决定挂起、等待还是主动介入。不能盲目相信 --auto 会自行兜底——平台只会在 CI 通过后合并,CI 失败时 PR 会一直挂在那里不动,需要 Agent 主动介入。
# GitHub
gh pr checks <PR_NUMBER>
# 或结构化输出:gh pr view <PR_NUMBER> --json statusCheckRollup
# GitLab
glab mr view <MR_IID> --output json | jq -r '.head_pipeline.status // .pipeline.status // "none"'
# 或:glab ci status --branch <branch-name>
按结果分流:
无 CI checks(输出 no checks / none 等):--auto 没有等待门槛,稍等 1-2 秒重查 PR 状态;MERGED 进入步骤 8、9;仍 OPEN 则告知用户挂起后跳过步骤 8、9。
CI 全部通过(all pass / success):平台即将合并,稍等 1-2 秒重查 PR 状态;MERGED 进入步骤 8、9;仍 OPEN 则告知用户挂起后跳过步骤 8、9。
CI 进行中(pending / running / queued / in_progress):告知用户:
PR <链接> 的 CI 仍在运行。已设置自动合并,CI 通过后会自动 squash 合并并删除远程分支;若 CI 失败请告诉我,我会先修复错误再重试合并。
skill 流程结束,跳过步骤 8、9,避免长时间挂起。
CI 失败(任一 check 为 fail / failure / error / cancelled):不能挂起,进入下方「CI 失败处理」。
状态查询命令报错:报告原始错误(多半是网络或权限),等待用户指示。
发现 CI 失败时,按顺序介入,不要让 PR 挂在自动合并状态等下次 push:
先取消自动合并,避免修复 commit 触发 CI 通过后被平台立即合入(修复未经用户复核就被合并是高风险动作):
# GitHub
gh pr merge <PR_NUMBER> --disable-auto
# GitLab(无直接 flag,通过 API 调取消接口)
PROJECT_ID=$(glab repo view --output json | jq -r .id)
glab api -X POST "projects/${PROJECT_ID}/merge_requests/<MR_IID>/cancel_merge_when_pipeline_succeeds"
若取消命令本身失败,先报告错误后再继续诊断(不阻塞下一步排查)。
拉取失败详情,定位具体失败 check 与日志:
# GitHub
gh pr checks <PR_NUMBER> # 看哪些 check 失败
gh run view <RUN_ID> --log-failed # 失败 job 的日志
# GitLab
glab ci view # 当前分支 pipeline 视图
glab ci trace --job <JOB_ID> # 失败 job 的日志
判断失败性质,二选一(与上文「冲突处理」同思路):
机械性失败 → 自行修复,不打扰用户。识别特征(满足任一即可):
gofmt、prettier、eslint --fix、cargo fmt、ruff format 等可一键修复)bun install / go mod tidy / cargo update / pip-compile 重新对齐即可)本地修复 → git add <files> → git commit → git push(普通 push 即可,无需 --force-with-lease)→ 重新执行步骤 7a 的自动合并设置命令(取消后需重新设置)。CI 重新跑通过后平台会自动 squash 合并。
业务性失败 → 立即停下,向用户报告并等待明确指示。识别特征(满足任一即停):
tsc、mypy、go vet 等带语义判断的失败)报告内容:失败的 check 名 + 关键错误日志(最具诊断价值的几行) + 你对失败性质的判断。在用户给出明确指示前,不要 force push、不要 close PR、不要重新设置自动合并,保持失败现场便于 review。
边界判断不确定时按"业务性失败"对待——宁可多打扰一次,不可在用户不知情时改动业务行为后被自动合并。
当 --auto(或回退即时合并)因 base 分支冲突失败时,先在本地复现冲突、判断性质,再决定是否打扰用户。
拉取 base 并尝试 rebase 复现冲突:
git fetch origin
git rebase origin/main # 若仓库默认分支是 master 则换成 origin/master
判断冲突性质,二选一:
机械性冲突 → 自行解决,不提醒用户。识别特征(满足任一即可视为机械性):
就地解决 → git add <files> → git rebase --continue → git push --force-with-lease(必须 --force-with-lease 而非 --force)→ 重新执行步骤 7a 的自动合并命令。
触碰业务逻辑或设计语义 → 立即停下,向用户报告并等待明确指示。识别特征(满足任一即停):
报告内容:冲突文件清单 + 关键冲突段(含 <<<<<<< HEAD / ======= / >>>>>>> 上下文)+ 你对冲突性质的判断。在用户给出明确指示前,不要 git rebase --continue 也不要 git rebase --abort,保持冲突现场。
边界判断不确定时按"触碰逻辑"对待——宁可多打扰一次,不可在用户不知情时改动业务行为。
用户声明已在网页完成合并。必须先查询 PR/MR 实际状态校验,不要直接相信用户的口头确认(用户可能误点了 Close、关掉了页面没真合并、或合并到错的分支):
# GitHub
gh pr view <PR_NUMBER> --json state -q .state
# GitLab
glab mr view <MR_IID> --output json | jq -r .state
按状态分支处理:
MERGED / merged:合并已确认,继续步骤 8、9 做本地清理。
OPEN / opened(PR 仍开启,实际未合并):明确提醒用户并停下等待:
检查到 PR <链接> 仍处于 OPEN 状态,似乎尚未完成合并。请到网页确认是否已点击 Merge,完成后再告诉我继续; 如果你是想关闭而非合并,请说一声,我改走关闭 PR 流程(7c)。
用户再次声明已合并后,必须重新查询一次状态再继续;连续两次校验失败则继续等待,不要凭口头确认进入清理。
CLOSED / closed(已关闭未合并):提醒用户:
PR <链接> 状态为 CLOSED,并未合并。是希望我按关闭 PR 流程(7c)继续清理本地,还是重新打开并合并?
按用户指示再继续,不要自行决定。
状态查询命令报错:报告原始错误(多半是网络或权限),等待用户指示。
用户选择放弃此次改动:
# GitHub(关闭并删除远程分支一步到位)
gh pr close <PR_NUMBER> --delete-branch --comment "<可选关闭说明>"
# GitLab(close 不会自动删除源分支,需后续步骤 9.3 探测删除)
glab mr close <MR_IID>
关闭成功后继续步骤 8、9 做本地清理:
如果 gh pr close / glab mr close 失败(多半是权限或 PR 已被他人处理),报告原始错误并停止,等待用户指示。
由步骤 7(7a 已就地合并 / 7b 状态校验确认已合并 / 7c 已关闭 PR)进入本步骤:
git checkout main
git pull origin main
如果 pull 失败,停止并报告。
清理本地分支、远程分支、本地保存的远程引用三者,确保最终状态干净。必须按 9.1 → 9.4 顺序全部执行,不能因为前一步成功就跳过后面任意一步。
# 9.1 防御性确认当前在 main(步骤 8 已切,再 check 一次)
git rev-parse --abbrev-ref HEAD # 必须输出 main 或 master,否则停止报错
# 9.2 删除本地分支:始终用 -D,不要先试 -d
git branch -D <branch-name>
# 9.3 删除远程分支:先探测是否还存在
if git ls-remote --exit-code --heads origin <branch-name> >/dev/null 2>&1; then
git push origin --delete <branch-name>
fi
# 9.4 裁剪本地的远程引用
git fetch -p
-D 而非 -d:squash merge 之后,功能分支的 commit hash 与 main 上 squash 后的新 commit 不同,git 不会把它识别为"已合并",git branch -d 几乎一定失败;7c 关闭 PR 场景下分支根本没合并,-d 同样会拒绝。直接 -D 强制删除是正确做法——此时 PR 已被显式处理(7a/7b 状态查询已确认合并 / 7c 已关闭),分支安全可删。gh --delete-branch / glab --remove-source-branch 已删除远程分支;7c gh pr close --delete-branch 同样会删;7b 用户也可能在网页上点了"删除分支"。直接 git push origin --delete 会报"remote ref does not exist"。先用 git ls-remote 探测再决定。refs/remotes/origin/<branch-name> 仍然残留。不跑 git fetch -p,后续 git branch -a 会持续看到一堆已被合并删除的过期分支。这一步不可省略。git worktree list,若有 worktree 引用该分支,先 git worktree remove <path> 再重试 9.2。每个仓库各自完整执行 9.1–9.4,互不影响。任一仓库失败不阻塞其他仓库继续清理。
当处理多个仓库时:
最终回复简洁明确:
遇到以下情况必须停下,告知用户并等待指示:
git push --forcegit reset --hardgit checkout -- .merge 或 rebase 策略(必须使用 --squash).env、凭据等)