日文原文:Gitメンテナ 濱野純:小飼弾のアルファギークに逢いたい♥
上一篇文章中提到,最近正在阅读《入门 Git》,搜索作者滨野纯相关信息的时候搜到了以下这篇著名博客作家小饲弹对滨野纯的访谈,里面提及了滨野纯当初参与 Git 项目时的轶事,以及他对于开源项目的看法。特别是滨野纯说“Git 是他第一次有一定规模地向开源项目提交代码”,很是鼓舞人——对那些想参与开源项目但缺乏信心的同学。所以趁闲把访谈全文翻译了一下。
今天我们的嘉宾,是分布式版本管理系统 Git 的主要维护者,同时也是《入门 Git》一书的作者,滨野纯先生。而这次的访谈,也从滨野先生谈自己从 Linux 内核的开发者,Linus Torvalds 手中接过 Git 维护工作的原委开始了。
结识 Git 的经过
小饲弹(以下简称弹):当初是因为什么原因参与 Git 了的开发呢?
滨野纯(以下简称滨):2005 年 4 月起 Linux Kernel 所使用的版本管理系统 BitKeeper 就因为 Licence 关系无法继续使用了,所以 Linus 考察了很多当时的版本管理系统,但认为没有一个是能用的。于是他在邮件列表里发了一封邮件,说自己写了一些代码,准备作为在找到更好的版本管理系统之前的过渡系统。而我看到那封邮件时,正好是我的本职工作处于旧项目刚刚完成而新项目还未上马的间歇时期。我觉得这似乎是件挺有意思的事情,于是就把代码下载了下来,看了一下发现只有 1244 行。
弹:全部都是C代码吗?
滨:是啊。这点代码量我估计 2 小时左右应该就能读完了。仔仔细细地读了一遍以后,被代码所表现出来的优美折服了。基本上我不算是一个 Kernel 开发者,Kernel 邮件列表也只是偶尔看一眼的程度而已。但是,如果说参与数十万行的 Kernel 开发确实有点困难的话,参与这个尚且才 1000 多行代码的项目应该会很有趣,这算是当初参与 Git 的动机之一。那时候,在一周时间内发生了很多事,不过归纳起来就是 Linux 的内核开发者们听说 Linus 要用个“新玩意”来管理代码,如果那个“新玩意”太难用的话大家都痛苦,还不如一起想办法把这个东西做好用点。而我也得以在开发中观察这个项目的进展,思考这个新系统真正需要的是什么等等,总之最后完成了提交 commit 的功能和输出 diff 的功能。不过,merge 功能还没有完成。虽然 Linux 当时发过好几封邮件,描述他理想中的 merge 应该是怎样的。
弹:Linus 对既往的版本管理系统,最不满的就是这方面吧。
滨:因为 Linus 只写C和 Shell,而 merge 的逻辑实在太复杂,所以他多次发邮件到邮件列表,说要是有人能够用脚本语言实现一个就好了。不过谁也没有上钩。就这么过了一个星期,一直关注邮件列表的我用 Perl 把 Linus 过去多次提到的 merge 算法实现并投到了邮件列表里。这是我第一次有一定规模地向开源项目贡献代码。然而,尽管我详细地写了将近 30 个测试用例以及各种分支条件下应该怎么处理的表格,6 个小时以后 Linus 提交到 master 分支的却是个截然不同的东西。据本人说是想到了更好的办法所以就这么着了。我看了一下,确实就像哥伦布的鸡蛋一样——足以让我那些依照 Linus 以前的逻辑所写的代码毫无价值——就是优雅到这种程度。不过之前你还说什么“谁来帮忙做一下啊”我做了结果你又不要(笑),然而当时并没有这么想,因为新的处理方法确实很漂亮。
哥伦布的鸡蛋
弹:为什么说是哥伦布的鸡蛋呢?
滨:我虽然没有使用过 BitKeeper,不过 BitKeeper 的做法是在 work tree 里基本上只存放自己的文件,而 merge 不发生在这里。merge 时首先会创建一个临时文件夹,在里面展开 merge 结果,发生冲突时就在里面解决,然后提交 commit 并在 work tree 里展开,这样就算 merge 完成了。最初 Git 也准备使用相同的流程,不过解决了冲突以后的代码,commit 前想测试一下也是人之常情。所以我们就想那不如不要临时文件夹,直接在 work tree 上 merge 就行了…。Git 在提交 commit 之前,不是有个记录了本次 commit 内容的 index 吗?对于这个 index,当初提出了引入分步骤(stage)的概念。也就是说,本来所谓3-way-merge 就是,首先我们有一个共同的版本,你在这个版本的基础上做了一些变更,我在这个版本的基础上做了另一些变更,然后将这两个差分 merge 起来。那么把这三个版本分别作为 stage1,stage2,stage3 依次添加到 index 里,那 merge 不就完成了吗——Linus 当时就是提出了这样的建议。仔细想想这种做法确实可以一下子解决很多问题。例如最简单的情况,我和你都没有做出变更,那么 merge 的结果就是没有变更。如果我做了变更而你没有,那么最后得到的就是我变更以后的代码,反之亦然。另外还有一种特殊的情况,就是你和我都做了“相同”的变更。
弹:这种事经常有啊(笑)。
滨:实际使用过以后发现确实如此,特别是 Linux Kernel 的开发,是基于邮件列表的。所以常有你我看到同一个 patch,因为自己使用的版本是 fix 对象于是各自都打上了这个 patch。这种情况也能在 index 中解决,不仅效率很高,结果也很清晰。
Linus 的管理才能
滨:Linus 常说,项目维护者的一半工作就是说 No。不过即便如此,在拒绝别人提交的 patch 的时候,他总会向提交者强调,拒绝是因为这个提交不行,而不是你的能力不行。他对每个贡献者都很看重。我那时候也是,Linus 对我说,虽然你的提交没有采用,但测试用例还是能用的,针对现在的实现你稍微修正一下吧。
弹:挺不错啊。
滨:让对方觉得自己的工作没有白费,这样就不会打击贡献者的热情。不仅提出新的 merge 算法很厉害,Linus 作为社区管理者的才能也很厉害。不服不行啊(笑)。
GitHub
弹:GitHub 和 Git 有组织上的联系吗?GitHub 不是 Git 社区的人,而是 Git 爱好者做的吗?
滨:这个关系说来复杂了。GitHub 的创始人都是 Git 社区以外的人。那些人基本上算是 Ruby 的人吧。Ruby 社区开始大量使用 Git 应该是 Rails 采用 Git 作为版本管理以后的事。GitHub 最初在还没有像现在这样流行之前,曾经采用邀请制试运营过一段时间,但是 Git 社区的主要成员却都没有收到邀请。虽然我个人不很在意,不过有些人觉得 GitHub 那群人在拿 Git 商业化所以很不爽,结果很长一段时间两个社区之间不怎么和睦。
弹:Git 和 GitHub 是这种关系啊(笑)。都不很看重对方。
滨:经常会有无视对方自顾自地开发这种事,就比如官方 Git 和 GitHub 的 Git 的 daemon 程序在某些地方是不同的。GitHub 做了一些他们自己的改动。面向大量用户做出这种非官方的版本,作为 Git 社区也很苦恼啊。
弹:是啊。
滨:然后呢,去年1有一个 GitTogether 的活动,Google 提供了场地,一共进行了三天吧,GitHub 和 Git 社区的主要成员都来了,探讨了今后的发展方向,现在两个社区的关系应该没有过去那么差了。事实上,你也觉得 GitHub 的帮助文档很不错吧。有 GitHub 替我们做文档以及用户支持,何乐而不为呢。
弹:因为过去什么经验都没有的人也可以在 GitHub 上直接 fork 项目是吧。确实这种方式我觉得足以改变世界。从一开始就不仅是公开代码…。
滨:大家一起做一个项目,然后互相 merge,这种工作流程很不错。
弹:我也是,如果没有 GitHub 的话也不会知道 Git。
滨:是的,那是非常新颖的方式。尽管有些小地方很希望能够改一下,但是 GitHub 在普及 Git 上功不可没。
弹:就是看到了它,才终于明白为什么 Linus 不满足于过去的版本管理系统了。(那些过去的版本系统)都没法 merge 嘛。说到底,对于 Linux Kernel 这种巨型的项目来说,或许 merge 这个分支的代码还是那个分支的代码会是一个大问题,但是对于普通的项目,只要考虑是取还是舍,维护也基本只需要一个人就足够了,再不济还可以分成多个子项目多人维护,至今为止我们都是这么过来的,所以很难理解 Git 的好处。而 GitHub 的用户时不时地就会碰到“那个分支再不 merge 就要出问题了”的状况,切身体会了 merge 的重要性。我觉得那非常好。
优秀程序员的品质
弹:你觉得“优秀的程序员”是怎样的一种人呢?
滨:当初接手 Git 项目时,Linus 曾说过一个明星程序员有三种品质。最重要的第一点是,能够持之以恒地做某件事。从这个角度上来说,AlphaGeek2是不行的。尽管对于新事物迅速投身进去不是坏事,但同时又迅速地失去兴趣就不好了。顺便我自己不那么激进不是新事物爱好者也不会三分钟热度,应该不算是 AlphaGeek。
弹:原来如此,三分钟热度是不行的。重要的是坚持。
滨:第二点算是审美观吧。拥有良好的直觉和品位,这是 Linus 的原话。良好的直觉,这里是指面对一个新问题时,即使没有完整地解决问题也能够凭直觉提出正确的解决思路和方向。第三点是沟通能力。这个沟通能力不是说只要说明“我想做什么”就可以了,而是能够解释“我的目标是什么”以及我得出这一目标的整个思维过程,并且更重要的,是能够让其他人信服,简而言之就是能够将自己的目标明确传达给他人的人。我觉得这非常重要。即使在 Git 社区内,非常优秀的人至少也有7、8 人,但能够同时兼具这三点的人非常之少。
弹:虽然之于审美观我有很多想对 Linus 说的(笑)。不过我也猜得到 Linus 会怎么反驳所以我还是作罢吧。话说回来,这三点中能够做到其中两点的人,估计在哪儿都会很吃香吧。做到一点就可以说工作能力很强,做到两点就可以称之为牛人了。
滨:说的是啊。Linus 是按照我上面所说的顺序提出的这三点,从 Git 社区至今为止的发展过程中来看,我觉得即使是只具备其中一点的人,只要锻炼一下沟通能力,就能做任何自己想做的事了。沟通能力就是,即使自己做不到,只要把目标向其他人说明清楚了,就一定会有人来帮你达成这个目标。就是说只要表达想法可以不用非得自己动手。
弹:我在还没有 Open Source 这个词的时候就已经算混开源界了吧,不过近几年来,开源界的表达能力真是越来越高了。拿十年前来和现在比,现在的年轻人的表达能力实在不一般,不是最近流行 Lightning Talk[^3]嘛,就是 5 分钟的演讲。要是换作以前,肯定得花上 30 分钟絮絮叨叨才行,但是那些年轻人证明缩短到 5 分钟内是完全没有问题的。实际在与他人合作的过程中,过去是做出了产品原型和对方讨论这么做如何,而现在则相反,不需要做出实际的成品,只要把想法提出来就可以了。都是因为现在的工具发达了啊,网络速度变快了,应用平台也变好了。有这么一句老语,“现在的年轻人啊真是……”,我想说的是“真是很厉害”。我甚至都想表扬一下依然能够跟上这些年轻人脚步的自己了(笑)。现在已经是半年不看项目就跟不上的时代了。觉得 Git 很难,或许也是因为我老了吧(笑)。
对 40 岁以上的程序员说的话
弹:有什么想对 40 岁以上的程序员说的话吗?40 多岁的程序员,已经渐渐感到追赶年轻人有点吃力,对他们有什么建议吗?虽然我想说的是,那就趁 20 多岁正年轻的时候多写点代码吧。
滨:要怎样才能成为年轻人的楷模,这个问题很困难啊。
弹:至少有一点,我觉得应该做到的,就是依然觉得写代码很快乐。如果抱着受罪的心态写代码,那一定是做不好工作的。这么说来,您今年几岁?
滨:保密(笑)。
弹:至少不是 20、30 岁了吧。我觉得还是挺厉害的。在版本管理系统中 Git 最年轻,但现在却正渐渐成为主流。
滨:是啊。
弹:年轻的项目不一定只有年轻人在做,我觉得这非常好。
至此全文完。最后附一张大叔的帅气照片。
左为小饲弹先生,右为滨野纯先生。
指一个机构内对新技术最敏感,技术力顶尖的人。参考这里。?
一种只有数分钟时间的演示或者演讲形式。参考 wiki。?