主要涉及三个方面:
- Git 分支流程与提交历史
- GitHub 协作流程
对 Git 不熟悉的开发者可以先阅读官方教材《Pro Git》。 其中 1、2、3、5、6、7 几章值得认真阅读,完全掌握其中内容可能需要 2~4 周。
Git 是一种分布式的版本控制系统,每个人都拥有自己的仓库的 100% 的权限,简而言之,每个人都有在自己电脑上修改代码的权利,并可以选择是否将代码贡献给上游,但一旦选择贡献,那么上游的人有拒绝的权利。这也是为什么 GitHub 将贡献代码称之为 PR (即 Pull Request) 的原因,也就是说,这是一个「Request」,上游有拒绝的权利。Git 正是这样营造了一个平等的协同环境。
为了避免工作成果被上游拒绝,就必须遵循上游的相关规范。一般仓库都有一个「贡献指南」以说明对开发者的要求。为了避免贡献指南太过冗长,一般在社区通行的要求就不会赘述。如果在 PR 时遇到问题,各方可以在 PR 中进行沟通,反复修改至满意为止。
下面着重介绍有关分支、提交应当遵循的规范。
分支规范主要约束两方面,一个是分支命名,一个是是分支生命周期管理。
- 1.1.1.1. 分支名称由两部分组成:分支类型和分支含义,两部分之间以斜线(
/
)分隔。 - 1.1.1.2. 分支类型有:
- feature:新功能(feature)
- fix:修补 bug
- hotfix:紧急修复 BUG
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)
- test:增加测试
- chore:构建过程或辅助工具的变动
- release:已发布的版本的长期维护分支
- wip:未完成的工作(Work In Process)
- 1.1.1.3. 分支名称用英文书写,如果内容涉及多个单词,单词与单词之间以连字符(
-
)分隔。
完整的分支名称示例如下:
feature/issue-12
fix/issue-13
hotfix/issue-14
docs/issue-15
style/issue-16
release/v2.1.4
wip/issue-17
Git 仓库创建时生成的分支默认为 main 分支,该分支一般作为收集工作成果的目的分支,并长期存在。 除了 main 分支之外,Git 仓库中也可以创建多个其它分支。 和 Subversion 不同,Git 创建分支的成本非常低,因此鼓励多建分支。 有关分支的创建、消亡以及依存关系,不同的习惯将产生不同的工作流。 有三种常见的工作流,GitHub flow、GitLab flow,和 Git flow。
其中对于有组织管理的项目,广泛流传的最佳实践是 Git flow,由 Vincent Driessen 发表在 这里。 其主要内容都在这张图上。
Rancher 的官方仓库基本遵循了 Git flow,除了将 main 看作是 develop 之外(main 分饰两角)。
从这张图中可以看到,Git flow 主要包含以下内容:
- 1.1.2.1. 只有 main 一个长期分支,其余全是临时分支。
- 1.1.2.2. main 分支不可直接修改(可以通过 GitHub 设置保护)。
- 1.1.2.3. 所有临时分支必须基于 main 创建,且最终回到 main(贡献成功)或放弃并删除(贡献失败)。
- 1.1.2.4. 所有临时分支合并回 main 时,必须经过 PR。
Git Commit message 是指 git commit
命令运行时提供的提交日志。通过提交日志,开发者可以了解项目开发历史,定位历史变更,提高项目变更历史的可读性。
- 1.2.1. 好的 Commit message 应当说明本次提交的性质、影响范围、一句话摘要,及详细内容。
- 1.2.2. 推荐的 Commit message 格式如下(注意空格和空行):
<类型>(<范围>): <标题>
// 空一行
<正文>
// 空一行
<补充说明>
- 1.2.3. 类型和标题不可省略,范围、正文及补充说明可以省略。
- 1.2.4. 类型可以参考 1.1.1.2 节描述的内容。
- 1.2.5. 范围视项目不同而不同,一般可以是模块名称或者业务名称。
- 1.2.6. 标题要言简意赅,以动词开头,末尾不要加任何标点符号。长度不可超过 50 个字符或 30 个汉字。
- 1.2.7. 正文建议用 markdown 语法。
- 1.2.8. 补充说明一般可以省略,但有两种情况必须提供:
- 1.2.8.1. 不兼容的更新,需要详细说明并给出老用户迁移方法。
- 1.2.8.2. 关闭了某个 issue,可以用「Close: #23, #24」这样的格式来标注,可以一次关闭多个 issue。
- 1.3.1. Git TAG 是只读的,不允许变更。
- 1.3.2. 有集中式托管仓库的项目,Git TAG 应当在中央服务器上生成。
- 1.3.3. 如果 TAG 发现有问题,不应当撤销重新生成,而应当生成新 TAG。
- 1.3.4. TAG 名称以语义化版本号格式命名,以字母
v
开头,例如v1.3.2
。 - 1.3.5. 原则上,TAG 只应当打在
release/*
分支上。如有必要也可在其它分支,此时格式不应当与 1.3.4. 条规定的格式雷同。
GitHub 为 Git 项目提供了集中式的托管中心。除了基本的 Git 仓库服务功能外,GitHub 还提供了诸如 issue、code review、CI 及看板功能。
为了更好地发挥 GitHub 的作用,我们可以:
- 2.1. 尽量将项目缺陷登记到项目 issue 里。
- 2.2. 对仓库的变更应当遵循第 1 章和第 2 章所约定的规范,包括代码风格、Git commit message、Git 分支名称、及 Git 分支关系。
- 2.3. 应当及时地更新本地 main 分支,rebase 本地临时分支,以确保 push 到服务器的分支基于 main 最新节点派生。
- 2.4. push 到服务器上的分支不能包含任何本地工作环境或线上生产环境所特有的信息,包括文件路径、账号信息、网络信息。
- 2.5. push 到服务器上的分支不能包含任何其他项目参与者不需要了解的本地修改过程,比如不必要的反复修改,以及未完成的工作内容,或不属于本分支目的范围内的修改内容。
- 2.6. push 到服务器上的分支所包含的 commit 应当是「独立的最小变更集」。「独立」是指每次提交都是完整地向前迈进了一小步(至少是可编译的),「最小」是指不可拆分为更小的单位。
- 2.7. main 分支不可直接修改。
- 2.8. 原则上,所有临时分支的变更只有经过 PR 才可以进入 main。PR 过程应当至少有两人参与。
- 2.9. PR 进行时,可以根据 reviewer 的意见追加修改,此时不必放弃 PR 重新创建。应当在本地修改完成后,继续
git push
。如有必要,还可以 rebase 后,通过git push -f
强制推送。
- Pro Git: https://git-scm.com/book/zh/v2
- Git flow: https://nvie.com/posts/a-successful-git-branching-model/
- Git flow 一图览毕: http://nvie.com/img/[email protected]
- 阮一峰, Commit message 和 Change log 编写指南: http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html
- 语义化版本号规范: https://semver.org/lang/zh-CN/