push-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePush & PR
Push & PR
Push commits and create/update pull requests with automatic branch management and
scope-aware multi-PR splitting.
推送提交记录(commit)并创建/更新拉取请求(PR),支持自动分支管理和基于范围的多PR拆分。
Arguments
参数
Parse flexibly from :
$ARGUMENTS- status: =opened,
1=draft,2=ready (default: new PR=opened, update=draft)3 - base-branch: Target branch (default: )
main
从中灵活解析:
$ARGUMENTS- status:=已开启,
1=草稿,2=就绪(默认:新建PR为已开启,更新PR为草稿)3 - base-branch:目标分支(默认:)
main
Pre-Flight Context
预执行上下文
Injected at invocation — analyze before taking any action:
- Working tree status:
!git status --porcelain - Current branch:
!git rev-parse --abbrev-ref HEAD - Unpushed commits:
!git rev-list @{u}..HEAD --count 2>/dev/null || echo "no upstream" - Recent commits: (assumes main base; see Step 3 if base differs)
!git log origin/main..HEAD --oneline 2>/dev/null - Diff stat: (captured before fetch; re-run if stale)
!git diff origin/main...HEAD --stat 2>/dev/null
调用时注入——执行任何操作前先分析:
- 工作区状态:
!git status --porcelain - 当前分支:
!git rev-parse --abbrev-ref HEAD - 未推送的提交记录:
!git rev-list @{u}..HEAD --count 2>/dev/null || echo "no upstream" - 近期提交记录:(假设基准分支为main;若基准分支不同,请查看步骤3)
!git log origin/main..HEAD --oneline 2>/dev/null - 差异统计:(获取前捕获;若过时则重新运行)
!git diff origin/main...HEAD --stat 2>/dev/null
Workflow
工作流程
1. Pre-Flight
1. 预执行检查
Run to sync remote state.
git fetch originIf the working tree status above shows uncommitted changes, invoke to
commit first.
Skill: commitComplete when: remote is fetched and working tree is clean.
运行同步远程仓库状态。
git fetch origin如果上述工作区状态显示存在未提交的更改,先调用完成提交。
Skill: commit完成标志:远程仓库已同步,工作区状态干净。
2. Branch Management
2. 分支管理
If on main/master with unpushed commits, cut a feature branch before proceeding.
Branch naming: prefix from the primary commit's conventional type (, ,
, , ); slug from the commit scope or subject, lowercase hyphens
only, max 45 chars total (keeps branch names readable in GitHub's UI and avoids truncation
in terminal prompts). Use the scope if present ( → ); otherwise
condense the subject to 2–4 words ( → ).
feat/fix/docs/chore/refactor/feat(auth)feat/authfix login redirect timeoutfix/login-redirectbash
git checkout -b <derived-branch-name>
git branch -f main origin/maingit branch -f--hardIf already on a feature branch: skip to step 3.
Complete when: HEAD is on a feature branch (not main/master).
如果当前处于main/master分支且存在未推送的提交记录,先创建功能分支再继续操作。
分支命名规则:以主要提交记录的约定类型作为前缀(、、、、);以提交记录的范围或主题作为后缀,仅使用小写连字符,总长度不超过45个字符(确保分支名称在GitHub界面中可读,避免在终端提示中被截断)。如果存在范围(如 → )则使用范围;否则将主题浓缩为2-4个单词(如 → )。
feat/fix/docs/chore/refactor/feat(auth)feat/authfix login redirect timeoutfix/login-redirectbash
git checkout -b <derived-branch-name>
git branch -f main origin/maingit branch -f--hard如果已处于功能分支:跳至步骤3。
完成标志:当前HEAD指向功能分支(而非main/master)。
3. Context Gathering
3. 上下文收集
Derive working variables from pre-flight context and arguments:
- = base-branch argument, or
BASEif not providedmain - = current branch name (from pre-flight injection)
BRANCH
Use the pre-flight context injected above. If the base branch differs from ,
re-gather against :
mainorigin/$BASEbash
git log origin/$BASE..HEAD --oneline --reverse
git diff origin/$BASE...HEAD --statAlways compare against , not local — the PR targets the remote
branch, so comparisons must match what GitHub will see.
origin/$BASE$BASERecord: commit count, conventional-commit types and scopes present, total diff lines
(approximate from output).
--statComplete when: commit count, scope/type inventory, and approximate diff size are known.
从预执行上下文和参数中推导工作变量:
- = 传入的base-branch参数,若未提供则为
BASEmain - = 当前分支名称(来自预执行上下文注入)
BRANCH
使用上述注入的预执行上下文。如果基准分支与不同,针对重新收集信息:
mainorigin/$BASEbash
git log origin/$BASE..HEAD --oneline --reverse
git diff origin/$BASE...HEAD --stat始终与对比,而非本地——PR的目标是远程分支,因此对比结果必须与GitHub将看到的内容一致。
origin/$BASE$BASE记录:提交记录数量、存在的约定式提交类型和范围、差异总行数(从输出估算)。
--stat完成标志:已获取提交记录数量、范围/类型清单以及大致差异规模。
4. Scope Analysis
4. 范围分析
Evaluate whether the changeset warrants multiple PRs. A split is warranted when either:
- Size: total diff exceeds ~400 lines (code lines; ignore lock files and generated files) — beyond this threshold, reviewer fatigue degrades review quality and catch rate
- Diversity: commits span 3+ distinct conventional-commit scopes or types (e.g.,
,
feat(auth),fix(ui)) — multiple scopes mean the changeset lacks a single narrative, making review harder and revert riskierchore(deps)
If neither condition is met: proceed to step 5 as a single PR.
If either condition is met — propose stacked PRs:
Cluster commits by scope/type in the order they were made. Each cluster becomes one PR
targeting the previous cluster's branch (the first targets ). Present the plan:
$BASEProposed stacked PRs (each PR targets the previous branch):
PR 1 [base: main] feat/auth — commits: abc1234, def5678
PR 2 [base: feat/auth] fix/ui-redirect — commits: ghi9012
PR 3 [base: fix/ui-...] chore/cleanup — commits: jkl3456Use AskUserQuestion: "Split into N stacked PRs as shown above, or push as a single PR?"
If user declines split: proceed to step 5 as a single PR.
If user confirms split — stacked PR execution:
For each cluster in order:
- Create a branch from the previous cluster's branch (for cluster 1):
$BASEbashgit checkout -b <cluster-branch> <previous-branch> git cherry-pick <sha1> <sha2> ... - Push:
git push -u origin <cluster-branch> - Generate PR body using the format script with :
--base <previous-branch>bashpython3 ${CLAUDE_PLUGIN_ROOT}/skills/push-pr/scripts/format-pr-body.py --base "<previous-branch>" - Create PR targeting the correct base branch.
- Repeat for next cluster.
After all PRs are created, check out the last cluster's branch and report the full
stack (see Output). Exit — skip steps 5–7.
Complete when: user has chosen single-PR or stacked, and stacked flow is finished if chosen.
评估变更集是否需要拆分为多个PR。满足以下任一条件时应拆分:
- 规模:总差异超过约400行(代码行;忽略锁文件和生成文件)——超过此阈值后,审核者疲劳会降低审核质量和问题检出率
- 多样性:提交记录涵盖3个及以上不同的约定式提交范围或类型(如、
feat(auth)、fix(ui))——多个范围意味着变更集缺乏统一的叙事逻辑,会增加审核难度和回滚风险chore(deps)
如果两个条件都不满足:继续步骤5,创建单个PR。
如果满足任一条件——建议创建堆叠式PR:
按提交顺序将提交记录按范围/类型分组。每个分组成为一个PR,目标分支为上一个分组的分支(第一个分组的目标为)。展示计划:
$BASE建议的堆叠式PR(每个PR以上一个分支为目标):
PR 1 [基准: main] feat/auth — 提交记录: abc1234, def5678
PR 2 [基准: feat/auth] fix/ui-redirect — 提交记录: ghi9012
PR 3 [基准: fix/ui-...] chore/cleanup — 提交记录: jkl3456使用AskUserQuestion:“按上述方式拆分为N个堆叠式PR,还是作为单个PR推送?”
如果用户拒绝拆分:继续步骤5,创建单个PR。
如果用户确认拆分——执行堆叠式PR流程:
按顺序处理每个分组:
- 基于上一个分组的分支创建新分支(第一个分组基于):
$BASEbashgit checkout -b <cluster-branch> <previous-branch> git cherry-pick <sha1> <sha2> ... - 推送:
git push -u origin <cluster-branch> - 使用格式化脚本生成PR正文,指定:
--base <previous-branch>bashpython3 ${CLAUDE_PLUGIN_ROOT}/skills/push-pr/scripts/format-pr-body.py --base "<previous-branch>" - 创建PR,目标为正确的基准分支。
- 重复上述步骤处理下一个分组。
所有PR创建完成后,切换到最后一个分组的分支并报告完整的堆叠结构(见输出部分)。退出流程——跳过步骤5-7。
完成标志:用户已选择创建单个PR或堆叠式PR;若选择堆叠式PR则已完成全部流程。
5. PR Status
5. PR状态检查
Check for an existing PR on this branch:
gh pr list --head "$BRANCH" --json number,stateUse the provided status argument, or default: new PR=opened, update=draft.
Complete when: existing PR state is known and target status is determined.
检查当前分支是否已有PR:
gh pr list --head "$BRANCH" --json number,state使用传入的status参数,或采用默认值:新建PR为已开启,更新PR为草稿。
完成标志:已了解现有PR状态并确定目标状态。
6. Push
6. 推送代码
Always push with — the flag sets tracking on new branches
and is a no-op when the upstream is already correctly set, so it is always safe to use.
git push -u origin "$BRANCH"-uIf push fails because the remote branch has diverged, run
and retry the push once. If the rebase itself has conflicts, stop and report.
git pull --rebase origin $BRANCHComplete when: branch is pushed and tracking the remote.
始终使用推送——标志会为新分支设置跟踪,对于已正确设置上游的分支则无操作,因此始终安全可用。
git push -u origin "$BRANCH"-u如果推送失败是因为远程分支已偏离,运行并重试一次推送。如果变基过程中出现冲突,停止操作并报告。
git pull --rebase origin $BRANCH完成标志:分支已推送并跟踪远程分支。
7. PR Creation/Update
7. 创建/更新PR
Generate the PR body using the format script:
bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/push-pr/scripts/format-pr-body.py --base "origin/$BASE"Exit 1 means no changes found relative to base; report to user. On success, use stdout
as the PR body directly.
New PR:
bash
gh pr create --title "<title>" --body "<format-pr-body output>" --base "$BASE"使用格式化脚本生成PR正文:
bash
python3 ${CLAUDE_PLUGIN_ROOT}/skills/push-pr/scripts/format-pr-body.py --base "origin/$BASE"返回值1表示相对于基准分支未发现变更;向用户报告此情况。执行成功时,将标准输出直接作为PR正文。
新建PR:
bash
gh pr create --title "<title>" --body "<format-pr-body output>" --base "$BASE"If status=ready: gh pr ready
如果status=ready: gh pr ready
**Existing PR:** Add a comment listing new commits since last push; update PR status if
the status argument changed.
```bash
PR_NUM=$(gh pr list --head "$BRANCH" --json number -q '.[0].number')
gh pr comment $PR_NUM --body "New commits: ..."Complete when: PR URL is obtained and status matches the target.
**现有PR:** 添加评论列出上次推送以来的新提交记录;如果status参数有变化,则更新PR状态。
```bash
PR_NUM=$(gh pr list --head "$BRANCH" --json number -q '.[0].number')
gh pr comment $PR_NUM --body "New commits: ..."完成标志:已获取PR URL且状态符合目标要求。
Constraints
约束条件
Produce clean, unattributed PRs that match the project's existing commit and PR style:
- No Co-authored-by or AI signatures — PRs should look like human-authored work
- No "Generated with Claude Code" — same reason; attribution is the user's choice
- No emojis in PR title or description — most project conventions use plain text
- Use existing git user config only — never modify or
user.nameuser.email
生成简洁、无归属信息的PR,匹配项目现有的提交记录和PR风格:
- 不添加Co-authored-by或AI签名——PR应看起来像是人工编写的成果
- 不添加"Generated with Claude Code"——原因同上;是否归属由用户决定
- PR标题和描述中不使用表情符号——大多数项目约定使用纯文本
- 仅使用现有的git用户配置——绝不修改或
user.nameuser.email
Edge Cases
边缘情况
- No remote → suggest and stop
git remote add origin <url> - No CLI → report requirement and stop
gh - Branch behind remote → pull/rebase before pushing
- No commits to push → report and stop
- Cherry-pick conflict during stacked flow → stop, report the cluster name, failing commit
SHA, and conflicting file(s). Suggest followed by manual resolution, then re-running
git cherry-pick --abort
- 无远程仓库 → 建议并停止操作
git remote add origin <url> - 无CLI → 报告此要求并停止操作
gh - 分支落后于远程 → 先拉取/变基再推送
- 无提交记录可推送 → 报告并停止操作
- 堆叠流程中cherry-pick冲突 → 停止操作,报告分组名称、失败的提交记录SHA和冲突文件。建议运行后手动解决冲突,然后重新执行流程
git cherry-pick --abort
Output
输出
Single PR: branch name, PR URL, PR status (opened/draft/ready).
Stacked PRs: ordered list showing each PR URL and the branch it targets, plus the name
of the final branch now checked out.
单个PR:分支名称、PR URL、PR状态(已开启/草稿/就绪)。
堆叠式PR:有序列表显示每个PR的URL及其目标分支,以及当前已切换到的最后一个分支的名称。