3. 维护项目:与开发者互动

一旦你的项目启动,你就已经克服了程序开发过程中最困难的障碍。奠定坚实的基础至关重要,但开发过程本身也同样重要,并且提供了同样多的失败机会。在接下来的两节中,我将通过讨论如何通过与开发者和用户的互动来维护开发工作,从而描述如何运行一个项目。

在发布你的程序时,你的程序就变成了自由软件。这种转变不仅仅意味着更大的用户群。通过将你的程序作为自由软件发布,你的软件变成了自由软件社区的软件。你的软件开发方向将被你的用户,以及在更大程度上,被社区中的其他开发者重塑、重新定向和完全决定。

自由软件开发和专有软件开发之间的主要区别在于开发者基础。作为自由软件项目的领导者,你需要以一种专有软件项目领导者根本不必担心的方式来吸引和留住开发者。作为自由软件项目开发的领导者,你必须通过做出负责任的决定和负责任地选择不做出决定来利用其他开发者的工作。你必须在不专横跋扈的情况下指导开发者。你需要努力赢得尊重,并且永远不要忘记给予尊重。

3.1. 分配工作

到目前为止,你已经在假设的情况下跟随我完成了软件的早期编程、网站和文档系统的创建,并且我们已经(正如将在第 4.3 节中讨论的那样)将其发布到世界各地。时间流逝,如果一切顺利,人们会变得感兴趣并想要提供帮助。补丁开始涌入。

就像任何孩子长大的父母一样,现在是时候皱着眉头、露出微笑,并做父母一生中最困难的事情了:是时候放手了。

授权是描述“放手”这个过程的一种委婉说法。它是将项目的部分责任和权力移交给其他负责任且积极参与的开发者的过程。对于任何在项目中投入了大量时间和精力的人来说,这都很困难,但对于任何自由软件项目的成长来说,这都是至关重要的。一个人只能做这么多。一个自由软件项目,如果没有一群开发者的参与,就什么都不是。只有通过尊重和负责任的领导和授权,才能维持一群开发者。

随着项目的进展,你会注意到有人为你的项目投入了大量的时间和精力。这些人将是提交最多补丁、在邮件列表上发布最多内容以及参与长时间电子邮件讨论的人。你的责任是联系这些人,并尝试将你作为项目维护者的部分权力和责任转移到他们身上(如果他们愿意的话)。你可以通过几种简单的方法做到这一点

需要声明的是,授权并不一定意味着委员会统治。在许多情况下确实如此,并且已被证明是有效的。在其他情况下,这会造成问题。以开源方式管理项目认为,“当一个人是团队的明确领导者并做出重大决定(设计变更、发布日期等等)时,OSS 项目做得最好。”我认为这通常是正确的,但会敦促开发者考虑项目领导者不必是项目创始人,并且这些重要权力不必全部掌握在一个人手中,而是发布经理可能与首席开发者不同。这些情况在政治上很棘手,所以要小心,并在授权他人之前确保这是必要的。

3.1.1. 如何授权

你可能会发现其他开发者似乎比你更有经验或知识渊博。你作为维护者的工作并不意味着你必须是最好或最聪明的。这意味着你负责表现出良好的判断力,并识别哪些解决方案是可维护的,哪些不是。

像任何事情一样,观看别人授权比自己做更容易。一句话:留意其他合格的开发者,他们对你的项目表现出兴趣和持续的参与,并尝试将责任转移到他们身上。 以下想法可能是好的起点或灵感的来源

3.1.1.1. 允许更多人拥有 CVS 仓库的写入权限,并真正努力实现委员会统治

Apache 是一个由一小群开发者运行的项目的例子,他们对主要技术问题和新成员的加入进行投票,并且都拥有对主源代码仓库的写入权限。他们的流程在网上有详细说明。

Debian 项目是委员会统治的一个极端例子。目前统计,超过 700 名开发者对项目的各个方面负有全部责任。所有这些开发者都可以上传到主 FTP 服务器,并对重大问题进行投票。项目的方向由项目的社会契约章程决定。为了促进这个系统,有专门的团队(例如安装团队、日语团队)以及技术委员会和项目负责人。负责人的主要责任是,“任命代表或将决策委托给技术委员会。”

虽然这两个项目都在你的项目不会达到的规模上运作(至少最初是这样),但它们的例子很有帮助。Debian 的项目负责人的想法是,他可以做授权,这可以作为如何让大量开发者参与和授权,并发展到巨大规模的漫画式例子。

3.1.1.3. 委托对整个分支的控制权

如果你的项目选择拥有分支(如第 3.3 节中所述),那么任命其他人为分支负责人可能是一个好主意。如果你喜欢将精力集中在开发版本和新功能的实现上,那么将稳定版本的完全控制权交给一位合适的开发者。

Linux 的作者 Linus Torvalds 站出来,加冕 Alan Cox 为“稳定内核的人”。所有稳定内核的补丁都发送给 Alan,如果 Linus 因为任何原因离开 Linux 的工作,Alan Cox 也完全有能力胜任他作为 Linux 维护者公认的继承人的角色。

3.2. 接受和拒绝补丁

本 HOWTO 已经提到了一个事实,即作为自由软件项目的维护者,你的首要和最重要的责任之一是接受和拒绝其他开发者提交给你的补丁。

3.2.1. 鼓励良好的补丁实践

作为项目管理或维护人员,你不是会打很多补丁的人。但是,值得了解 ESR 在软件发布实践 HOWTO[ESRHOWTO]中关于良好的补丁实践的章节。我不同意 ESR 的观点,即大多数丑陋或没有文档的补丁可能一开始就值得扔掉——这根本不是我的经验,尤其是在处理通常根本不是以补丁形式出现的错误修复时。当然,这并不意味着我喜欢收到做得不好的补丁。如果你收到丑陋的 -e 补丁,如果你收到完全没有文档的补丁,尤其是当它们不仅仅是微不足道的错误修复时,那么根据 ESR 的 HOWTO 中的一些标准来判断补丁,然后向人们发送文档链接,以便他们可以以“正确的方式”进行操作,这可能是值得的。

3.2.2. 技术判断

使用 CVS 进行开源开发中,Karl Fogel 提出了一个令人信服的论点,即在拒绝或接受补丁时,最重要的事情是记住

这些是你作为项目维护者在每次收到补丁时都应该考虑的标准。

Fogel 对此进行了详细阐述,并指出“在考虑是否实施(或批准)更改时,要问自己的问题是:”

  • 它是否会使程序用户社区的很大一部分受益?

  • 它是否符合程序的领域或该领域的自然、直观的扩展?

这些问题的答案从来都不是直截了当的,而且非常可能(甚至很可能)提交补丁的人对这些问题的答案与你的感觉不同。但是,如果你认为这两个问题的答案都是“否”,那么你有责任拒绝更改。如果你未能做到这一点,项目将变得笨重且不可维护,并且最终会失败。

3.2.3. 拒绝补丁

拒绝补丁可能是任何自由软件项目的维护者都必须面对的最困难和最敏感的工作。但有时必须这样做。我之前提到过(在第 3 节第 3.1 节中),你需要尝试平衡你的责任和权力,做出你认为最好的技术决策,同时考虑到如果你看起来像是在权力游戏中,或者过于专横或占有社区的项目,你将失去其他开发者的支持。我建议你在拒绝补丁(或其他更改)时,牢记以下三个主要概念

3.3. 稳定分支和开发分支

稳定分支和开发分支的想法已经在第 2.4 节第 3.1.1.3 节中简要描述过。这些暗示证明了多个分支会以某种方式影响你的软件。分支可以让你(在某种程度上)避免一些围绕拒绝补丁的问题(如第 3.2 节中所述),方法是允许你暂时损害项目的稳定性,而不会影响那些需要稳定性的用户。

分支项目的最常见方法是拥有一个稳定分支和一个开发分支。这是 Linux 内核遵循的模型,在第 2.4 节中描述。在这个模型中,始终有一个分支是稳定的,并且始终有一个分支处于开发中。在任何新版本发布之前,开发分支都会进入第 3.4.1 节中描述的“功能冻结”状态,其中主要更改和添加的功能将被拒绝或搁置,直到开发内核作为新的稳定分支发布,并且主要开发在开发分支上恢复。不太可能产生任何大的负面影响的错误修复和小更改也会被合并到稳定分支以及开发分支中。

Linux 的模型提供了一个极端的例子。在许多项目中,没有必要始终提供两个版本。只有在接近发布时才拥有两个版本可能是有意义的。Debian 项目历史上提供了稳定和不稳定发行版,但已扩展到包括:稳定版、不稳定版、测试版、实验版以及(在发布时)冻结版,该冻结版仅在从不稳定版过渡到稳定版期间合并错误修复。很少有项目的规模需要像 Debian 这样的系统,但是这种分支的使用有助于证明如何使用它们来平衡一致和有效的开发与定期和可用的发布的需求。

在尝试为你自己设置开发树时,有几件事可能值得记住

尽量减少分支的数量

Debian 可能能够很好地利用四到五个分支,但它包含千兆字节的软件,超过 5000 个软件包,为 5-6 种不同的架构编译。对于你来说,两个可能是一个很好的上限。分支太多会使用户(我数不清有多少次我不得不描述 Debian 的系统,当时它只有 2 个有时是 3 个分支!)、潜在的开发者甚至你自己感到困惑。分支可以提供帮助,但它们是有代价的,所以要非常谨慎地使用它们。

确保解释清楚所有不同的分支

正如我在上一段中提到的,不同的分支使用户感到困惑。尽一切努力避免这种情况,方法是在你网站的显眼页面和FTP 或 Web 目录中的 README 文件中清楚地解释不同的分支。

我还可能建议不要犯我认为 Debian 犯下的错误。“不稳定版”“测试版”“实验版”这些术语是模糊的,并且难以按稳定性(或不稳定程度)排序。尝试向某人解释“稳定版”实际上意味着“超级稳定版”,而“不稳定版”实际上不包含任何不稳定的软件,而实际上是作为发行版未经测试的稳定软件。

如果你要使用分支,尤其是在早期,请记住人们已经习惯于理解“稳定版”“开发版”这两个术语,并且你可能不会因为这种简单而常见的分支划分而犯错。

确保所有分支始终可用

像本文档的许多内容一样,这可能应该是不言而喻的,但经验告诉我,对于人们来说,这并不总是显而易见的。最好将不同的分支物理地拆分到你的 FTP 或网站上的不同目录或目录树中。Linux 通过在 v2.2 和 v2.3 子目录中放置内核来实现这一点,在你知道它们的版本编号方案后,立即清楚哪个目录用于最新的稳定版和当前的开发版。Debian 通过使用名称(即 woody、potato 等)命名其所有发行版,然后更改名为 “stable”“unstable”“frozen” 的符号链接以指向哪个发行版(按名称)处于哪个阶段来实现这一点。这两种方法都有效,还有其他方法。在任何情况下,重要的是不同的分支始终可用,可以从一致的位置访问,并且不同的分支之间要明确区分,以便你的用户确切地知道他们想要什么以及在哪里获得它。

3.4. 其他项目管理问题

在一个如此规模和范围的 HOWTO 中,我无法详细介绍与自由软件项目中开发者互动的更多问题。如果你发现任何重大遗漏,请随时与我联系。

其他值得一提的小问题是

3.4.1. 冻结

对于那些选择采用拆分开发模型的项目(第 3.3 节),冻结是一个值得熟悉的概念。

冻结主要有两种形式。“功能冻结”是指在一段时间内,不会向程序添加任何重要功能。这是一个可以改进和完善已建立功能(甚至是勉强工作的功能骨架)的时期。这是一个修复错误的时期。这种类型的冻结通常在发布前一段时间(一到两个月)应用。当你等待“一个功能”时,很容易推迟发布,冻结有助于通过在沙地上划出急需的线来避免这种情况。它为开发者提供了他们需要的空间,以便为发布做好程序准备。

第二种类型的冻结是“代码冻结”,它更像是一个已发布的软件。一旦一个软件进入“代码冻结”,就不鼓励对代码进行所有更改,只允许进行修复已知错误的更改。这种类型的冻结通常在“功能冻结”之后,并且直接在发布之前。大多数发布的软件都处于可以解释为某种高级“代码冻结”的状态。

即使你从不选择任命发布经理(第 3.1.1.2 节),你也会更容易证明在公开声明冻结生效的情况下,拒绝或推迟补丁(第 3.2 节)是合理的。

3.5. 分叉

我不确定如何在本文档中处理分叉(或者是否会处理分叉)。当一群开发者从一个自由软件项目中获取代码,并实际上用它启动一个全新的自由软件项目时,就会发生分叉。分叉最著名的例子是 Emacs 和 XEmacs 之间的分叉。这两个 emacs 都是基于相同的代码库,但由于技术、政治和哲学原因,开发被分成两个现在相互竞争的项目。

分叉部分的简短版本是,不要这样做。 分叉迫使开发者选择一个项目来合作,导致令人讨厌的政治分裂和工作冗余。幸运的是,通常分叉的威胁足以吓唬项目的维护者或维护者改变他们运行项目的方式。

在关于“开源流程”的章节中,Karl Fogel 描述了如果你绝对必须这样做,该如何进行分叉。如果你已确定这是绝对必要的,并且你与威胁要分叉的人之间的差异是绝对无法解决的,我建议你阅读 Fogel 的书,这是一个很好的起点。