前一段时间,我的几位朋友做了国内唯一一个以区块链为主题的 Podcast , http://forkit.fm/ 。主播都是都是开源世界的老手,所以大家对 fork 这个词是非常有感情,但是不同的语境下,其实 fork 的含义是有差异的,下面咱们仔细聊聊。

传统开源语境下

Peter 十多年前就开始做开源了,那个时候如果有人说,You are forked ,其实是一个不好消息。fork 就是 Knife and Fork 中的 fork ,就是吃饭用的叉子。但是开源代码跟叉子是怎么挂上勾的呢?

我们要从开源代码的开发过程说起。说起一个项目,最初其实就是一个文件夹,里面存放着一些代码。每次对项目的修改内容,开源世界的行话叫做一个 patch ,翻译成中文就是补丁,注意,开源世界的补丁是源码形式的,跟升级 windows 系统时说的补丁不一样。这样,项目不断添加补丁,就会形成多个版本。有了类似 CVS 和 SVN 这样的版本控制工具之后,每一个版本都会被永久保留,同时新老版本互相连接,就形成一条线。后来大家都用 Git 做版本控制了,一个版本叫做一个 commit 。

那项目什么时候会被 fork 呢?项目不断开发,总有人会对项目的方向有不同意见,所以这些人会把项目代码自己拷贝一份。然后按照不同的思路继续开发。这样形成的结果是,两拨人的项目的最初的一些版本是相同的,也就是开发都在一条线上,但是后来大家分道扬镳了,项目变成了两条线来进行。这样整体上看起来就像叉子一样,顶部分叉了。这就是 fork 这个词在开源世界的最初含义了,国内对 fork 的翻译是”分叉“,翻译的非常好。

所以说,开源世界的分叉,最本质的意思就是,有些人跟我有不同意见,自己另起炉灶了。所以,一旦被 fork ,就意味着团结破裂,竞争出现,所以是不太好的感觉。

Github 语境下

2008年 Github 诞生了,Fork 的含义开始变得越来越正面。Github 甚至还出过一个文化衫,上面赫然印着 Fork me 。这种含义的转变,跟 Git 的工作模式有关系。

Linux 之父 Linus 在2005年创造了 Git 版本控制工具。Git 是去中心化的版本控制,原则上是没有中央服务器的,每个人都是各自开发,即使机器不联网也一样可以制作新版本,所以如果使用 Git 来开发项目,任意一个时间点,出现无数的分支时很正常的事情了,也就是说即使大家共识没有破裂,项目也一直处于一种临时的 fork 状态。区别于传统的 CVS/SVN 这些版本控制工具,Git 最大的强项就是合并分支,术语就叫 Merge 。

Github.com 上一个项目被 fork 的次数越多,就意味着这个项目越活跃。Github 流行起来之后,fork 的含义非常积极了。打开一个开源项目,例如 https://github.com/nervosnetwork/ckb ,页面的右上角就可以看到一个 fork 按钮。如果我想要为这个项目贡献代码,就点一下 Fork 。这样,Github 就会把 ckb 项目拷贝到我的名下。这样,我就可以在这个拷贝上不断做 commit 。当我想要提交这些代码给 ckb 官方的时候,就会发一个 Pull Request ,也就是“拉取请求”,ckb 官方收到请求通知后,可以审核一下我的代码,没有问题就可以把代码 merge 到官方仓库中了。

所以说,Github 语境下,fork 是整个开源贡献过程的第一步,没有任何共识破裂的意思,所以意义是完全积极的。

区块链语境下

区块链出现以后,fork 这个词又反复出现在区块链语境下。http://forkit.fm/ 上第一期就是 《 Let’s talk about FORK 》,两位主播作为区块链的资深从业者,聊了他们对 fork 的看法,可以作为参考。我认为区块链这里 fork 要分两个层面来讨论。

首先第一个层面,区块链项目本身都是开源项目,一个区块链项目被 fork 了,首先就是一个传统的开源 fork 的事件发生了。类似比特币这样的区块链项目,都是基于去中心化网络的。整个网络上没有中央服务器,每个节点都是一个安装了相同的客户端的一台机器。每个机器都地位对等,互为服务器。对于比特币,所有的运行规则都要靠比特币客户端来执行。比特币客户端的代码在 https://github.com/bitcoin/bitcoin 。2017年比特币就被 fork 过一次,有一批人另起炉灶,搞了 BCH ,代码就是把比特币的代码拷贝一份,然后继续开发,当然这些新开发的内容是根本没有打算 merge 回官方的仓库的。

再说第二个层面,区块链本身也会分叉。前面我们说的分叉,一直是说源码的各个版本形成的一条历史线出现了新的分支。但是有意思的是,区块链本身也是一个由多个区块组成的一条历史线,所以区块链语境下,人们说分叉,一般指的是区块链的分叉,而非客户端源码的分叉。这里的知识非区块链业内人士不会太关心,所以这里我简要说明一下。区块链分叉有软分叉和硬分叉之分。软分叉指的是最终能回归到一条线上的分叉,是临时性的分叉。而硬分叉是永久性的分叉,原因就是因为客户端代码有了大的改动造成了向前不兼容。例如,比特币官方客户端和 BCH 项目的客户端不兼容,就出现了硬分叉,这是两拨人共识破裂造成的。但是,也有的时候,官方发布了向后不兼容的更新,也会通过硬分叉的形式对区块链进行升级。

总之,区块链语境下,人们说的分叉通常指的是区块链自身的分叉,而非客户端源码的分叉。

总结

这节关于分叉,咱们就聊到这里。总结一下,传统上分叉,只的是源码分叉,指的是开源项目的开发历史线出现了新的分支。而区块链分叉,是区块连接成的历史线出现了新的分支。不管是源码分叉还是区块链的分叉,本身善恶没有定论,一方面意味着社区力量不团结了,但是另一方面,少数派有权利自己去探索一条新道路,也是一种开源自由精神的体现。