一、为什么 PR 规范重要
PR(Pull Request)是开源协作的核心单元。一个写得好的 PR:
- 让 reviewer 快速理解改动的目的和范围
- 减少来回沟通的成本
- 留下可查阅的决策记录
- 让 squash merge 后的 git 历史保持整洁
一个写得差的 PR 会让 reviewer 猜测你的意图,导致反复要求修改,甚至直接被关闭。
二、提 PR 之前
1. 一个 PR 只做一件事
这是最重要的原则。
| 好的 PR | 坏的 PR |
|---|---|
| 修复某个 UI bug | 修复 UI bug + 顺手重构了配置模块 + 更新了依赖 |
| 新增某个 API 功能 | 新增功能 + 修了几个不相关的 typo |
如果你发现自己顺手改了不相关的东西,把它拆成独立的 PR。
2. 保持分支整洁
从最新的 master 拉分支,命名要有意义:
# 好的分支名
feat/cross-platform-shell
fix/card-collapse-animation
docs/update-setup-guide
# 坏的分支名
my-branch
fix
test123
3. 提交前自测
- 本地跑一遍测试(
./gradlew test) - 确认没有遗留的
console.log、调试代码 - 确认编译通过
三、Commit Message 怎么写
Conventional Commits 规范
这是目前开源社区最广泛采用的提交规范,格式如下:
<type>(<scope>): <description>
[可选 body:解释 why,不解释 what]
[可选 footer:BREAKING CHANGE 或关联 issue]
type 速查
| type | 含义 | 示例 |
|---|---|---|
feat | 新功能 | feat(chat): add streaming token display |
fix | Bug 修复 | fix(ui): card collapse state not resetting |
docs | 仅文档变更 | docs: add build instructions to README |
refactor | 重构(不是 fix 也不是 feat) | refactor(settings): extract provider config builder |
test | 新增或修改测试 | test(execution): add ShellPlatform unit tests |
chore | 构建/依赖/工具变更 | chore: upgrade gradle to 8.5 |
perf | 性能优化 | perf(webview): lazy load markdown renderer |
ci | CI/CD 流程变更 | ci: add pr title validation workflow |
style | 格式调整,不影响逻辑 | style: fix indentation in ExecutionService |
scope(可选但推荐)
scope 是括号里的部分,说明改动影响的模块:
feat(execution): ... # 影响命令执行模块
fix(webview): ... # 影响前端 React 部分
docs(readme): ... # 影响 README
description 的写法
- 用祈使句(动词开头):
add、fix、remove,不用added、fixed - 首字母小写
- 结尾不加句号
- 不超过 72 个字符
# 好
feat(chat): add retry logic on stream disconnect
# 坏
feat(chat): Added the retry logic for when the stream disconnects.
什么时候需要 body
简单的改动不需要 body。但如果 "为什么改" 不显而易见,就写:
fix(settings): prevent NPE when provider list is empty
Provider list can be null on first launch before any config is saved.
Null check was missing in the initialization path.
Breaking Change 怎么标注
在 type 后加 !,并在 footer 里说明:
feat(settings)!: rename apiUrl to endpointUrl
BREAKING CHANGE: saved settings using the old key `apiUrl` will not
be loaded. Users need to re-enter their endpoint URL after upgrading.
四、PR 标题怎么写
PR 标题 = squash merge 后进入 git 历史的 commit message。
规则和 commit message 完全一致,遵循 Conventional Commits 格式。
# 好的 PR 标题
feat(execution): add cross-platform shell abstraction
fix(ui): correct card collapse animation on resize
docs: update README with Corretto 17 requirement
# 坏的 PR 标题
Update code
Fix bug
WIP
my changes
五、PR 描述怎么写
一个完整的 PR 描述包含三部分:
1. What changed(改了什么)
简洁说明本次变更的内容,一段话即可:
新增了
ShellPlatform抽象层,将 shell 命令执行从平台相关代码中解耦。
Windows 使用cmd /c,macOS/Linux 使用sh -c。
2. Why(为什么改)
说明动机,或关联 issue:
Closes #12
原来的实现在 Windows 上执行命令会失败,因为直接使用了
sh -c。
3. How to test(怎么验证)
给 reviewer 一个可操作的验证步骤:
- 在 Windows 和 macOS 上分别运行插件
- 在 Chat 中发送一条需要执行 shell 命令的请求
- 确认两个平台上命令都能正常执行并返回结果
好的 PR 描述示例
## What changed
Adds `ShellPlatform` abstraction to decouple shell command execution
from platform-specific logic. Windows uses `cmd /c`, Unix uses `sh -c`.
## Why
Closes #12
The previous implementation hardcoded `sh -c` which silently fails on
Windows without any error message shown to the user.
## How to test
1. Run the plugin on Windows (or use the test suite)
2. Trigger any command execution from the Chat panel
3. Verify the command completes successfully and output is streamed back
## Checklist
- [x] Tests pass (`./gradlew test`)
- [x] No debug logs left in code
- [x] PR title follows Conventional Commits
六、作为维护者怎么处理 PR
Review 时关注什么
| 层面 | 关注点 |
|---|---|
| 正确性 | 逻辑是否正确,边界情况有没有处理 |
| 范围 | PR 是否只做了一件事 |
| 测试 | 有没有测试覆盖新行为 |
| 规范 | commit/PR 标题格式是否正确 |
| 破坏性 | 是否影响已有功能或公共 API |
给出 Review 意见的方式
- 指出问题时说明原因,不要只说"这里不对"
- 区分
blocker(必须改)和suggestion(可以考虑) - 对好的实现也给出肯定,不要只挑毛病
关闭 PR 时
解释原因,给出改进方向,不要直接静默关闭:
感谢你的贡献!这个改动目前超出了项目的范围,我们暂时不打算引入这个功能。
如果你想继续,可以考虑作为独立插件发布。
Merge 策略
推荐使用 Squash and Merge:
- 将 PR 的所有 commit 压缩为一个
- commit message 使用 PR 标题(因此 PR 标题必须符合规范)
- 保持 master 分支历史线性整洁
七、常见错误速查
| 错误 | 正确做法 |
|---|---|
| PR 里混了多个不相关的改动 | 拆成多个 PR |
| commit message 写 "fix bug" | 写清楚修了什么 bug:fix(ui): card state not reset on close |
| PR 描述为空 | 至少写清楚 What changed 和 How to test |
| 没有测试就提 PR | 新功能和 bug fix 都应该有对应测试 |
| 提 PR 前没有同步最新 master | git fetch origin && git rebase origin/master |
| 回应 review 意见时只改代码不回复 | 回复每条 comment,说明你做了什么或为什么不改 |