git-flow-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Flow PR Skill
Git Flow PR 技能
Complete workflow for creating a clean, rebased pull request from in-progress work.
基于进行中的工作创建干净、经过变基的拉取请求的完整工作流。
Step 1 — Confirm Current State
步骤1 — 确认当前状态
Before doing anything, understand what exists:
bash
git status --short # Are there uncommitted changes?
git log --oneline -10 # What commits exist on this branch?
git branch --show-current # Which branch are we on?
BASE_BRANCH="<base-branch>" # e.g. main, develop, release/*
git fetch origin "$BASE_BRANCH"
git log --oneline "origin/$BASE_BRANCH"..HEAD # Commits unique to this branchIdentify:
- The base branch (often , but use the repo's actual target)
main - Any uncommitted changes that need to be staged
- Whether the current branch's ancestor commits are already merged into main
(this determines which strategy to use in Step 4)
--onto
在执行任何操作之前,先了解当前状态:
bash
git status --short # 是否存在未提交的更改?
git log --oneline -10 # 当前分支上有哪些提交?
git branch --show-current # 当前处于哪个分支?
BASE_BRANCH="<base-branch>" # 例如:main、develop、release/*
git fetch origin "$BASE_BRANCH"
git log --oneline "origin/$BASE_BRANCH"..HEAD # 当前分支独有的提交确认以下信息:
- 基础分支(通常为,但需使用仓库实际的目标分支)
main - 需要暂存的未提交更改
- 当前分支的祖先提交是否已合并到main分支
(这将决定步骤4中使用哪种策略)
--onto
Step 2 — Stage and Commit (if uncommitted changes exist)
步骤2 — 暂存并提交(若存在未提交更改)
If there are uncommitted changes, stage and commit them now:
bash
git add <files> # Stage relevant files; be specific — don't `git add .` blindly
git commit -m "<type>(<scope>): <summary>
<body explaining why, not just what>
Closes #<issue-number>"Commit message rules:
- Follow Conventional Commits: ,
feat,fix,docs,chore,refactortest - Scope should reflect the area changed: ,
(gemini),(tooling),(docs), etc.(skills) - For final PRs that should auto-close the issue on merge, use or
Closes #NFixes #N - For stacked/chained PRs or partial work, use to link without auto-closing
Refs #N - Keep the subject line ≤ 72 characters
如果存在未提交更改,立即暂存并提交:
bash
git add <files> # 暂存相关文件;请明确指定文件,不要盲目使用`git add .`
git commit -m "<type>(<scope>): <summary>
<body explaining why, not just what>
Closes #<issue-number>"提交信息规则:
- 遵循Conventional Commits规范:、
feat、fix、docs、chore、refactortest - Scope应反映更改的领域:、
(gemini)、(tooling)、(docs)等(skills) - 对于合并后应自动关闭问题的最终PR,使用或
Closes #NFixes #N - 对于堆叠/链式PR或部分工作,使用关联问题但不自动关闭
Refs #N - 主题行长度≤72字符
Step 3 — Create the Feature Branch
步骤3 — 创建功能分支
Create a new branch from the tip of the current work and give it a descriptive name:
bash
COMMIT=$(git rev-parse HEAD)
git checkout -b feat/<short-description> "$COMMIT"Branch naming convention:
- — new feature or enhancement
feat/<description> - — bug fix
fix/<description> - — documentation only
docs/<description> - — maintenance, tooling, dependencies
chore/<description>
Use kebab-case. Keep it short but descriptive (3–5 words max).
基于当前工作的最新提交创建新分支,并赋予其描述性名称:
bash
COMMIT=$(git rev-parse HEAD)
git checkout -b feat/<short-description> "$COMMIT"分支命名规范:
- — 新功能或增强
feat/<description> - — bug修复
fix/<description> - — 仅文档更改
docs/<description> - — 维护、工具、依赖更新
chore/<description>
使用短横线命名法(kebab-case)。名称应简短但具有描述性(最多3-5个单词)。
Step 4 — Rebase onto origin/<base-branch>
步骤4 — 变基到origin/<base-branch>
Critical: determine the correct rebase strategy before running.
关键: 在执行前确定正确的变基策略。
Case A — No ancestor commits already in the selected base branch (simple case)
情况A — 选定的基础分支中没有祖先提交(简单场景)
The branch was created fresh and diverged directly from the selected base branch:
bash
git rebase "origin/$BASE_BRANCH"分支是基于选定的基础分支全新创建并分叉的:
bash
git rebase "origin/$BASE_BRANCH"Case B — Ancestor commits are already merged into the selected base branch (squash-merge or similar)
情况B — 祖先提交已合并到选定的基础分支( squash-merge或类似场景)
This happens when:
- The branch was created on top of another branch that was already merged
- The repo uses squash-merge PRs, so commit SHAs on the branch differ from the selected base branch
Identify the last commit not in the selected base branch:
bash
undefined以下情况会出现这种场景:
- 当前分支是基于另一个已合并的分支创建的
- 仓库使用squash-merge PR,因此分支上的提交SHA与基础分支不同
找出不在选定基础分支中的最后一个提交:
bash
undefinedFind the oldest commit on this branch not present in the selected base branch
找出当前分支中未出现在选定基础分支中的最早提交
git log --oneline "origin/$BASE_BRANCH"..HEAD
git log --oneline "origin/$BASE_BRANCH"..HEAD
The last line shows the oldest unique commit — its parent is the rebase base
最后一行显示最早的唯一提交 — 其父提交即为变基的基准
ANCESTOR=$(git log --oneline "origin/$BASE_BRANCH"..HEAD | tail -1 | awk '{print $1}')
PARENT=$(git rev-parse "$ANCESTOR"^)
Then rebase only the unique commits onto the selected base branch:
```bash
git rebase --onto "origin/$BASE_BRANCH" "$PARENT" HEADThis replays only the commits that are genuinely new, dropping the already-merged ones.
ANCESTOR=$(git log --oneline "origin/$BASE_BRANCH"..HEAD | tail -1 | awk '{print $1}')
PARENT=$(git rev-parse "$ANCESTOR"^)
然后仅将唯一的提交变基到选定的基础分支:
```bash
git rebase --onto "origin/$BASE_BRANCH" "$PARENT" HEAD这将仅重放真正新增的提交,丢弃已合并的提交。
After rebase — verify
变基后 — 验证
bash
git log --oneline -5 # Should show: new commit(s) on top of origin/<base-branch> HEAD
git status # Should be cleanIf there are conflicts, resolve them file by file, then . Never use unless you are certain the commit is truly redundant.
git add <file> && git rebase --continuegit rebase --skipbash
git log --oneline -5 # 应显示:origin/<base-branch> HEAD之上的新提交
git status # 应显示干净状态如果存在冲突,逐个文件解决冲突,然后执行。除非确定提交确实冗余,否则绝不要使用。
git add <file> && git rebase --continuegit rebase --skipStep 5 — Run Quality Gates
步骤5 — 运行质量检查
Before pushing, run the project's verification suite. For this repo:
bash
just test # All assertions must pass
just lint # Zero findingsFor other projects, run whatever the project defines as its quality gate (CI commands, test suite, type-check, etc.). Do not push a branch that fails its own quality gates.
推送前,运行项目的验证套件。对于本仓库:
bash
just test # 所有断言必须通过
just lint # 零检查结果对于其他项目,运行项目定义的质量检查(CI命令、测试套件、类型检查等)。不要推送未通过自身质量检查的分支。
Step 6 — Push the Branch
步骤6 — 推送分支
bash
git push origin <branch-name> -uThe flag sets the upstream, making future / work without arguments.
-ugit pushgit pullIf the push is rejected because the remote already has a version of this branch (e.g., you rebased), use force-push only on feature branches (never on ):
mainbash
git push origin <branch-name> --force-with-lease--force-with-lease--forcebash
git push origin <branch-name> -u-ugit pushgit pull如果推送被拒绝(因为远程已存在该分支的版本,例如你已执行变基),仅在功能分支上使用强制推送(绝不要在分支上使用):
mainbash
git push origin <branch-name> --force-with-lease--force-with-lease--forceStep 7 — Open the Pull Request
步骤7 — 打开拉取请求
bash
gh pr create \
--title "<type>(<scope>): <concise summary>" \
--base "$BASE_BRANCH" \
--head <branch-name> \
--body "$(cat <<'EOF'bash
gh pr create \
--title "<type>(<scope>): <concise summary>" \
--base "$BASE_BRANCH" \
--head <branch-name> \
--body "$(cat <<'EOF'Summary
摘要
- <bullet 1: what changed and why>
- <bullet 2>
- <bullet 3>
- <要点1:更改内容及原因>
- <要点2>
- <要点3>
Changes
更改详情
| Area | Files |
|---|---|
| <area> | <files> |
<issue-footer: Refs #<issue-number> | Closes #<issue-number>>
EOF
)"
PR title rules:
- Same format as the commit message subject
- Must match the branch's purpose exactly
- ≤ 72 characters
Body rules:
- 2–4 bullet summary (what + why, not just what)
- Changes table for non-trivial diffs
- Use `Refs #N` for stacked/chained PRs and intermediate slices
- Use `Closes #N` only on the final PR that should auto-close the issue| 领域 | 文件 |
|---|---|
| <领域> | <文件> |
<问题脚注: Refs #<issue-number> | Closes #<issue-number>>
EOF
)"
PR标题规则:
- 格式与提交信息主题行一致
- 必须完全匹配分支的用途
- ≤72字符
正文规则:
- 2-4条要点摘要(包含内容及原因,而非仅内容)
- 对于非微小差异,添加更改表格
- 堆叠/链式PR和中间阶段使用`Refs #N`
- 仅在最终PR上使用`Closes #N`以自动关闭问题Step 7.1 — Stacked/Chained PRs
步骤7.1 — 堆叠/链式PR
When a change is too large for one reviewable PR, split into a chain:
- Create from the base branch and open PR A (
feat/<topic>-base).--base "$BASE_BRANCH" - Create from
feat/<topic>-part-2and open PR B (feat/<topic>-base).--base feat/<topic>-base - Continue similarly for PR C, D, etc., each targeting the prior branch.
Rules for stacked PRs:
- Keep each PR independently reviewable and logically scoped.
- PR body should include (not
Refs #N) until final branch in the chain.Closes #N - After lower PRs merge, rebase higher branches onto the updated base branch and force-push with lease.
- Update PR base with when needed.
gh pr edit --base <new-base>
当更改过大无法在一个PR中完成评审时,拆分为链式PR:
- 基于基础分支创建并打开PR A(
feat/<topic>-base)。--base "$BASE_BRANCH" - 基于创建
feat/<topic>-base并打开PR B(feat/<topic>-part-2)。--base feat/<topic>-base - 以此类推创建PR C、D等,每个PR都以上一个分支为基础。
堆叠PR规则:
- 每个PR应独立可评审且逻辑范围清晰。
- PR正文应使用(而非
Refs #N),直到链式中的最后一个分支。Closes #N - 下层PR合并后,将上层分支变基到更新后的基础分支,并使用强制推送。
--force-with-lease - 必要时使用更新PR的基础分支。
gh pr edit --base <new-base>
Step 8 — Verify
步骤8 — 验证
After opening:
bash
gh pr view # Confirm PR is open with correct title, base branch, and issue linkCheck:
- PR title follows Conventional Commits format
- Base branch is correct for the workflow (or parent branch for stacked PRs)
$BASE_BRANCH - Issue linkage uses for intermediate PRs and
Refs #Nonly for final PRsCloses #N - CI checks are triggered and passing (check )
gh pr checks - Branch is up to date with the selected base branch (no "behind by N commits" warning)
打开PR后:
bash
gh pr view # 确认PR已打开,标题、基础分支和问题关联正确检查事项:
- PR标题遵循Conventional Commits格式
- 基础分支符合工作流要求(或堆叠PR的父分支)
$BASE_BRANCH - 问题关联:中间PR使用,仅最终PR使用
Refs #NCloses #N - CI检查已触发并通过(使用查看)
gh pr checks - 分支与选定的基础分支保持同步(无“落后N个提交”警告)