邮件列表VS GitHub(2018)

2020-07-01 15:49:15

大多数羽翼未丰的开源项目都使用Github或GitLab进行代码协作。但是,有一种较旧的方法是开发人员应该知道的,因为它提供了一些优势。

另一种方法是开发人员邮件列表。它出现在80年代末到90年代初,早于网络浏览器的流行。但是,讨论列表远非仅仅是历史珍品,它仍然是许多重要开源项目(从数据库到操作系统再到Web浏览器)的主要开发方法。

在本文中,我将仔细比较邮件列表和代码协作网站(如Github)的使用情况。我会尽最大努力展示每种方法的优缺点,以便评估这两种方法的项目能够做出明智的决定。

GitHub托管一个GIT服务器、一个bug跟踪器、一个维基,以及发布的工件。参与讨论或代码更改需要Github身份。建议更改代码的方法是创建另一个由Github托管的项目(“fork”),修改远程分支,并使用GUI打开从您的分支到原始分支的Pull请求。项目成员讨论注释中的更改,随后的更改作为提交推送到Pull Request分支。最终,项目所有者可以决定合并提交。

邮件列表维护一个订户列表,这些订户接收发送到“反射器”电子邮件地址的所有消息。项目必须在其他地方承载其自己的版本控制服务器。代码更改建议通过向反射器发送一封电子邮件,并附带更改的文本差异或内联更改。列表成员通过电子邮件回复就更改进行辩论,将后续更改作为更多不同之处发送,以取代或修改原始更改。最终,项目提交者可以决定将补丁应用到代码库。

邮件列表有三个属性,使开发人员可以比在Github UI中更精确、更灵活地进行通信:电子邮件的线程化、用户生成补丁以及自由混合讨论和补丁。

Github web UI有一个有限的线程模型,其中拉取请求作为一个整体有一个线程,其他线程附加到单个更改的代码行。UI显示了所选讨论行周围的几行上下文代码,但必须推断讨论中的完整代码块。

电子邮件子线程允许对代码的不同方面或部分进行专门讨论。线性的Github风格的讨论会将这些对话混为一谈。

与Github的评论相比,通过电子邮件进行的对话具有更大的持久性和参考价值。在Github上,评论不断变化。它们会变得“过时”,并在连接到已更改的线路时消失。提交也是如此,在强制推送到拉取请求分支之后,提交就会消失。相比之下,在电子邮件线程中,原始消息和建议的更改将保留下来,以便与以后的消息和补丁进行比较。

此外,来自多个作者的补丁不能混合在Github拉取请求中。打开拉取请求的人“拥有”它。其他参与者可以将代码建议作为注释删除,但UI最终合并的是分支上的提交。如果Pull请求者想要合并建议的更改,他或她必须将这些注释转换为分支上的提交。

在邮件列表上,任何人都可以自由地回复现有的帖子,提供一组新的建议补丁。另一个好的效果是,如果原作者不再关心或参与,其他人可以把补丁带到终点线。(多年来,我在我的项目的拉请求中遇到了许多MIA作者。)。

自定义补丁是电子邮件进程通过Github UI改进通信的另一种方式。贡献者可以调整补丁的形状,使其对其他人更具可读性。

使用Github你提交你的更改,然后Github选择如何将差异呈现给审阅者,但是当你自己创建补丁时,你可以调整设置。差异可以是统一格式或上下文格式,对于后者,上下文行的数量是可配置的。(公平地说,Github也允许围绕变化扩大背景视角。)。

有些人认为,GIT样式的统一差异对于少数几行的小更改最为清晰,而上下文差异更适合更改较大的范围,特别是具有缩进更改的行。(为了公平起见,我应该注意到,如果在显示更改的URL中添加?w=1,则Github将隐藏缩进更改。)。

最后,使用diff手动创建补丁可以利用其他选项,比如注释影响C函数的块标头(使用-p标志),以及选择“Patience”等各种算法。

耐心会多做一点工作来计算其结果,但输出对人类来说更有意义。例如,标准(非耐心)差异可能如下所示:

void func1(){x+=1+}++void funcThree halves(){+x+=1.5}void func2(){x+=2}。

void func1(){x+=1}+void funceHalves(){+x+=1.5+}+void func2(){x+=2}。

最后,没有什么可以阻止邮件列表风格的协作适应新兴的差异格式,例如结构差异。这是因为电子邮件中的补丁直接描述更改,而Github呈现的是没有细微差别的增量。

围绕一个新功能的大部分交流都是在它的提案中进行的,而不是围绕随后的代码。贡献者在编写任何代码之前提出该功能,证明其合理性,并确认其范围。社区做出了响应,通常在任何人实现任何东西的时候,想法已经从流程开始时发生了重大变化。

这也是电子邮件非常适合小组讨论的地方,它具有上面提到的内联回复和线状结构。到了开始编码的时候,从“问题”切换到“拉请求”是没有间断的。作者简单地再次回复,并附上补丁。

Web应用程序提供集中控制的用户界面,而本地应用程序允许每个人定制自己的体验。像SMTP这样的开放协议促进了客户端的激增。邮件客户端也是如此,每个客户端都提供自己的功能、过滤器、文件夹、标志和乐趣。邮件客户端提供了将邮件标记为重要邮件或将其设置为未读的方法。一般来说,你不需要在五年内向中央委员会乞求更换接口,但没有失败。(碰巧,在一份非官方的回购中可以看到这份请愿书,该请愿书旨在恳求吉图布诸神。)。

有些人编写邮件客户端脚本,以便可以使用键盘快捷键应用补丁程序,有些人选择极简主义,还有一些人甚至使用Webmail。每个人都是不同的,他们的软件也是不同的,但邮件列表的性质允许他们所有人一起工作。

另一个控制区域是脱机时搜索邮件列表并与之交互的能力。这通常是自愿的,而不是必然的。城市和郊区通常可以随时随地使用互联网接入,如果需要的话,可以使用蜂窝服务。事情不再像以前那样有断断续续的拨号连接,但脱机工作是一些人更喜欢的选择。

虽然Git本身是分布式的,并且在没有网络连接的情况下在本地运行,但Github需要连接才能检查问题和拉入请求。为一项本质上需要反思的单独任务要求连通性是不合理的。

请记住,在线有两个方向:开发者的互联网连接和Github的正常运行时间。虽然后者已经相当稳定了一段时间,但我确实记得有几次我的整个办公室因为Github停机而脱轨。对于愤怒的国家和野心勃勃的黑客来说,拿下Github是一个很有吸引力的目标。

使用本机电子邮件客户端,您可以脱机查看所有电子邮件和附件。您甚至可以脱机发送对邮件的回复,客户端将对它们进行排队,直到可以访问Internet为止。

另一方面,邮件列表服务器的正常运行时间,发送到脱机服务器的邮件最终将通过。电子邮件链上的邮件传输代理被设计为重试传输。此外,开发人员列表建议用户“全部回复”消息,以便线程中涉及的每个人以及列表反射器地址都能收到消息。这样,即使反射器离线,您的电子邮件也可以直达最近参与的人。

归根结底,邮件列表开发风格所享有的控制和可定制性来自于为开放标准构建的各种工具。补丁文件是普遍支持的(git本身直接支持补丁),SMTP有一个RFC。工具可以协同工作,而不是将GUI锁定在浏览器中。

Git最初是为了逃避BitKeeper而创建的,BitKeeper是一个具有相关集中托管的版本控制系统。BitKeeper为开源项目授予了免费许可,并要求项目将其元数据存储在公司服务器上。

那么,Git的用户选择了Github…,这真是历史的转折。为开源项目授予免费许可证的集中式主机,并要求项目将其元数据存储在公司服务器上。

GitHub可以合法删除项目或用户,无论是否有原因。这当然是有意义的,因为这些项目使用的是Github拥有的计算机。此外,虽然没有像BitKeeper那样明确禁止竞争项目的开发,但Github仍然可以查看所有选择与它们一起托管的公司的私人源代码。

说真的,Github(或任何利润驱动但免费的代码托管服务)的未来是什么?历史提供了SourceForge的例子,SourceForge是世纪之交首屈一指的代码协作平台。在被Dice.com收购后,SourceForge为赚取更多资金做了最后的努力,劫持了托管项目,以便它们的安装程序将包括广告软件和间谍软件。

当我第一次开始为这篇文章做笔记时,对Github的影响纯粹是假设的,但即使在撰写本文时,有消息称微软正在收购Github。说Github可能进入“SourceForge阶段”并不牵强。

然而,让这一教训比吉瑟布更广泛。同样的逻辑也适用于集中和组合程序员通信和托管的其他Web平台。

一些主要的开放源码项目,如PostgreSQL数据库,非常安全,并明确选择从不将代码放在外部公司服务器上(镜像除外)。Postgres还煞费苦心地将控制权放在一个横跨多家公司的管理机构中。任何公司都不允许大多数提交者,组织的设计是为了独立生存。

并不是所有的项目都重要到需要这种程度的中立,但所有的项目都应该掌握自己的命运。

我们正在讨论的基本任务是代码更改的异步组通信。补丁是一种普遍理解的描述代码更改的方式,而电子邮件是一种普遍理解的通信方法。因此,这种方法似乎与手头的问题相匹配。

事实上,通过电子邮件发送补丁适用于任何版本控制系统,而不仅仅是Git。OpenBSD项目仍然很乐意将邮件列表与CVS结合使用。补丁作者根本不需要安装任何版本控制软件。作者可以下载源代码发行版tarball、在副本中进行更改、捕获差异并通过电子邮件发送。

发送和应用补丁程序省去了一些工作,比如合并后清理远程分支,或者在派生的回购中创建本地分支以准备拉入请求。作为对比,我记得我教过一群新程序员如何使用Github,在我要求他们做所有奇怪的步骤时,我都是有意识的。

完成通信的工作也更少了。没有需要“清理”的东西,比如放弃的拉取请求、合并的分支或要标记为已关闭的问题。回复只是停留在那些帖子上。稍后会有更多关于这一点的负面信息,但目前来看好的一面。

使用电子邮件还可以将数字身份从Github这样的网站上的账户中分离出来,并最终信任由国际组织ICANN管理的DNS系统。有关这方面的更多信息,请参阅我的文章“回归最初的社交网络”。PGP通过分散的信任网络提供进一步的身份保证。请看我录制的尼尔·沃尔菲尔德的演讲“GnuPG的高级入门”(The Advanced Intro To GnuPG)。

邮件列表方法带来了相当多的问题和困难。我已经尽了最大努力承认这些问题,并提出可能的解决方案。

当您浏览Github项目时,您确切地知道它是如何工作的。当然,插件/配置项/挂钩可能会有所不同,设置项目可能会涉及一些扭曲,但浏览代码、查找已知bug和提交更改的过程总是相同的。对于有自己的网络存在和邮件列表的项目来说,这绝对不是真的。

我甚至听到人们说,“如果一个项目不在Github上,那么我贡献的可能性为0%。”老实说,我也不能说我为非Github项目做出了贡献。在我从Google Code迁移到Github之后,我唯一的非Github贡献(如果你想这么称呼他们的话)是为Chrome提交一份bug报告,另一份是为GitLab上的一个工具提交错误报告。

另一个不熟悉的来源是,许多人,特别是年轻的开发人员,从来没有见过像MUTT这样的真正的邮件客户端。在他们的脑海中,他们可能会想象一个满满的Gmail收件箱,里面装满了来自不同项目的热门回复。这不是一个诱人的形象。也许本文可以让这些开发人员重新发现传统电子邮件客户端(它们被称为“MUA”)中的关怀和工程。

考虑到不熟悉的情况,自托管项目需要非常清楚地沟通它是如何进行协作的。仅有一个邮件列表是不够的;一个项目需要在网络上进行自我解释,并提供有关参与的信息。

关于陌生感的最后一点说明。请注意,在当今的互联时代,离线用户可能会被误解。在离线状态下写一封电子邮件可能看起来很愚蠢,只是在另一个更好的回复使您的回复变得不必要之后,它才会让它排队、发送和到达。可能明智的做法是在签名行中加上这样的内容:“注意:离线编写,可能缺少最近的上下文。”

Github以外的项目面临的下一个问题是缺乏通过明星投票的社会证明。没有明星,新项目更难建立声誉。人们注意到一个拥有数千颗星的项目的方式,仅仅是项目描述是无法唤起人们的注意的。虽然许多成熟的软件,如操作系统、浏览器和数据库在没有明星的情况下都表现良好,但它们在几年前就获得了认可,或者得到了大公司的推广。

帮助自托管项目受欢迎的一种方法是在不太深入的情况下与Github挂钩。像git和linux这样的一些项目是运行他们自己的服务器,但是在Github上提供一个只读镜像,以供公众欣赏和代码浏览。

可以提供帮助的两个工具是Pull Request Rejection Bot和用于禁用问题的内置设置。在禁用Pull请求和问题之后,项目自述文件需要包含有关如何以及在哪里做出贡献的信息。

自托管的Git服务器还需要一个提交后挂钩来使Github保持最新。此命令应该会在钩子中起到作用:

邮件列表的一大困难是共享电子邮件线程的全局状态。显然,不是信息的内容,而是需要采取行动的决定。单个投稿人可以在其邮件客户端中标记要操作的邮件,但此状态对每个人都是私有的。公开记录补丁已被接受以供将来应用,或修复了之前报告的错误,这很有帮助。

项目通过以下两种方式之一来实现这一点:将元数据添加到git存储库本身,或者使用绑定到邮件列表的外部工具。

例如,PostgreSQL有一个问题,补丁挂起而没有被接受或拒绝(一次有多达250个建议的补丁需要考虑!)。因此,该团队创建了Commifest.postgresql.org。贡献者现在在此站点上注册补丁以供最终审查。提交者每年几次停止自己的工作,并抽出时间接受/推迟/拒绝/应用补丁。

Patchwork是一种与Postgres无关的类似工具,更适合一般使用。Patchwork通过订阅邮件列表来补充邮件列表,就像一个人一样,并从电子邮件中捕获补丁。它为每个补丁创建一个网页。它不会分割讨论,因为它不允许通过Web界面进行评论,它只反映电子邮件中的任何评论,并允许维护人员使用诸如已接受、已拒绝或正在审查的状态来标记补丁。

我刚刚了解到一件令人惊讶的事情:PostgreSQL项目没有任何新的贡献者可以去寻找该项目的开放bug列表。有一个单独的邮件列表pgsql-bugs,人们在那里报告它们,但没有任何与pgsql-hacker上的活动联系在一起的东西来表明漏洞是否已经解决。有趣的是,OpenBSD还有一个bug电子邮件列表,没有集中的bug状态。

Postgres仍在寻找一种与他们喜欢的工作方式相匹配、不会影响邮件列表的系统。我不相信OpenBSD想要一个bug追踪器。就像他们在IRC上打趣的那样,“如果我们真的有一个,我们就是FreeBSD了,不是吗?”

对于确实需要bug跟踪器的项目,Debian项目中的Debbugs是一个很好的竞争者。它提供了一个电子邮件界面来处理错误,并且可以用于Debian以外的项目。

其他bug系统通过将文件或对象添加到项目git repo本身来工作。因此,修复分支上的bug可能意味着将该bug与该分支上的其他更改一起从repo中删除。与电子邮件一样,这也保留了对错误信息的离线访问权限。也许最好的之一是到处都是虫子。另一个相当干净的代码被简单地称为bug。

一旦您订阅了邮件列表,新邮件就会流入您的客户端并可供搜索。万岁!但是,在你加入列表之前发送的消息怎么办?此外,您如何“链接”到来自新消息的旧消息?Github上的每个问题都有自己的URL,所以问题可以相互引用,但是一封电子邮件怎么会说这样的话:“我们已经在消息X中讨论过这个问题,请看那里。”

其工作方式是使用Message-ID头。每封电子邮件都有一封,它们是回复方式的一部分。它们是大GUID,看起来像[email protected]或CAFjFpReKyYrsUF8sP5GoPYyyp9ZSqm_mLeD8kQLigX-3CzDiUg@mail.gmail.com.。因此,一封电子邮件可能会说,“我们在[email protected]讨论了这个问题,让我们将讨论转移到那里。”

阅读在您加入列表之前发送的邮件需要转到Web上的列表存档。好的存档提供指向Mbox文件的链接,这些文件可以导入到本地邮件客户端。这样就可以在邮件客户端中搜索/回复旧邮件。档案通常还提供一个Web界面来读取HTML格式的邮件,但是在这些旧界面中导航线程通常比在一个好的邮件客户端中要麻烦得多。

例如,查看pgsql-hacker的存档。请注意Mbox文件链接。你可以下载一个月的邮件Mbox,可以是单独的邮件,也可以是完整的帖子。要导航到某个消息ID,请使用URL https://www.postgresql.org/message-id/:the-id.。试试我前面列出的其中一个ID。同样,Linux内核邮件列表存档可以通过lkml.kernel.org按id显示消息。

请记住,所有电子邮件都有Message-ID。

..