如何提交 PR?
解读
在国内 Rust 岗位面试中,面试官问“如何提交 PR”并不是想听你背诵 Git 命令,而是考察三条主线:
- 工程化流程是否规范——有没有遵循社区或公司内部的 Git 工作流;
- Rust 项目特有的质量门槛——是否理解 Cargo.lock 变更规则、CI 中的 clippy --deny warnings、rustfmt 强制格式化、测试覆盖率与 benchmark 回归;
- 协作与沟通意识——能否在 Issue 里先对齐需求、拆分最小可 Review 单元、回应 Review 时做到“一次 push 解决一批评论”。
回答时要让面试官感受到:你不仅能写安全高效的 Rust 代码,还能让团队低成本地信任你的每一次合并。
知识点
- Fork + Feature Branch 工作流:master/main 只放稳定代码,feature 分支名格式
issue-123-feature-name。 - Commit 规范:国内大厂普遍参考 Angular 规范,Rust 社区额外要求
cargo fmt --check零警告、cargo clippy --all-targets --all-features -- -D warnings零错误。 - Lock 文件策略:库(library)项目不提交 Cargo.lock,二进制项目必须提交;升级依赖须单独 commit 并说明原因。
- 测试矩阵:CI 至少覆盖
stable/beta/nightly三通道与x86_64-unknown-linux-gnu、aarch64-unknown-linux-gnu、x86_64-pc-windows-msvc三大目标;嵌入式岗位需加no_std构建。 - Review 礼仪:Rust 社区流行“Review 是礼物”,回复时必须
@指人,强制 push 后使用git rebase -i保持历史线性,禁止 merge commit。 - 安全与性能回归:使用
cargo-audit检查 RUSTSEC,使用cargo bench上传结果到 GitHub 的gh-pages分支,防止性能回退 >5 %。 - 签署 DCO/CLA:国内开源基金会(如开放原子)要求
git commit -s签署 DCO;外企或 Apache 项目需签 CLA,面试时提到“我已签署贵司 CLA”是加分项。
答案
我按“七步提交法”操作,确保一次通过 Review:
- 认领任务:在官方仓库 Issue 区评论“/assign”或“我想认领”,防止重复劳动。
- 环境对齐:fork 后把 upstream 加为远程,
git remote add upstream git@github.com:xxx/xxx.git,并保证本地rustc --version与 CI 的stable通道一致。 - 创建分支:
git checkout -b issue-123-fix-data-race,分支名直接关联 Issue,方便机器人自动关联。 - 开发自检:
- 写代码前先写单元测试 + 文档测试,保证
cargo test --all-features通过; - 提交前跑
cargo fmt && cargo clippy --fix,所有 fix 必须在本机解决,不把格式化机器人当保姆; - 若改公共接口,跑
cargo semver-checks确保语义化版本无破坏。
- 写代码前先写单元测试 + 文档测试,保证
- Commit 信息:首行 50 字内英文,格式
fix: remove data race in channel::send,正文用中文详细说明背景,结尾加Closes #123与Signed-off-by: 张三 <zhangsan@example.com>。 - Push 与 CI:
git push origin issue-123-fix-data-race后,在 PR 模板里勾选“我已阅读贡献者公约”“已跑通本地测试”,并贴上 CI 通过的截图(国内网络常掉线,提前准备)。 - 回应 Review:收到 Review 后 24 小时内回复,每条评论必须有对应 commit 或解释,使用
git rebase -i整理历史,最后git push --force-with-lease保持一条线性记录;Review 通过后由 Maintainerbors r+或 GitHub Merge Queue 自动合并,禁止自点 Merge 按钮。
拓展思考
- 大型 Rust 单仓(monorepo)如何提速 CI?
可引入cargo-nextest并行测试、sccache分布式缓存、以及cargo-hakari统一 workspace 特征,把全量 CI 从 40 min 压到 8 min,面试时给出数据会让面试官眼前一亮。 - 遇到 breaking change 但主版本号不能升怎么办?
用#[deprecated(since = "0.5.0", note = "use new_api instead")]标记旧 API,并加default-features = false的兼容性层,实现“零感知”迁移,体现你对语义化版本与用户生态的敬畏。 - 国内代码托管平台(Gitee、Coding)PR 流程与 GitHub 差异?
Gitee 无bors,需用 企业级分支保护规则(要求两人 Review + CI 通过 + 手动合并),面试国企或军工背景公司时,主动提到“我已配置 Gitee 保护分支模板”可快速拉近距离。