你可能有過這樣的經(jīng)歷:在 debug 的時(shí)候這里加一句庞瘸,那里減一句,順便改改參數(shù)赠叼,不一會(huì)你的程序就從一個(gè) bug 增加到了無數(shù)個(gè) bug 擦囊。最重要的是,你完全想不起來自己到底改了幾個(gè)地方嘴办,原來的程序到底長什么樣子了瞬场。經(jīng)歷過幾次這樣的痛苦,你學(xué)乖了涧郊,下次 debug 之前先把原文件備份一下——改成 program.c.bak 什么的贯被,然后放開了膽子改。有時(shí)候修改的次數(shù)多了妆艘,就會(huì)出現(xiàn) program_V1.c.bak刃榨, program_V2.c.bak …… 又有時(shí)候需要同時(shí)修改多個(gè)文件。而需要倒回到之前的版本的時(shí)候双仍,又完全想不起來這些 V1, V2 到底改了哪些地方枢希。坑爹吶朱沃!難道要老子手工查不成苞轿?難道老子還要給每個(gè) version 寫個(gè)描述文件?
程序員們應(yīng)該都中槍了逗物。
或者你有過這樣的經(jīng)歷:寫論文的時(shí)候這里改動(dòng)一個(gè)詞搬卒,那里改動(dòng)一句話。改來改去發(fā)現(xiàn)還不如最初的版本……囧之余翎卓,你怎么辦契邀?Ctrl+Z 能救你幾次?甚至失暴,萬一是第二天打開 Word 的時(shí)候后悔了坯门,又怎么辦?
學(xué)生黨們應(yīng)該都中槍了逗扒。
有沒有辦法解決問題古戴?當(dāng)然有。但是別著急矩肩,喝杯茶现恼,我們慢慢聊。
1972年的時(shí)候,貝爾實(shí)驗(yàn)室的程序員們快被這個(gè)問題煩死了叉袍∈济可能純粹出于提升工作舒適度,他們寫出了史上第一個(gè)版本控制系統(tǒng)(Version Control System A.K.A. VCS)喳逛,取了個(gè)直白的名字叫 Source Code Control System疼蛾,簡稱 SCCS。這個(gè)軟件用 C 語言改寫后艺配,被收錄在 AT&T 的系統(tǒng)中。由于太懶了衍慎,這群程序員們只寫了 Unix 版本转唉。
SCCS 的原理很簡單,儲(chǔ)存要監(jiān)控的源文件稳捆,當(dāng)文件被修改時(shí)赠法,它自動(dòng)地為每次修改創(chuàng)建一個(gè)快照(Snapshot)。你工作的時(shí)候乔夯,想切換到哪個(gè)版本砖织,它就先取出源文件,再依次應(yīng)用修改直到你要的那個(gè)版本為止末荐。
SCCS 好用是好用侧纯,但有幾個(gè)問題。首先甲脏,當(dāng)你對(duì)文件作出多次眶熬、大量修改后,它的速度明顯變慢了——對(duì)啊块请,它要從原文件開始依次應(yīng)用修改嘛娜氏。然后,它內(nèi)置在 AT&T 生產(chǎn)的系統(tǒng)中墩新,不能跨平臺(tái)啊贸弥,廣大 Windows 用戶很不開心啊。
這其中 Water.F.Tichy 估計(jì)是最不開心的一個(gè)海渊。
Water 是一個(gè)教計(jì)算機(jī)的大學(xué)教授绵疲,學(xué)校里的電腦上有 AT&T 的系統(tǒng),可是到家就沒轍了臣疑,老爺子很不爽啊最岗,這叫人家在家怎么刻苦呢?1982年朝捆,他一氣之下般渡,寫出了改變歷史的第二個(gè)被廣泛應(yīng)用的 VCS,取名 Revision Control System,也就是大家熟知的 RCS(誰熟知了驯用?誰脸秽?)。
從名字上就能看出蝴乔,老爺子雄心很大记餐,不想讓它僅僅成為程序員們的玩具。RCS 開源薇正,跨平臺(tái)片酝,一經(jīng)推出即在全球……的程序員,和大學(xué)中流行挖腰。它相比于 SCCS 更快雕沿。為什么?因?yàn)槔蠣斪訖C(jī)智地?fù)Q了一個(gè)想法猴仑,儲(chǔ)存最近的文件作為源文件审轮,對(duì)歷史修改反向,并且創(chuàng)建快照(Snapshot)辽俗。對(duì)呀疾渣,正常人工作肯定是從最新的文件開始讀取,出現(xiàn)問題后再回滾到歷史文件崖飘,誰沒事就從第一版開始改起啊榴捡, SCCS 那種做法也太二了吧?
于是 RCS 開始統(tǒng)治江湖朱浴。漸漸地薄疚,程序員們又不高興了,說你這個(gè) RCS 也不科學(xué)呀赊琳,你每次都只能監(jiān)控單個(gè)文件街夭,老爺子你寫個(gè)論文什么的倒是還行,可是我們是要寫整個(gè)項(xiàng)目的呀躏筏,我項(xiàng)目中每個(gè)文件是有關(guān)聯(lián)的呀板丽,你這個(gè)單一文件監(jiān)控不好使呀。被 RCS 折磨了四年之后趁尼,程序員們終于忍不了了埃碱,不知是哪路豪杰在開源社區(qū)吼了一聲,一呼百應(yīng)酥泞,不一會(huì)兒(哪有那么快Q獾睢),新的 VCS 誕生了——Concurrent Versions System(A.K.A. CVS)芝囤。
CVS 不能不說是革命性的成果似炎,它不但支持了對(duì)整個(gè)項(xiàng)目進(jìn)行監(jiān)控辛萍,并且首次提出了倉庫(Repository)的概念,更加不能忍的是羡藐,它明確地分成了服務(wù)端和客戶端贩毕,把代碼倉庫放在服務(wù)器上,由客戶端向服務(wù)端提交修改仆嗦。這還是 1986 年啊同學(xué)們辉阶,我真想回滾到那個(gè)時(shí)候激動(dòng)地告訴他們:小伙子們(為什么是小伙子們……)你們發(fā)明的這種概念叫「云」你們?cè)靻幔俊冈啤乖诙嗄暌院笥卸嗷鹉銈冊(cè)靻幔?/p>
CVS 很好地支持了多用戶多文件并行操作瘩扼,按說這樣一來所有人應(yīng)該都滿意了吧谆甜?當(dāng)然不是,不然今天講的就是 CVS 而不是 Git 了集绰。它的問題是監(jiān)控的對(duì)象是文件规辱,而不是目錄。乍聽起來倒慧,覺得好像沒什么呀。其實(shí)不然包券,仔細(xì)想想纫谅,如果在項(xiàng)目目錄下再創(chuàng)建目錄,這個(gè)子目錄里面的文件并不會(huì)被監(jiān)控溅固;同理付秕,添加一個(gè)新文件,這個(gè)新文件也不會(huì)被監(jiān)控侍郭。
程序員們又不開心了询吴。
終于到了21世紀(jì),一個(gè)跨時(shí)代的 VCS 出現(xiàn)了—— Subversion(A.K.A. SVN)亮元。它由 CollabNet 公司開發(fā)猛计,并且在后來被納入了 Apache 軟件項(xiàng)目孵化器(Apache Incubator),成為其中 top-level 的產(chǎn)品爆捞。它不但支持監(jiān)控整個(gè)目錄奉瘤,而且首次支持了監(jiān)控非文本文件。這兩個(gè)特性使它在 2001 年在全球范圍內(nèi)取代了 CVS煮甥,并且一直流行到今天盗温。沒錯(cuò),現(xiàn)在許多軟件公司用的版本控制系統(tǒng)還是 SVN成肘。
咦卖局,說好的 Git 呢?
這就不得不提到同時(shí)代的另一款 CVS —— BitKeeper双霍。與 SVN 不同砚偶,它是一款商業(yè)軟件批销,但提供了免費(fèi)的社區(qū)版本(Community Version)。它最大的優(yōu)點(diǎn)在于蟹演,分布式管理风钻。在 SVN 中,服務(wù)端相當(dāng)于代碼中心酒请,所有的代碼都提交到這里骡技。它兩點(diǎn)不方便的地方在于,客戶端要不斷地和服務(wù)端進(jìn)行交互以保證自己的代碼是最新的羞反,如果自己從一個(gè)比較舊的版本開始修改布朦,就會(huì)出現(xiàn)問題。而且與服務(wù)端的交互要求網(wǎng)絡(luò)連接昼窗,不適合離線工作是趴。分布式管理的概念是每個(gè)倉庫都是主倉庫,當(dāng)兩個(gè)倉庫版本不一致時(shí)澄惊,可以方便地查看沖突之處并加以修改唆途。
使得 BitKeeper 如此出名的原因還在于,大名鼎鼎的 Linux Kernel 就存放在其免費(fèi)的社區(qū)版本上掸驱。
2005年4月肛搬,BitMover(擁有 BitKeeper 的那家公司)突然宣布,停止 BitKeeper 的社區(qū)版本毕贼,你們這群不想交錢就用我們軟件人都玩蛋去温赔!好嘛,改變了人類歷史的 Linux 就這樣無家可歸了鬼癣。
Linux 之父 Linus 看著自己的兒子被別人趕出了家門陶贼,憤怒值立刻飆升。他環(huán)繞四周看了看待秃,覺得 SVN 什么的簡直是屎拜秧,決不能允許親兒子流落至此。兩斤啤酒下肚章郁,他沖到電腦前三天三夜不眠不休腹纳。
Bang!Git 誕生了驱犹。
什么嘲恍?你說 BitKeeper ?玩蛋去吧雄驹。