向一个项目贡献

描述如何向一个项目贡献的主要困难在于完成贡献有很多不同的方式。 因为 Git 非常灵活,人们可以通过不同的方式来一起工作,所以描述应该如何贡献并不是非常准确 - 每一个项目都有一点儿不同。 影响因素包括活跃贡献者的数量、选择的工作流程、提交权限与可能包含的外部贡献方法。

第一个影响因素是活跃贡献者的数量 - 积极地向这个项目贡献代码的用户数量以及他们的贡献频率。 在许多情况下,你可能会有两三个开发者一天提交几次,对于不活跃的项目可能更少。 对于大一些的公司或项目,开发者的数量可能会是上千,每天都有成百上千次提交。 这很重要,因为随着开发者越来越多,在确保你的代码能干净地应用或轻松地合并时会遇到更多问题。 提交的改动可能表现为过时的,也可能在你正在做改动或者等待改动被批准应用时被合并入的工作严重损坏。 如何保证代码始终是最新的,并且提交始终是有效的?

下一个影响因素是项目使用的工作流程。 它是中心化的吗,即每一个开发者都对主线代码有相同的写入权限? 项目是否有一个检查所有补丁的维护者或整合者? 是否所有的补丁是同行评审后批准的? 你是否参与了那个过程? 是否存在副官系统,你必须先将你的工作提交到上面?

下一个问题是提交权限。 是否有项目的写权限会使向项目贡献所需的流程有极大的不同。 如果没有写权限,项目会选择何种方式接受贡献的工作? 是否甚至有一个如何贡献的规范? 你一次贡献多少工作? 你多久贡献一次?

所有这些问题都会影响实际如何向一个项目贡献,以及对你来说哪些工作流程更适合或者可用。 我们将会由浅入深,通过一系列用例来讲述其中的每一个方面;从这些例子应该能够建立实际中你需要的特定工作流程。

提交准则

在我们开始查看特定的用例前,这里有一个关于提交信息的快速说明。 有一个好的创建提交的准则并且坚持使用会让与 Git 工作和与其他人协作更容易。 Git 项目提供了一个文档,其中列举了关于创建提交到提交补丁的若干好的提示 - 可以在 Git 源代码中的 Documentation/SubmittingPatches 文件中阅读它。

空白错误

首先,你不会想要把空白错误(根据 git help diff 的描述,结合下面给出的图片,空白错误是指行尾的空格、Tab 制表符,和行首空格后跟 Tab 制表符的行为)提交上去。 Git 提供了一个简单的方式来检查这点 - 在提交前,运行 git diff --check,它将会找到可能的空白错误并将它们为你列出来。

如果在提交前运行那个命令,可以知道提交中是否包含可能会使其他开发者恼怒的空白问题。

每一个提交成为一个逻辑上的独立变更集

接下来,尝试让每一个提交成为一个逻辑上的独立变更集。 如果可以,尝试让改动可以理解 - 不要在整个周末编码解决五个问题,然后在周一时将它们提交为一个巨大的提交。 即使在周末期间你无法提交,在周一时使用暂存区域将你的工作最少拆分为每个问题一个提交,并且为每一个提交附带一个有用的信息。 如果其中一些改动修改了同一个文件,尝试使用 git add –patch 来部分暂存文件(在 交互式暂存 中有详细介绍)。 不管你做一个或五个提交,只要所有的改动是在同一时刻添加的,项目分支末端的快照就是独立的,使同事开发者必须审查你的改动时尽量让事情容易些。 当你之后需要时这个方法也会使拉出或还原一个变更集更容易些。 重写历史 描述了重写历史与交互式暂存文件的若干有用的 Git 技巧 - 在将工作发送给其他人前使用这些工具来帮助生成一个干净又易懂的历史。

提交信息

最后一件要牢记的事是提交信息。 有一个创建优质提交信息的习惯会使 Git 的使用与协作容易的多。 一般情况下,信息应当以少于 50 个字符(25个汉字)的单行开始且简要地描述变更,接着是一个空白行,再接着是一个更详细的解释。 Git 项目要求一个更详细的解释,包括做改动的动机和它的实现与之前行为的对比 - 这是一个值得遵循的好规则。 在这些信息中使用现在时态祈使语气也是一个好想法。 换句话说,使用命令。 使用 “Add tests for.” 而不是 “I added tests for” 或 “Adding tests for,”。 这里是一份最初由 Tim Pope 写的模板:

修改的摘要(50 个字符或更少)

如果必要的话,加入更详细的解释文字。在
大概 72 个字符的时候换行。在某些情形下,
第一行被当作一封电子邮件的标题,剩下的
文本作为正文。分隔摘要与正文的空行是
必须的(除非你完全省略正文);如果你将
两者混在一起,那么类似变基等工具无法
正常工作。

空行接着更进一步的段落。

  - 句号也是可以的。

  - 项目符号可以使用典型的连字符或星号
    前面一个空格,之间用空行隔开,
    但是可以依据不同的惯例有所不同。

日志提交规范

可以使用

[Feature] 新特性

[Fixed] 修复一个BUG

[Update] 更新

[Remove] 文件删除

[Optimize] 优化

如果你所有的提交信息看起来都像这样,对你与跟你工作在一起的其他开发者来说事情会变得非常容易。

Git 项目有一个良好格式化的提交信息 - 尝试在那儿运行 git log --no-merges 来看看漂亮的格式化的项目提交历史像什么样。

在接下来的例子中,以及贯穿本书大部分,出于简洁性的原因本书不会有像这样漂亮格式的信息;相反,我们使用 -m 选项的 git commit。 照我们说的做,而不是照我们做的做。

私有小型团队

你可能会遇到的最简单的配置是有一两个其他开发者的私有项目。 “私有” 在这个上下文中,意味着闭源 - 不可以从外面的世界中访问到。 你和其他的开发者都有仓库的推送权限。

在这个环境下,可以采用一个类似使用 Subversion 或其他集中式的系统时会使用的工作流程。 依然可以得到像离线提交、非常容易地新建分支与合并分支等高级功能,但是工作流程可以是很简单的;主要的区别是合并发生在客户端这边而不是在提交时发生在服务器那边。 让我们看看当两个开发者在一个共享仓库中一起工作时会是什么样子。

ps: 剩下的流程比较多,此处省略。

私有管理团队

在接下来的情形中,你会看到大型私有团队中贡献者的角色。

在你将学习到的这种工作环境中,小组基于特性进行协作,这些团队的贡献将会由其他人整合。

ps: 剩下的流程比较多,此处省略。

派生的公开项目

向公开项目做贡献有一点儿不同。

因为没有权限直接更新项目的分支,你必须用其他办法将工作给维护者。 第一个例子描述在支持简单派生的 Git 托管上使用派生来做贡献。 许多托管站点支持这个功能(包括 GitHub、BitBucket、Google Code、repo.or.cz 等等),许多项目维护者期望这种风格的贡献。 下一节会讨论偏好通过邮件接受贡献补丁的项目。

ps: 剩下的流程比较多,此处省略。

通过邮件的公开项目

许多项目建立了接受补丁的流程 - 需要检查每一个项目的特定规则,因为它们之间有区别。 因为有几个历史悠久的、大型的项目会通过一个开发者的邮件列表接受补丁,现在我们将会通过一个例子来演示。

工作流程与之前的用例是类似的 - 你为工作的每一个补丁序列创建特性分支。 区别是如何提交它们到项目中。 生成每一个提交序列的电子邮件版本然后邮寄它们到开发者邮件列表,而不是派生项目然后推送到你自己的可写版本。

ps: 剩下的流程比较多,此处省略。

总结

这个部分介绍了处理可能会遇到的几个迥然不同类型的 Git 项目的一些常见的工作流程,介绍了帮助管理这个过程的一些新工具。 接下来,你会了解到如何在贡献的另一面工作:维护一个 Git 项目。 你将会学习如何成为一个仁慈的独裁者或整合管理者。

参考资料

5.2 分布式 Git - 向一个项目贡献