提交、推送并创建PR 是做什么的?
在当前功能分支上完成工作流程:提交 → 推送 → PR。确认门(第6步)控制推送操作——即使在同一轮中连续调用,也绝不能跳过。
接受一个可选参数:基础分支。如果未提供,第5步将解析出基础分支。
1. 检查分支
git branch --show-current。如果是 main/master,则停止并告知用户先创建功能分支——绝不能在 main 上直接提交或推送。
2. 确定提交范围
git status + git diff。仅暂存属于当前任务的文件。未跟踪的文件,如果看起来像是临时输出、生成的数据或本地测试夹具(CSV、*_results/*、日志文件),则不会自动暂存——列出它们并询问用户是否要包含、忽略或添加到 gitignore。
3. 提交前检查
查找仓库自身的格式化/检查命令——按顺序检查 AGENTS.md、CLAUDE.md、README.md 中是否有文档记录的格式化工具/检查器,并运行指定的工具。如果这些文档都没有指定,则不要默认使用 dotnet format 或其他特定工具猜测——注明没有文档记录格式化工具/检查器并继续。
如果改动涉及经过测试的代码并且可以快速运行有针对性的测试,则运行它;不要为了提交而运行完整的测试套件。
4. 提交信息
遵循约定式提交格式(feat|fix|test|docs|refactor(scope): summary),与仓库 git log 中已有的风格保持一致。仅当“原因”在 diff 中不明显时才提供正文。
5. 解析基础分支
基础分支为 main,除非工作是叠加的——即构建在尚未合并的功能分支之上,此时基于 main 会将下方的分支拖入当前 diff。
- 提供了参数——即为基础分支。使用
git rev-parse --verify origin/<base>验证;如果引用不存在,则说明情况并使用main。 - 未提供参数——寻找一个候选分支。以下任一情况:
- 对话表明当前工作位于另一个分支的提交之上。
- 工作来自一个被另一个工单阻塞或依赖另一个工单的工单——解决该阻塞工单的分支即为候选分支。
git log --oneline origin/main..HEAD显示当前任务未产生的提交;git branch -r --contains <sha>指出这些提交的来源。
- 验证候选分支。 它必须存在于远程、与当前分支不同、并且不在
git branch -r --merged origin/main中——已合并到main的候选分支是无效的。 - 无候选分支,或验证失败——使用
main。
已验证的候选分支是建议而非决定:在第6步的门控中同时提供该选项和 main,让用户选择。
6. 确认门——推送
向用户显示提交信息、git diff --stat(或已创建的提交)以及第5步确定的基础分支——如果第5步找到了候选分支,则显示两个选项。在 git push -u origin <branch> 之前获得明确的授权。推送操作会发布分支——视为单向操作。PR创建依赖于同一个确认(见第7步),无需单独的批准。
7. 创建PR
首先检查该分支是否已经存在PR:gh pr list --head <branch> --state all。
- 找到开放的PR——重用它,不要重复创建。报告其URL。
- 找到已合并的PR——该分支已发布过一次;停止并询问用户想要做什么,然后再创建另一个PR(合并后的新提交是非典型情况)。
- 不存在PR或已合并的PR——第6步的推送确认已涵盖此情况:起草正文并直接运行
gh pr create --base <base> --head <branch> --title "<title>" --body "<body>",无需额外批准。
可见的UI变更截图。 如果改动改变了用户可见的任何内容——新的文本字段、颜色变化、新布局或文案、新页面或组件——则捕获快乐路径和变更引入的边缘情况(空白和错误状态、长/溢出文本、响应式与桌面端的对比)。使用 gh pr create --attach '<path>#<alt text>' 上传(每个图片重复此命令;使用 gh pr edit <pr> 添加到现有PR)。如果正文引用了相同的路径——例如,## Screenshots 标题下的 ——gh会就地重写引用到上传的URL;否则附件会追加在正文末尾。这适用于私有仓库:附件对具有仓库访问权限的任何人都可见。将文件保留在提交之外(临时目录)——它们被上传,而非版本化。需要 gh ≥ 2.99;在旧版本上,将图片拖入Web UI的PR正文中。仅在变更是用户不可见的情况下跳过(逻辑、测试、配置、文档、CI)。
在起草之前,检查仓库自身的PR描述标准——.github/PULL_REQUEST_TEMPLATE.md、.github/pull_request_template.md、docs/* 或 CONTRIBUTING.md 中关于PR正文的指导。仓库文档化的模板会覆盖下面的模板;请使用它。
PR正文模板(后备方案——如果存在仓库标准则优先使用)
## 摘要
<变更了什么及原因,1-6句>
## 变更
- <值得注意的变更1>
- <值得注意的变更2>
## 截图
<对于可见的UI变更:快乐路径 + 相关边缘情况;对于不可见变更请省略>
## 设计决策
<值得注意的权衡或已被拒绝的替代方案——仅适用于较大的功能变更,见下文>
## 测试
<已运行的命令 / 如何验证>
## 后续工作
<推迟的工作,或“无”>
当基础分支不是 main 时,在摘要中命名基础分支以及必须先合并的内容——审查者需要知道 diff 是叠加的,并且一旦基础分支合并,PR将重新定向到 main。
仅在PR引入了实际规模的新功能行为(新模块、非平凡算法、审查者可能不得不询问的权衡)时才包含设计决策——对于文档/配置/杂务/小型修复,请完全省略该部分,而不是留空。
8. 审查向导(仅限大型变更)
在以下任一条件成立时编写一个自包含的HTML向导:
- diff涉及多个不同的非UI模块;
- 更改了数据库模式(迁移、表、列、索引、约束);
- 是一个大型端到端功能(跨越多个层次的新流程)。
对于文档、配置、杂务、小型修复以及仅限于一个模块或仅UI的变更,请跳过。向导的目的是缩短审查时间——不要为每个PR自动生成。
在提交之外的临时目录中编写一个文件 pr-walkthrough.html(永远不要暂存它),使用 open pr-walkthrough.html 在本地打开它,并向用户提供路径。不要托管、附加或版本化它。
结构上使用原生 <details>/<summary> 可折叠标题组织为章节——第一个章节展开,其余折叠——以便审查者浏览标题并仅展开他们需要的内容。无需JavaScript。
为未阅读diff的审查者编写:
- 内容及原因——用几句话描述变更,以及阅读diff的顺序。
- 变更图——涉及哪些模块以及它们如何连接。是图表,而不是文件列表。
- 机制——每段不明显的逻辑或数据流,在提到的代码(
path:line)旁边解释。 - 模式变更——变更前后的表结构、迁移路径以及风险(锁、回填、回滚)。
- 难点——审查者原本不得不询问的部分,以及需要仔细审查的内容。
图表:内联SVG,手写并适应内容大小,用于模块依赖关系、请求/序列流和模式。保持文件自包含——没有外部JS、CSS或图片URL,以便离线打开。仅当被解释的内容是视觉内容时,才使用渲染图片或截图。
9. 报告
向用户提供PR URL及其目标基础分支。明确说明已提交、推送和创建了哪些内容——不要含糊其辞。
