likes
comments
collection
share

如何向 Git 官方社区提交代码(一)

作者站长头像
站长
· 阅读数 1

前言

作为目前最流行的开源分布式版本控制系统,Git 的诞生超过17年,但目前仍然具有非常活跃的开发者社区,远超一般开源软件的生命周期,其代码贡献者也已经超过 1.5K,并且仍源源不断有新增贡献者,这使得 Git 能够持续不断地有各种更新、功能优化等等。

但是要想参与到这个大型的国际化的开源社区中来并成为源码贡献者,对于国内很多开发者来说并不是那么容易。

在 Gitee 架构团队中,我有机会深入探究 Git 的底层原理,以及 Git 的一些应用,这个过程中我也成为了 Git 社区的贡献者。截至目前,我向 Git 社区提交了 4 次代码。 现在,作为贡献者中的一员,我很乐意分享这个过程,以便帮助更多人有机会参与到像 Git 这样的大型开源社区中来。

这个系列将从 Git 社区贡献者的角度,向广大开发者分享我如何向 Git 官方社区提交代码,以及从提交代码到最终合并代码的整个过程。

起因

如果你在使用 Git 时发现了 bug,或者觉得某些命令没有你想要的功能,或者你发现它的帮助文档描述不够清晰让你感到迷惑,你完全可以自己修改 Git 源码,从而实现自己的预期功能。

获取源码

首先从 Git 在 Github 镜像仓 上 fork 出一个自己的仓库,然后克隆到本地:

$ git clone https://github.com/myfork/git mygit
$ cd mygit
# 添加上游远程仓库,便于更新最新代码
$ git remote add upstream https://github.com/git/git

编译源码

确保在未作任何修改之前,代码不缺少任何编译依赖,能够正常编译。

# 切出一个自己的主题分支
$ git checkout -b myown-topic origin/master
$ make DEVELOPER=1

topic 是个人主题分支,所谓主题就是自己要修改什么那就是什么主题。

编写代码

其实在成熟的项目中编写新代码的过程就是一个模仿的过程,先观察别人是怎么写的,再模仿写即可。比如,观察别人是如何定义变量,在哪里定义,如何处理缩进,如何定义函数等等,按照同样的风格进行模仿大致是不会出错的。 如果想看详细的编码规范,可参考 Git 代码编写规范

测试代码

Git 测试代码绝大部分是用 shell脚本写的,因为 Git 原本就是一个Linux下的命令行工具,对它的测试就是由一系列命令组成的,所以就很自然地使用 shell 脚本写测试用例。 它有自己独特的测试框架,这个在前期我们不用深究。那如何写测试代码呢,答案也是模仿。 具体测试代码都在 t/ 目录下,请阅读 t/README 文档,参考测试编写规范,然后编写测试用例。

当然,如果有需要,我可以再写一篇详细介绍 Git 测试框架以及如何写 Git 测试代码的文章。

PS. 向开源软件贡献代码不一定非得是修改核心代码,或者说非得搞一个什么特性,或者解决什么 bug, 只完善文档,完善测试代码也是一种方式贡献,而且这对于入门者好处多多:更容易成功,形成激励闭环,能够熟悉一整套流程,熟悉这个开源社区的氛围,规范等等。

例如,对照 t/README 中推荐的测试风格 Recommended style章节,可以在测试代码中找到一些不符合推荐风格的测试代码,从而向社区提交PR。这个任务就留给有心人啦。

运行单项测试:

$ make DEVELOPER=1
$ cd t/ && prove t9999-psuh-tutorial.sh

或者运行全部测试,以确保自己的修改没有影响别的代码运行:

$ cd t/
$ prove -j$(nproc) --shuffle t[0-9]*.sh

文档更新

如果修改是新增某个特性,或者增加某个选项配置等,都需要补充文档,配置说明,甚至是原理解析等等。

Linux环境中需要安装 asciidoc 工具,来支持文档

$ sudo apt-get install asciidoc
$ make all doc
$ make check-docs

对待文档需要跟对待代码一样,因为它们同样重要。 和编写代码一样,需要遵循已有文档的风格,详细风格指导文档请参考可参考 Git 代码编写规范中的 Writing Documentation 章节。

编写 commit

编写 commit 信息也是很重要的一步,这个后续系列文章我会专门说明这一点。

创建 commit 的原则,首先是对逻辑上不同的更改进行不同的提交(make separate commits for logically separate changes),也就是保持每个commit尽量独立且是最小更改。

每条 commit 需要带上签名,使用 git commit -s-s/--signoff 选项会在 commit 尾部加上 Signed-off-by:签名信息。

编写commit message 需要遵循一定规范,如下图: 如何向 Git 官方社区提交代码(一)

对于commit message, 官方主要维护者说:A canonical form of our log message starts by explaining the need, and then presents the solution at the end.(一个标准的格式的 commit message 应该在开头描述需求,在结尾展示解决方案。)

commit head 部分不超过 50 个字符

commit body 部分不超过 76 个字符

向社区提交代码

首先有以下几点需要注意:

  • Git 仓库主要有 5 个分支,master, maint, seen, next, todo。其中:

seen 是观察分支,向官方提交一般补丁,初步被接受后还需先进入观察期,即合并到seen 分支,此时还要继续接受别人的代码检视,可能会继续修改。

next 是预备分支,当 seen 上准备好了后,进入 next 分支,接受更多更广泛的测试,保证新补丁不会引发其它 issue。

master 是稳定分支, 在 next 分支上的补丁通过各种测试后,就可以进入稳定分支。

maint 是维护分支,bugfix 一般在这个分支上进行(也可以在 master 分支上进行)

  • 向社区发送邮件至少需要以下邮件地址:
  1. 主送官方邮件列表(必须): git@vger.kernel.org
  2. 抄送代码相关人。比如你的补丁修改了某个文件的某行代码,通过 git-blame 知道这行代码之前的修改者,那么最好也要抄送给这个人,因为他应该比你更熟悉这行代码。
  3. 抄送现在主要维护者: gitster@pobox.com
  • Git 社区交流都是用纯文本邮件方式,邮件回复有很多种方式,常见的有 top-posting, bottom-posting, interleaved-style(也叫inline-style)。邮件回复方式详情见 Posting_style Wiki
  • Git 官方社区推荐用 inline-style 回复邮件。

向官方提交代码的方式主要有两种:

一. 通过 Git 命令行:

  1. git format-patch 制作补丁包;
  2. git send-email 发送邮件到官方社区。

二. 通过 GitGitGadget

  1. 使用Github的PR工作流,向 GitGitGadget 的 Github 仓库 提交 PR;
  2. 找人邀请自己,让别人在 PR 评论区发送 /allow(仅针对第一次提交PR的用户);
  3. Github CI 通过后,发送 /submit 触发脚本,自动发送格式化的邮件到官方社区。

通过命令发送邮件向社区提交代码的方式遵循的是比较古老的 mailing list(邮件列表)工作流程,对于现在习惯了直接在网页上提交 PR/MR 的用户来说,邮件列表的方式比较复杂,不建议使用这种方式。但是如果想了解的话,可以参考如下链接:Submit Your Patch

GitGitGadget 相当于一套自动化程序,实现了 Github PR 工作流,使所有人能够直接在 Github 上通过提交 PR 的方式向 Git 官方提交代码,这极大的简化了原来的 mailing list工作流。所有这里推荐使用这种方式进行提交代码。

如何在 Github 上提交 PR 大部分人应该都会,所有这里就不展开讲了。对于第一次向 Git 仓库提交代码的情况,这里简单说明一下:

当在本地仓库按照前面的方式编写好 commit 后,push 到自己 fork 的仓库后,回到 gitgitgadget/git 仓库,可以看到:

如何向 Git 官方社区提交代码(一) 只需要点击绿色按钮,就可以创建 PR 了。

GitGitGadget 能够检测到用户是第一次提交 PR ,所以 gitgitgadget bot 会自动在 PR 下面发送评论,提示用户该如何操作。这里最重要的一点就是用户(你)需要找一个已经向 Git 成功提交过 PR 的人在你的 PR 评论区发送 /allow 指令,这样你才被真正允许提交 PR。

如果一切顺利,这时候你只需要在 PR 评论区发送 /submit 指令,GitGitGadget 程序会自动将你的 PR 转化为 Git 社区能够接受的格式,并发送到 Git 邮件列表 中。

提交成功!

/submit 指令发送成功后,第一次向 Git 社区提交代码就成功啦! 但是,这只是成功的第一步,后续的代码检视,以及你对检视意见的回应才是重点。这将在下一篇文章中介绍。