版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
开源项目贡献指南
Git·GitHub工作流·PR规范
从第一次提交到成为核心维护者的完整路径
10大章节·120+命令示例·60条协作规范
开源协作实战系列
目录
第一章开源贡献入门与心法
第二章Git基础与核心概念
第三章分支管理与协作工作流
第四章Fork、Clone与远程协作
第五章提交规范与CommitMessage
第六章PullRequest完整规范
第七章代码评审与协作沟通
第八章常见问题与故障排除
第九章从贡献者到维护者
第十章实战案例与速查表
开源项目贡献指南·Git/GitHub工作流/PR规范
第一章开源贡献入门与心法
1.1为什么要参与开源
参与开源项目,不只是"给别人的代码做贡献",更是一次系统性的能力提升。无论是修改文档里的一个错别
字,还是实现一个复杂特性,每一次提交都在塑造你的技术品牌、扩展你的协作能力、加深你对工程实践的理解。
参与开源能带来四个层面的价值。技术能力:你会接触到大型项目的代码结构、设计模式、测试体系,这些是
业务项目很难提供的。协作能力:开源项目的协作流程、代码评审、沟通方式,是团队协作的最佳训练场。职业发
展:持续的贡献记录是技术能力的公开证明,很多机会来自开源社区。个人成长:与来自全球的开发者协作,会打
开你的视野,提升你的表达和沟通能力。
1.2开源贡献的多种形式
很多人误以为贡献开源就是"写代码"。实际上,一个健康的开源项目需要多种形式的贡献,代码只是其中一部
分。
贡献类型具体形式适合人群入门难度
文档改进修正错别字、补充示例、翻译文档所有人低
问题反馈提交清晰的Bug报告、功能建议使用者低
代码修复修复小Bug、改进错误处理有编程基础中
新功能开发实现新特性、扩展API熟悉项目中高
测试补充补充单元测试、集成测试测试爱好者中
代码评审评审他人的PR,提出建议资深贡献者高
社区运营回答问题、组织活动、维护社区沟通能力强中
设计贡献Logo、UI、图标设计设计师中
1.3如何选择目标项目
选择目标项目是参与开源的第一步,选对项目能让你的贡献之路事半功倍。选择项目时应考虑四个因素。
因素一:你正在使用。最好的项目是你日常在用的,你对它有真实的理解和需求,提交的改进也更有价值。
因素二:活跃度。项目要有持续的提交、活跃的Issue讨论、及时的PR响应。如果项目几个月没有更新,说
明维护者可能已经不再投入。
因素三:新手友好度。好的项目会有明确的新手引导、标记为"goodfirstissue"的入门任务、友好的社区氛
围。
因素四:技术栈匹配。项目的技术栈要与你的技能匹配,或者是你想学习的方向。
如何判断项目是否活跃:查看最近一个月的提交记录、Issue的响应速度、PR的合并周期、贡献者的数量变
化。一个健康的项目,每周都有提交,Issue通常几天内有回复,PR通常一到两周内处理。
1.4贡献前的准备工作
#贡献前的准备清单
##1.了解项目
-[]阅读README(项目介绍、使用方式)
-[]阅读CONTRIBUTING(贡献指南)
-[]阅读CODE_OF_CONDUCT(行为准则)
-[]阅读LICENSE(开源协议)
-[]了解项目的技术栈和架构
##2.熟悉工具
-[]Git基本命令
-[]平台的基本操作(Fork、PR、Issue)
-[]项目的构建和测试流程
-[]项目的代码规范
##3.环境搭建
-[]Fork项目
-[]Clone到本地
-[]配置上游仓库
-[]安装依赖
-[]运行测试,确保环境正常
##4.选择任务
-[]查看标记为"goodfirstissue"的问题
-[]查看"helpwanted"的问题
-[]查看文档中的TODO
-[]提交你自己的改进建议
##5.沟通确认
-[]在Issue中留言,表示你想处理
-[]等待维护者确认
-[]讨论方案(如果是复杂改动)
1.5开源礼仪
开源社区有自己的一套礼仪,遵守这些礼仪能让你的贡献之路更顺畅。
先搜索,再提问。提问前先搜索Issue列表和文档,避免重复提问。
先讨论,再动手。复杂改动应该先在Issue中讨论方案,避免做完后被拒绝。
尊重维护者的时间。维护者通常是业余时间做开源,不要催促,要有耐心。
接受不同意见。你的方案可能被拒绝,理解并尊重维护者的决定。
遵循项目规范。代码风格、提交信息、PR格式都要符合项目要求。
感谢他人的帮助。无论是维护者还是其他贡献者,都要表达感谢。
保持耐心和礼貌。即使对方态度不好,也要保持专业和礼貌。
不只是索取。不要只提交需求,也要主动帮助他人。
开源新手最常见的三个错误:第一,不读CONTRIBUTING就直接提PR,结果不符合项目规范被关闭;第
二,不讨论就直接动手实现大功能,做完后发现方向不对;第三,PR描述写得太简单,维护者不知道你做了
什么、为什么这么做。
第二章Git基础与核心概念
2.1Git的四个工作区域
理解Git的四个工作区域,是掌握Git的基础。很多Git操作之所以让人困惑,就是因为没有搞清楚数据在哪个
区域。
区域说明对应命令
工作区(WorkingDirectory)你正在编辑的文件直接编辑文件
暂存区(StagingArea)准备提交的改动gitadd
本地仓库(LocalRepository)提交后的本地历史gitcommit
远程仓库(RemoteRepository)平台上的共享仓库gitpush
#四个区域的数据流向
工作区──gitadd──>暂存区──gitcommit──>本地仓库──gitpush──>远程仓库
↑↑↑
gitresetgitresetgitfetch
↓↓↓
工作区<──gitcheckout──暂存区<──gitreset──本地仓库<──gitpull──远程仓库
#查看各区域状态
gitstatus#查看工作区和暂存区状态
gitlog#查看本地仓库历史
gitremote-v#查看远程仓库
2.2配置与初始化
#全局配置(只需一次)
gitconfig--global"你的名字"
gitconfig--globaluser.email"你的邮箱"
gitconfig--globalcore.editor"vim"
gitconfig--globalinit.defaultBranchmain
gitconfig--globalpull.rebasefalse
#查看配置
gitconfig--list
#为单个项目配置(覆盖全局)
cd你的项目目录
gitconfig"项目专用名字"
gitconfiguser.email"项目专用邮箱"
#初始化仓库
gitinit
#克隆已有仓库
gitclone远程仓库地址
#查看当前配置
gitconfig--get
2.3基本操作
#查看状态
gitstatus#详细状态
gitstatus-s#简略状态
#查看改动
gitdiff#工作区与暂存区的差异
gitdiff--staged#暂存区与本地仓库的差异
gitdiffHEAD#工作区与本地仓库的差异
#添加到暂存区
gitadd文件名#添加单个文件
gitadd.#添加所有改动
gitadd-A#添加所有改动(含删除)
gitadd-p#交互式添加
#提交
gitcommit-m"提交信息"#提交暂存区的改动
gitcommit-am"提交信息"#添加并提交已跟踪文件的改动
gitcommit--amend#修改最近一次提交
#查看历史
gitlog#完整历史
gitlog--oneline#单行历史
gitlog--graph#图形化历史
gitlog-p#显示差异
gitlog--stat#显示文件统计
#撤销操作
gitrestore文件名#撤销工作区改动(危险,会丢失改动)
gitrestore--staged文件名#从暂存区移除(不丢失改动)
gitresetHEAD~1#撤销最近一次提交(保留改动)
gitreset--hardHEAD~1#撤销最近一次提交(丢弃改动,危险)
#查看文件历史
gitlog--follow文件名
gitblame文件名
2.4分支操作
#查看分支
gitbranch#本地分支
gitbranch-r#远程分支
gitbranch-a#所有分支
gitbranch-v#带最后提交的分支
#创建分支
gitbranch分支名#创建不切换
gitcheckout-b分支名#创建并切换
gitswitch-c分支名#创建并切换(新版命令)
#切换分支
gitcheckout分支名
gitswitch分支名
#重命名分支
gitbranch-m旧名新名
#删除分支
gitbranch-d分支名#已合并的分支
gitbranch-D分支名#未合并的分支(强制删除)
#合并分支
gitmerge分支名#合并到当前分支
gitmerge--no-ff分支名#保留分支历史
gitmerge--squash分支名#压缩为一次提交
#变基
gitrebase分支名#变基到目标分支
gitrebase-iHEAD~3#交互式变基(合并、修改、删除提交)
#暂存当前工作
gitstash#暂存工作区
gitstashlist#查看stash列表
gitstashpop#恢复最近的stash
gitstashapplystash@{0}#恢复指定的stash
gitstashdropstash@{0}#删除指定的stash
2.5远程操作
#查看远程仓库
gitremote-v
#添加远程仓库
gitremoteaddorigin远程仓库地址
gitremoteaddupstream上游仓库地址
#修改远程仓库
gitremoteset-urlorigin新的远程仓库地址
#删除远程仓库
gitremoteremoveorigin
#拉取远程改动
gitfetchorigin#拉取但不合并
gitfetch--all#拉取所有远程
gitpull#拉取并合并
gitpull--rebase#拉取并变基
#推送到远程
gitpush#推送到默认远程
gitpushorigin分支名#推送到指定远程
gitpush-uorigin分支名#推送并设置上游
gitpush--force#强制推送(危险)
gitpush--force-with-lease#安全强制推送
#删除远程分支
gitpushorigin--delete分支名
2.6常用命令速查表
场景命令
查看状态gitstatus
查看改动gitdiff
添加文件gitadd文件名
提交gitcommit-m"信息"
查看历史gitlog--oneline
创建分支gitswitch-c分支名
切换分支gitswitch分支名
合并分支gitmerge分支名
拉取远程gitpull
推送远程gitpush
撤销改动gitrestore文件名
暂存工作gitstash
查看远程gitremote-v
回退提交gitreset--hardHEAD~1
危险命令警示:gitreset--hard、gitpush--force、gitclean-fd会丢失未提交的改动或覆盖历
史。执行这些命令前,一定要确认没有重要的未保存内容。在团队协作的分支上,永远不要用--force,改用
--force-with-lease。
第三章分支管理与协作工作流
3.1主流的Git工作流
工作流核心思想适用项目
GitFlow多个长期分支(main、develop、feature、release、hotfix)版本发布周期长、需求稳定的项目
GitHubFlow只有main分支,所有改动通过PR合入持续部署的项目
GitLabFlowmain+环境分支(预发、生产)多环境部署的项目
TrunkBased所有开发者提交到主干,小步快速高质量CI/CD的团队
开源项目最常用的是GitHubFlow,因为它简单、灵活,适合频繁发布的节奏。核心原则只有两条:main分支始
终保持可发布状态;所有改动通过PR合入,禁止直接推送main。
3.2分支命名规范
#分支命名规范
##通用格式
<类型>/<简短描述>
##常见类型
-feature/新功能
-fix/Bug修复
-docs/文档更新
-refactor/重构
-test/测试相关
-chore/构建、配置等杂项
-perf/性能优化
##示例
feature/user-authentication
fix/login-timeout-error
docs/api-reference-update
refactor/extract-common-utils
test/add-unit-tests-for-parser
chore/upgrade-dependencies
perf/optimize-database-query
##命名原则
1.使用小写字母
2.使用短横线分隔单词
3.描述清晰,见名知意
4.不要过长(不超过50字符)
5.不要使用特殊字符
6.不要使用中文
##反例
myBranch#驼峰命名,不规范
fix#太模糊
feature/新的登录功能#包含中文
feature/this-is-a-very-long-branch-name-that-is-hard-to-read#太长
feature/user@login#fix#含特殊字符
3.3分支操作规范
#标准的分支操作流程
##1.从最新的main创建分支
gitswitchmain
gitpullupstreammain#更新本地main
gitswitch-cfeature/新功能名
##2.开发过程中保持分支更新
gitfetchupstream
gitrebaseupstream/main#变基到最新的main
##3.完成开发,推送到自己的Fork
gitpushoriginfeature/新功能名
##4.创建PullRequest
##5.根据评审意见修改
gitadd修改的文件
gitcommit-m"fix:根据评审修改"
gitpushoriginfeature/新功能名
##6.PR合并后清理分支
gitswitchmain
gitpullupstreammain
gitbranch-dfeature/新功能名
gitpushorigin--deletefeature/新功能名
3.4merge与rebase的选择
对比项mergerebase
历史记录保留分支结构线性、整洁
冲突处理一次性解决每个提交都可能冲突
提交哈希保留原提交重新生成提交
适用场景公共分支个人分支
安全性安全会改写历史
核心原则:个人的本地分支用rebase,公共分支用merge。在你自己的feature分支上,可以随意rebase来保
持整洁;但一旦分支被推送并被他人使用,就不要rebase了,因为这会影响他人。
#使用rebase保持分支整洁
#场景:feature分支落后于main很多
#方式一:rebase(推荐)
gitswitchfeature/my-feature
gitfetchupstream
gitrebaseupstream/main
#如果出现冲突,解决后继续
gitadd冲突的文件
gitrebase--continue
#如果想放弃rebase
gitrebase--abort
#方式二:merge(保留合并记录)
gitswitchfeature/my-feature
gitmergeupstream/main
#rebase后推送(因为改写了历史)
gitpush--force-with-leaseoriginfeature/my-feature
rebase的黄金法则:永远不要rebase已经推送到公共分支的提交。如果你rebase了别人也在用的分支,会导
致他们的历史与你不同步,产生大量冲突。个人分支、未合并的PR分支可以rebase,main、develop这类共享
分支绝对不能rebase。
3.5提交历史的整理
#交互式变基:整理提交历史
gitrebase-iHEAD~5#编辑最近5个提交
#编辑器中会显示:
pickabc1234feat:添加用户登录功能
pickdef5678fix:修复登录验证bug
pick9876abcdocs:更新API文档
pick5432defstyle:调整代码格式
pick1098fedfeat:添加用户注册功能
#可用的操作:
#pick保留该提交
#reword修改提交信息
#edit暂停,修改该提交
#squash合并到上一个提交
#fixup合并到上一个提交(丢弃提交信息)
#drop删除该提交
#整理为3个提交的示例:
pickabc1234feat:添加用户登录功能
fixupdef5678fix:修复登录验证bug
pick9876abcdocs:更新API文档
fixup5432defstyle:调整代码格式
squash1098fedfeat:添加用户注册功能
#保存后:
#提交1:feat:添加用户登录功能
#提交2:docs:更新API文档
#提交3:feat:添加用户注册功能
3.6冲突处理
#冲突的产生
#当两个分支修改了同一文件的同一位置,合并时就会冲突
#冲突文件的标记:
<<<<<<<HEAD
当前分支的内容
=======
要合并分支的内容
>>>>>>>feature/other-branch
#解决冲突的流程
1.打开冲突文件,找到冲突标记
2.决定保留哪部分(或都保留、修改为新的内容)
3.删除冲突标记
4.gitadd冲突文件
5.gitcommit或gitrebase--continue
#使用工具解决冲突
gitmergetool
#查看冲突文件
gitdiff--name-only--diff-filter=U
#放弃合并
gitmerge--abort
gitrebase--abort
#一个冲突示例
#main分支的内容
defgreet(name):
returnf"Hello,{name}"
#feature分支的内容
defgreet(name):
returnf"你好,{name}"
#解决冲突后(保留两种语言支持)
defgreet(name,lang="en"):
iflang=="zh":
returnf"你好,{name}"
returnf"Hello,{name}"
第四章Fork、Clone与远程协作
4.1Fork与Clone的区别
操作说明执行位置用途
Fork把别人的仓库复制一份到你自己的账号下Web界面没有写权限时的贡献方式
Clone把远程仓库下载到本地本地命令行开始本地开发
Branch从当前分支创建一个新分支本地或远程隔离开发,避免互相影响
Fork是开源协作的核心机制。当你没有目标仓库的直接写权限时,就可以Fork一份到自己的账号下,在这个副
本上进行修改,然后通过PR把改动提交回原仓库。
4.2标准协作流程
#完整的开源贡献流程
##1.在Web界面Fork目标仓库
#点击目标仓库页面上的"Fork"按钮
#会在你的账号下创建一个副本
##2.把Fork的仓库Clone到本地
gitclone你的Fork仓库地址
cd项目目录
##3.添加上游仓库(原仓库)
gitremoteaddupstream原仓库地址
gitremote-v
#输出:
#origin你的Fork地址(fetch)
#origin你的Fork地址(push)
#upstream原仓库地址(fetch)
#upstream原仓库地址(push)
##4.创建特性分支
gitswitch-cfeature/my-feature
##5.开发并提交
gitadd.
gitcommit-m"feat:添加新功能"
##6.保持分支最新(定期执行)
gitfetchupstream
gitrebaseupstream/main
##7.推送到你的Fork
gitpush-uoriginfeature/my-feature
##8.在Web界面创建PullRequest
#从你的Fork分支->原仓库的main
##9.根据评审修改
gitadd.
gitcommit-m"fix:根据评审意见修改"
gitpushoriginfeature/my-feature
##10.PR合并后清理
gitswitchmain
gitpullupstreammain
gitbranch-dfeature/my-feature
gitpushorigin--deletefeature/my-feature
4.3上游仓库的维护
#保持Fork与上游同步
##方式一:命令行同步(推荐)
#拉取上游的最新改动
gitfetchupstream
#切换到main
gitswitchmain
#合并上游的main
gitmergeupstream/main
#推送到你的Fork
gitpushoriginmain
##方式二:使用rebase(更整洁)
gitfetchupstream
gitrebaseupstream/main
gitpush--force-with-leaseoriginmain
##方式三:Web界面同步
#在你的Fork仓库页面,会有"Syncfork"按钮
#点击即可把上游的最新改动同步到你的Fork
##定期同步的好处
1.减少PR时的冲突
2.获得最新的功能和修复
3.保持分支与上游一致
4.4远程仓库管理
#远程仓库的常见操作
#查看所有远程
gitremote-v
#查看某个远程的详细信息
gitremoteshoworigin
gitremoteshowupstream
#重命名远程
gitremoterenameoriginold-origin
#修改远程地址
gitremoteset-urlorigin新的地址
#删除远程
gitremoteremoveupstream
#添加多个远程
gitremoteaddgithub仓库地址1
gitremoteaddgitee仓库地址2
#从指定远程拉取
gitfetchupstream
gitpullupstreammain
#推送到指定远程
gitpushoriginfeature/my-feature
gitpushgithubfeature/my-feature
#查看远程分支
gitbranch-r
gitbranch-r|grepupstream
#检出远程分支到本地
gitswitch-cfeature/local-branchorigin/feature/remote-branch
4.5多账号配置
#场景:同时使用公司账号和个人账号
#方式一:为每个仓库单独配置
cd公司项目
gitconfig"公司账号名"
gitconfiguser.email"公司邮箱"
cd开源项目
gitconfig"个人账号名"
gitconfiguser.email"个人邮箱"
#方式二:使用includeIf条件配置
#编辑全局配置文件~/.gitconfig
[user]
name=默认名字
email=默认邮箱
[includeIf"gitdir:~/work/"]
path=~/.gitconfig-work
[includeIf"gitdir:~/opensource/"]
path=~/.gitconfig-opensource
#~/.gitconfig-work内容
[user]
name=公司账号名
email=公司邮箱
#~/.gitconfig-opensource内容
[user]
name=个人账号名
email=个人邮箱
#方式三:使用SSH配置
#~/.ssh/config
Hostgithub-work
HostName平台地址
Usergit
IdentityFile~/.ssh/id_rsa_work
Hostgithub-personal
HostName平台地址
Usergit
IdentityFile~/.ssh/id_rsa_personal
4.6权限模型说明
角色权限典型职责
访客读、提Issue报告Bug、提建议
贡献者读、提Issue、提PR提交代码、文档改进
协作者读写代码、评审PR评审代码、合并PR
维护者全部权限,含仓库设置管理项目、发布版本
所有者最高权限删除仓库、转让所有权
作为外部贡献者,你的权限通常是"访客"或"贡献者"。要修改代码,必须Fork后提交PR。只有当项目维护者把
你加为协作者后,你才能直接推送分支到主仓库。
为什么要Fork而不是直接分支:在团队内部协作时,通常大家都有仓库的写权限,可以直接创建分支。但
在开源项目中,你没有主仓库的写权限,必须先Fork到自己的账号下,再从这个副本提交PR。这是权限隔离
的自然结果。
第五章提交规范与CommitMessage
5.1为什么要规范提交信息
提交信息是代码历史的注释,是未来自己和他人理解代码的线索。一份规范的提交信息能让审查者快速理解改
动、让维护者快速生成变更日志、让后来的贡献者快速追溯历史。相反,随意的提交信息会让历史变得难以阅
读,"update"、"fixbug"、"修改一下"这类信息毫无价值。
规范提交信息还能带来实际好处:可以自动生成CHANGELOG、可以基于提交类型触发不同的CI流程、可以按
类型过滤提交记录、可以在评审时快速定位改动意图。
5.2ConventionalCommits规范
ConventionalCommits是目前最流行的提交信息规范,被大量开源项目采用。它的格式如下:
#基本格式
():
#各部分说明:
#type:提交类型(必须)
#scope:影响范围(可选)
#subject:简短描述(必须)
#body:详细描述(可选)
#footer:关联信息(可选)
#完整示例
feat(auth):添加用户登录功能
-支持邮箱和手机号登录
-添加验证码校验
-添加登录失败限流
Closes#123
Reviewed-by:@reviewer
5.3提交类型对照表
类型说明示例
feat新功能feat:添加用户注册功能
fixBug修复fix:修复登录超时问题
docs文档更新docs:更新API使用说明
style代码格式(不影响逻辑)style:格式化代码
refactor重构(既非新功能也非Bug修复)refactor:提取公共工具函数
perf性能优化perf:优化数据库查询
test测试相关test:添加用户模块单元测试
build构建、依赖变更build:升级依赖版本
ciCI配置变更ci:添加自动化测试流程
chore杂项(不修改源码或测试)chore:更新.gitignore
revert回滚某个提交revert:回滚#123的改动
5.4提交信息的写作要点
#好的提交信息
feat(auth):添加JWTToken自动刷新
当Token剩余有效期小于5分钟时,
自动调用刷新接口获取新Token,
避免用户在操作过程中被登出。
-添加TokenExpiryChecker组件
-添加RefreshTokenService
-添加相关单元测试
Closes#456
#坏的提交信息
update#太模糊
fix#没说什么
修改一下#中文且模糊
修复了那个bug#什么bug
ADDFEATURE#大写,不清晰
feat:a#描述太短
feat:添加了JWTToken自动刷新功能但是这个功能还包含了很多其他改动比如...#太长
#写作要点
##1.主题行不超过50字符
feat(auth):添加用户登录功能#✅
feat(auth):添加用户登录功能并支持多种登录方式包括邮箱手机号和第三方账号#❌
##2.主题行使用祈使句
feat:添加登录功能#✅
feat:添加了登录功能#❌用过去时
feat:正在添加登录功能#❌用进行时
##3.主题行首字母小写(英文)
feat:adduserlogin#✅
feat:Adduserlogin#❌
##4.主题行不加句号
feat:添加登录功能#✅
feat:添加登录功能。#❌
##5.正文与主题之间空一行
feat:添加登录功能
#空行
详细说明...
##6.正文说明"为什么"而非"是什么"
#✅说明原因
fix:修复并发下单导致超卖的问题
原有的库存扣减逻辑没有加锁,
在高并发场景下会出现超卖。
#❌只说明改了什么(代码已经说明了)
fix:在扣减库存前加锁
##7.关联Issue
Closes#123
Fixes#456
Refs#789
5.5提交粒度
提交粒度是很多人忽视的问题。一个好的提交应该是一个逻辑完整的原子改动:只做一件事,且这件事是完整
的。粒度太粗会让审查者难以理解,粒度太细会让历史变得零碎。
粒度表现评价
太粗一个提交改了50个文件,实现了5个功能难以审查,难以回滚
合适一个提交实现一个完整功能或修复一个Bug推荐
太细每个文件一个提交,每个方法一个提交历史零碎,难以理解
#提交粒度的示例
#❌太粗:一个提交包含多个不相关的改动
gitcommit-m"feat:添加用户功能并修复登录Bug并更新文档"
#✅合适:拆分为3个提交
gitcommit-m"feat(user):添加用户注册功能"
gitcommit-m"fix(auth):修复登录超时问题"
gitcommit-m"docs:更新用户模块文档"
#拆分的技巧:使用gitadd-p
gitadd-p
#交互式选择要添加的代码块
#y-添加
#n-不添加
#s-拆分为更小的块
#e-手动编辑
#已提交但需要拆分:使用rebase
gitrebase-iHEAD~3
#把要拆分的提交标记为edit
#然后用gitresetHEAD~回退
#再分多次提交
5.6提交信息工具
#Commitizen:规范化提交信息
#安装
npminstall-gcommitizencz-conventional-changelog
echo'{"path":"cz-conventional-changelog"}'>~/.czrc
#使用
gitcz
#交互式选择类型、填写描述、关联Issue
#Commitlint:检查提交信息规范
#安装
npminstall--save-dev@commitlint/cli@commitlint/config-conventional
#配置文件commitlint.config.js
module.exports={
extends:['@commitlint/config-conventional']
};
#配合Husky使用(提交时自动检查)
npxhuskyadd.husky/commit-msg'npx--no-installcommitlint--edit"$1"'
#Commitizen+ConventionalChangelog自动生成CHANGELOG
npxconventional-changelog-pangular-iCHANGELOG.md-s
提交信息的价值:好的提交信息是团队协作的润滑剂。当你在三个月后回看自己的提交,能快速想起当时的
思路;当审查者看你的PR,能快速理解改动意图;当维护者发布版本,能自动生成CHANGELOG。花30秒写
好提交信息,能节省未来无数人的时间。
第六章PullRequest完整规范
6.1PR的本质与价值
PullRequest(PR)不只是一个"请求合并"的按钮,而是一次完整的代码变更提案。一个好的PR应该让审查者
能够:理解改动背景、看懂改动内容、验证改动正确性、评估改动影响。这三个目标决定了PR的结构和内容。
一份高质量PR的价值:加速评审(审查者能快速上手)、降低沟通成本(减少来回追问)、便于追溯(未
来回看能理解当时的决策)、建立信任(维护者更愿意合并你的改动)。
6.2PR的生命周期
#PR的完整生命周期
1.准备阶段
├──Fork仓库
├──创建特性分支
├──开发并提交
├──保持分支与上游同步
└──本地测试通过
2.创建阶段
├──推送到Fork
├──在Web界面创建PR
├──填写标题和描述
├──关联Issue
└──添加标签和审查者
3.评审阶段
├──CI自动检查
├──维护者/审查者评审
├──提出修改意见
├──作者根据反馈修改
└──反复迭代直到通过
4.合并阶段
├──所有检查通过
├──所有评审意见解决
├──维护者合并(Squash/Merge/Rebase)
└──清理分支
5.后续
├──关注合并后的效果
├──如果出现问题及时修复
└──感谢参与评审的人
6.3PR标题的规范
#PR标题规范(与提交信息类似)
##推荐格式
():
##示例
feat(auth):添加JWTToken自动刷新
fix(api):修复分页查询的边界错误
docs(readme):更新安装说明
refactor(parser):重构解析器逻辑
##好的PR标题
feat:添加用户注册功能
fix:修复登录超时问题
docs:更新API使用说明
perf:优化列表查询性能
##不好的PR标题
UpdateREADME#太模糊
fixbug#什么bug
修改#完全没说清楚
添加功能#什么功能
[WIP]开发中#不应用在PR上
feat:添加了一个新功能,包含注册、登录、找回密码、修改资料等多个子功能#太长
6.4PR描述的完整模板
#PR描述模板(完整版)
##变更类型
-[]新功能
-[]Bug修复
-[]重构
-[]文档
-[]性能优化
-[]测试
-[]构建/CI
-[]其他
##关联Issue
Closes#123
Fixes#456
Refs#789
##变更背景
说明为什么要做这个改动。如果是修复Bug,说明Bug的表现、
复现步骤、影响范围;如果是新功能,说明业务场景、用户需求。
##变更内容
详细说明做了什么改动。建议按文件或模块列出。
-在src/auth/login.js中:
-添加了Token过期检查
-添加了自动刷新逻辑
-在tests/auth/login.test.js中:
-添加了10个测试用例
-更新了docs/auth.md文档
##实现思路
说明为什么这样实现。如果考虑了多种方案,说明为什么选择当前方案。
这能帮助审查者理解你的思考过程,也能避免误解。
##测试方式
说明如何验证这个改动。
-[]单元测试:`npmtest`
-[]集成测试:`npmruntest:integration`
-[]手动测试:本地启动后,执行XXX操作
-[]兼容性测试:在Node.js18/20/22上测试通过
##影响范围
说明这个改动可能影响的功能。
-影响接口:登录接口
-影响用户:所有用户
-兼容性:向后兼容
-数据库:无需迁移
##截图/录屏
如果是UI改动,提供前后对比截图。
(此处粘贴截图)
##检查清单
-[]代码符合项目编码规范
-[]添加了必要的测试
-[]所有测试通过
-[]更新了相关文档
-[]更新了CHANGELOG
-[]没有引入新的警告
-[]已自我审查代码
-[]提交信息符合规范
##其他信息
任何需要审查者注意的内容。比如:
-有争议的设计决策
-后续计划
-已知限制
6.5PR描述示例
#示例一:Bug修复PR
##变更类型
-[x]Bug修复
##关联Issue
Fixes#1234
##变更背景
用户反馈在订单列表页,当订单数量超过1000时,
页面会崩溃。经过排查,是分页查询的offset
超过数据库限制导致的。
##变更内容
-在src/services/order.js中:
-添加了offset上限校验
-当offset超过上限时,自动切换到游标分页
-在tests/services/order.test.js中:
-添加了边界测试用例
##实现思路
有两种方案:
1.限制用户最多翻到第50页
2.切换到游标分页
选择方案2,因为用户体验更好,不会限制功能。
游标分页使用订单ID作为游标,避免深度分页的性能问题。
##测试方式
-[x]单元测试通过
-[x]手动测试:模拟10000条订单数据,翻页正常
-[x]性能测试:P99延迟从800ms降到50ms
##影响范围
-影响接口:GET/api/orders
-兼容性:向后兼容,不影响现有调用方
##检查清单
-[x]代码符合规范
-[x]添加了测试
-[x]所有测试通过
---
#示例二:新功能PR
##变更类型
-[x]新功能
##关联Issue
Closes#5678
##变更背景
用户反馈希望能通过手机号登录,而不仅仅是邮箱。
这是社区投票排名第一的功能请求。
##变更内容
-添加手机号登录接口
-添加短信验证码服务
-添加相关的错误处理和限流
-更新API文档
##实现思路
设计时考虑了三种方案:
1.手机号+密码登录:需要用户先设置密码,
增加使用门槛。
2.手机号+验证码登录:更简单,但需要接入短信服务。
3.手机号+一键登录:用户体验最好,但需要运营商合作。
最终选择方案2,因为它在体验和成本之间取得了平衡。
##测试方式
-[x]单元测试:20个测试用例全部通过
-[x]集成测试:完整登录流程通过
-[x]手动测试:真机测试验证
-[x]压测:1000QPS下稳定
##影响范围
-新增接口:POST/api/auth/login-by-phone
-新增依赖:短信服务SDK
-需要配置:短信服务密钥
##检查清单
-[x]代码符合规范
-[x]添加了测试
-[x]更新了文档
-[x]更新了CHANGELOG
6.6PR的大小控制
PR大小代码行数评审时间推荐度
极小<50行5-10分钟推荐
小50-200行15-30分钟推荐
中200-400行30-60分钟可接受
大400-800行1-2小时需要拆分
超大>800行>2小时强烈建议拆分
研究表明,单次评审超过400行代码时,评审质量显著下降。超过800行时,审查者往往只能走马观花。因
此,一个PR应该尽可能控制在400行以内。如果改动确实很大,拆分为多个PR:每个PR完成一个独立的子任务,
依次提交。
6.7PR的常见问题
#PR常见问题与解决
##问题一:PR太大
解决:拆分为多个小PR
-第一步:只添加测试
-第二步:添加核心实现
-第三步:添加文档
-第四步:重构优化
##问题二:PR中混合了不相关的改动
解决:保持PR聚焦
-一个PR只做一件事
-不相关的改动单独提交
-格式化和重构分开
##问题三:CI检查失败
解决:本地先跑一遍CI
-提交前运行测试
-检查代码风格
-确保构建通过
##问题四:与main冲突
解决:定期同步
-每天rebase一次
-或者mergemain
-解决冲突后重新推送
##问题五:PR被长期搁置
解决:主动跟进
-一周后礼貌地@维护者
-说明为什么重要
-询问需要什么才能合并
##问题六:PR被拒绝
解决:理解原因
-询问维护者的理由
-如果是方向问题,调整方案
-如果是时机问题,换个时间再试
-保持礼貌,不要情绪化
PR的黄金原则:让审查者省心。这意味着:PR要小、描述要清晰、改动要聚焦、测试要完备、CI要通过。
当审查者打开你的PR,能一眼看懂你在做什么、为什么这么做、如何验证,你的PR就会很快被合并。
第七章代码评审与协作沟通
7.1代码评审的价值
代码评审不是"挑刺",而是团队协作的核心环节。一次好的代码评审,能在代码合入前发现bug、提升代码质
量、促进知识共享、统一团队规范。对于开源项目,代码评审还是新贡献者学习项目规范的重要途径。
代码评审有三个层次的价值。质量保障:发现bug、安全问题、性能隐患。知识传递:审查者了解代码,作者
学习最佳实践。标准统一:通过评审形成团队共识,逐步沉淀为规范。
7.2审查者的基本素养
素养表现反例
尊重作者就事论事,不针对个人"你怎么总是犯这种错误"
聚焦代码只讨论代码,不讨论人"你是不是没经验"
建设性给出可执行的建议"这里不好,改一下"
有耐心解释清楚原因"不用问,按我说的改"
接受不同风格差异可以接受"必须按我的风格写"
及时响应在约定时间内完成评审PR放置多天不响应
给予肯定不仅指出问题,也肯定优点只挑毛病,不给鼓励
7.3评审意见的表达方式
#评审意见的表达模板
##格式一:问题+建议
"第45行直接使用字符串拼接SQL,存在SQL注入风险。
建议使用参数化查询。"
##格式二:背景+问题+影响+建议
"根据项目规范(参考CONTRIBUTING.md),
这里直接使用字符串拼接SQL,可能导致SQL注入,
攻击者可以通过构造恶意输入窃取数据。
建议使用PreparedStatement参数化查询。"
##格式三:提问式
"这里使用字符串拼接SQL,是有什么特殊考虑吗?
我担心可能存在SQL注入风险,是否考虑过
使用参数化查询?"
##反馈的分类
###Blocker(必须修改)
"这里存在SQL注入风险,必须使用参数化查询。"
###Major(强烈建议)
"这个查询没有使用索引,性能可能有问题。
建议添加(user_id,created_at)联合索引。"
###Minor(建议修改)
"变量名data不够具体,建议改为orderList。"
###Nit(细微建议)
"这里多了一个空行。"
###Question(提问)
"这段逻辑为什么要先删除再添加,而不是直接更新?"
###Praise(肯定)
"这个缓存策略设计得很好,值得学习。"
##评审意见的语气
###好的表达
-"建议使用XXX,因为YYY"
-"这里是否可以改为XXX?"
-"我注意到XXX,可能有YYY风险"
-"这个设计很巧妙,能说说是怎么想到的吗?"
###差的表达
-"这是错的"
-"应该这样写"
-"不对"
-"重写"
-"这段代码质量太差"
7.4作者的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 大学物业精细化服务方案
- 高中地理教资面试教资面试逐字稿题库
- 统编版语文七年级上册第7课《荷叶·母亲》同步练习
- 2026年信息安全管理体系规划框架
- 《教育科研方法》课件
- 第2课 古代两河流域 课件 统编版九年级历史上册
- 壤塘县消防安全问题分析
- 癫痫护理查房(含病例分析)
- 2027年高二信息学竞赛教学设计:高精度算法专题研讨
- 码头登船梯防滑防腐检修指南(2025版)
- 《机床数控技术 第2版》课件全套 杜国臣 第1-6章 绪论、数控加工工艺基础 -数控机床机械结构
- (高清版)DZT 0280-2015 可控源音频大地电磁法技术规程
- 小学生必读图书目录
- 同济大学《房屋建筑学》(第5版)配套题库
- 太平洋雇主责任保险(2016版)条款
- 2022年新人教版四年级数学上册电子课本
- 2019新版药品管理法培训PPT
- 高分子的聚集态结构
- GB/T 20634.1-2006电气用非浸渍致密层压木第1部分:定义、命名和一般要求
- 常见症状发热
- 劳务费工作量说明表
评论
0/150
提交评论