一本账的五十年
每改一次,就把整个项目此刻的样子记下来,盖上指纹,指着上一笔。这本账有个名字,叫 Git。
做软件的人管这本账叫「版本管理」。它走了五十多年,每一步都在回答同一个问题:一群人改同一份东西,怎么改得清楚、退得回去、说得出是谁、什么时候、为什么改的。
这五十年里,有两条线并排走。一条是程序员的:怎么管好一份文件的很多个版本。一条是密码学家的:怎么证明一份记录没被人动过。2005 年,第一条线借走了第二条线的指纹,长出了 Git。三年后,第二条线自己补上了「大家怎么达成一致」,长出了区块链。
所以 Git 和区块链很像,但不是谁学了谁。它们是同一批祖先的两个后代。
本页只谈这套记账结构,不涉及任何虚拟货币的发行与交易。
1972
留版本
贝尔实验室的罗奇金德(Rochkind)从 1972 年末开始写 SCCS:第一次让一个文件的每一次修改都存下来,想退回哪一版就退回哪一版。
在我们的工作流里
每一次提交都留着,改坏了能退。我们要求 AI 动手前先提交一次,就是这一步的用处:先留一条退路,再让它改。
和区块链比
一本账的起点都一样,先得记下来。
出处:Rochkind,The Source Code Control System,IEEE Transactions on Software Engineering,1975需订阅
1979
指纹树
默克尔(Merkle)提出一种「指纹树」:一大堆数据,层层算指纹,最后汇成一个总指纹。里面任何一块被动过,总指纹就对不上。
在我们的工作流里
Git 给整个项目的每一层目录都算指纹。我们合入后核对「线上这一版和审读过的那一版是不是一字不差」,比的就是这棵树的总指纹。
和区块链比
共同祖先之一。区块链每个区块里的交易,也用这棵树汇成一个指纹。
出处:Merkle,US Patent 4,309,569,Method of Providing Digital Signatures,1979 年申请、1982 年授权原件
1982
共识难题
兰波特(Lamport)等人提出「拜占庭将军问题」:一群互不信任、其中还可能有人说谎的人,怎么对同一件事达成一致。
在我们的工作流里
Git 没有接这道题。哪一版算数,不是 Git 算出来的,是我们约定的:送审、审读、自动检查、拍板人合入。这套工作流里的「一致」,靠人每天守。
和区块链比
这正是区块链的核心题。区块链用「谁算得最多谁记账」的办法,第一次在没有中心的情况下答了它。
出处:Lamport、Shostak、Pease,The Byzantine Generals Problem,ACM TOPLAS,1982免费全文
1991
时间戳链
哈伯(Haber)与斯托内塔(Stornetta):把每份文件的指纹里放进上一份的指纹,一份接一份串成链。谁想事后插一份、改个日期,后面全对不上。
在我们的工作流里
每一次提交都指着上一次提交。历史不能悄悄插进一笔,也不能悄悄抽走一笔。
和区块链比
共同祖先之二。2008 年那份白皮书一共 8 条参考文献,3 条出自这两位。
出处:Haber、Stornetta,How to Time-Stamp a Digital Document,Journal of Cryptology,1991需订阅
1986
—2000
一个中心
CVS(1986)、Subversion(2000 年起步)让很多人能改同一份代码,办法是一台中心服务器保管唯一的正本。服务器停了,大家就都停了。
在我们的工作流里
我们也有一个「中心」:约定托管平台上的主干算正本,生产服务器只照主干跑。但和那时不同,每个人手里都有一整本,中心坏了,账不会丢。
和区块链比
区块链要去掉的,正是这个「唯一的中心」。
出处:Grune,CVS 原始版本与 1986 年说明作者本人页;Version Control with Subversion,Subversion's History免费全文
2005
人人全本
管理 Linux 内核的开发者,因为授权纠纷失去了一款商业工具的免费使用权。托瓦兹(Torvalds)用大约十天,写出了能管内核的 Git。每个人手里一份完整的历史,每次提交都用指纹串起来,没有中心也能干活。
在我们的工作流里
每条工作线各开一条分支,各干各的,互不踩脚;开工先把自己手里这本和主干对齐,对不齐就停手。这些都是这一步给的能力。
和区块链比
这是和区块链最像的一步,人人一整本账。但 Git 没有共识:两本对不上时,谁算数,仍然由人来定。
出处:Git 的第一次提交,2005 年 4 月 7 日原件;GitHub Blog,Git turns 20: A Q&A with Linus Torvalds,2025免费全文
2008
分岔
同一年,两个后代走向了相反的方向。2 月,GitHub 还在测试,就上线了「拉取请求」:把一次改动摆成一张网页,大家可以在上面评论、审读,再决定要不要并进去;4 月正式上线。10 月 31 日,中本聪(Satoshi Nakamoto)在一个密码学邮件列表里发出了《比特币:一种点对点的电子现金系统》。
在我们的工作流里
送审页、审读意见、检查结果、谁点的合入,都记在托管平台上,不在 Git 里。Git 记「改了什么」,平台记「谁同意的」。两样合起来,才是我们的留痕。
和区块链比
区块链把「一致」写进了协议,靠计算;GitHub 把「一致」做成了一张给人看的网页,靠人。
出处:GitHub Blog,Oh yeah, there's pull requests now,2008-02-23免费全文;GitHub Blog,We Launched,2008-04-10免费全文;Nakamoto,Bitcoin P2P e-cash paper,密码学邮件列表,2008-10-31原件
2017
指纹会老
谷歌和荷兰国家数学与计算机科学研究中心第一次造出了两份内容不同、指纹却一样的文件,攻破的正是 Git 当时用的指纹算法。Git 随后加了检测,并开始准备换用更强的算法。
在我们的工作流里
「改了瞒不住」也有前提:指纹算法得够硬。我们的仓库仍用老算法,已知的攻击有检测挡着。
和区块链比
区块链同样押在指纹算法上。算法会老,账的可信度也跟着老。
出处:shattered.io,2017-02-23免费全文;GitHub Blog,Highlights from Git 2.29,2020-10-19免费全文
三本账放在一起看
我们自己同时有三本账:区块链(大家听说过的)、我们的合伙人财务账本(一笔接一笔带指纹,每天两个人分别签)、Git。放在一起看,同和异都清楚。
| 区块链 | 我们的财务账本 | Git | |
|---|---|---|---|
| 每笔带指纹、指着上一笔 | 有 | 有 | 有 |
| 改一处,后面全对不上 | 有 | 有,一键可校验 | 有 |
| 人人一整本 | 有 | 没有,在一台库里 | 有 |
| 更正的办法 | 只能往后记 | 红冲:再记一笔反向的 | 撤销:再记一笔反着改的 |
| 谁说了算 | 协议,靠计算 | 两个人分别签 | 约定,靠人审 |
| 能不能改历史 | 几乎不能 | 不能 | 能,但瞒不住 |
一句话:区块链用计算换掉了「信人」;Git 没有换掉,它让「信的是谁、谁点的头」每一步都留下指纹。
财务账本详见《合伙人的账,怎么记到不用靠人品》。
这一步,最难的不是技术
Git 给了指纹,没有给共识。共识要靠人每天守。
我们自己被教育过:有一次,改动报了「已合入」,一查其实没合上;还有一次,几笔试过但没合入的改动,分支一重置,就只剩一串提交号能去找。工具记得清清楚楚,前提是人记得去看。
Git 让每一步都翻得到;靠不靠得住,看人有没有每一步都去翻。
这一篇讲的,是我们每天在用的方法。
看我们怎么交付