git是每個(gè)程序員必備的工具之一妙痹,但對(duì)于他們來說,git的學(xué)習(xí)過程并不輕松鼻疮,主要原因是因?yàn)樗容^晦澀難懂怯伊,即便你去查找git的定義,也不一定能理解這貨有什么用判沟?為什么所有程序員都會(huì)使用它耿芹?下面是git在wikipedia中的解釋:
git(GNU Interactive Tools)是一個(gè)分布式版本控制軟件崭篡。
小白第一次讀到這個(gè)解釋時(shí),心里肯定在想:能說點(diǎn)人話嗎猩系?什么是GNU媚送?什么是版本控制軟件?于是為了照顧初學(xué)者的情緒寇甸,很多人對(duì)git的解釋給出了很好的類比塘偎,例如:
git就像小叮當(dāng)?shù)臅r(shí)光機(jī),它能幫你把代碼恢復(fù)到過去的任意一個(gè)時(shí)刻拿霉。
這個(gè)解釋很形象吟秩,因?yàn)樗腥硕贾佬《.?dāng)?shù)臅r(shí)光機(jī)是什么,這樣一下子就和初學(xué)者拉近了距離绽淘,在眾多類比中涵防,我認(rèn)為最好的一個(gè)是:
git是你在玩游戲時(shí)的存檔,當(dāng)你game over時(shí)沪铭,你不需要重新開始壮池,就可以接著上一次存檔的地方繼續(xù)。
存檔是游戲通關(guān)中的重要手段杀怠,它能極大的提升游戲的樂趣性椰憋,因?yàn)闆]有人愿意一遍又一遍的從零開始,寫代碼也一樣赔退,如果你對(duì)當(dāng)前的代碼不滿意橙依,又不想手動(dòng)恢復(fù)一個(gè)個(gè)源文件,更不想重來一遍硕旗,那么最好的辦法是窗骑,通過git回退到上一次滿意的地方。這個(gè)功能對(duì)新手也是極為重要的漆枚,因?yàn)樾率忠M(jìn)bug的可能性極大创译,同時(shí)他們沒有很好的解決bug的能力,這時(shí)對(duì)他們來說最有效的方法可能就是恢復(fù)到上一個(gè)正常的狀態(tài)墙基,然后一點(diǎn)點(diǎn)的敲入新代碼昔榴,看自己是從哪個(gè)地方把bug引進(jìn)來的。所以碘橘,從這個(gè)角度來說,
git是程序員在高空作業(yè)下的防護(hù)網(wǎng)吱肌。
讀完以上文字痘拆,你應(yīng)該是對(duì)git有了一定的了解,但如果你回過頭再來查看一下git的定義氮墨,你會(huì)發(fā)現(xiàn)git應(yīng)該還有其他功能纺蛆,沒錯(cuò)吐葵,從interactive這個(gè)詞來說,git是具備多人協(xié)作的功能的桥氏,這其實(shí)也是git的眾多功能中最重要的温峭。
在過去,公司里共享文件時(shí)字支,經(jīng)常會(huì)搭建一個(gè)smb服務(wù)器凤藏,然后把文件放在這個(gè)服務(wù)器上,所有的同事都可以訪問這些文件堕伪,并且可以基于這些文件進(jìn)行修改揖庄,如果共享的是word文件,還可以通過word的修訂功能蚌成,查看誰(shuí)庇茫,在什么時(shí)間论熙,修改了哪些內(nèi)容,但這僅限于word文件禁炒,對(duì)于程序這種極其復(fù)雜的工程管理,smb顯然是無能為力霍比。
為此幕袱,程序員便開發(fā)出了CVS和SVN兩種版本控制系統(tǒng),它提供了很多便利于工程管理的特性桂塞,例如保存了文件的差異性凹蜂,可以為不同的版本創(chuàng)建不同的分支,可以為提交打上標(biāo)簽阁危,下面簡(jiǎn)單說下這幾個(gè)概念
- 保存了文件的差異性 - 只要納入到版本管理系統(tǒng)中的文件玛痊,任何變更都會(huì)被記錄下來,方便維護(hù)狂打,例如可以通過該功能查看某個(gè)開發(fā)者修改了哪些內(nèi)容——這被稱作code review擂煞,他是否引入了新bug
-
分支(branch) - 還是為了工程管理,在開發(fā)過程中趴乡,我們一般會(huì)為軟件創(chuàng)建兩個(gè)不同的版本:開發(fā)版和穩(wěn)定版对省,這兩個(gè)版本在版本管理系統(tǒng)中對(duì)應(yīng)著兩個(gè)不同的分支,更一般的晾捏,穩(wěn)定版是由開發(fā)版合并而來的蒿涎。下圖可以很好的說明這兩個(gè)分支間的關(guān)系
-
標(biāo)簽(tag) - 通過分支管理還不夠,標(biāo)簽的作用是為了讓已發(fā)布的軟件更為直觀惦辛,同時(shí)幫助團(tuán)隊(duì)使用統(tǒng)一的語(yǔ)言進(jìn)行溝通劳秋。例如,項(xiàng)目經(jīng)理需要確認(rèn)某次bugfix要合并到哪個(gè)版本,或除了開發(fā)以外玻淑,測(cè)試同學(xué)也需要知道運(yùn)行在生產(chǎn)環(huán)境中的版本號(hào)嗽冒,以便在對(duì)應(yīng)的版本上提交bug。這往往需要借助標(biāo)簽的功能补履,標(biāo)簽其實(shí)是將某一次提交和一個(gè)具體的版本號(hào)關(guān)聯(lián)在一起的功能添坊,雖然很簡(jiǎn)單,但它極大的促進(jìn)了團(tuán)隊(duì)間的溝通箫锤,因?yàn)樯婕暗巾?xiàng)目的所有人都可以基于版本號(hào)進(jìn)行交流了贬蛙。下圖在branch的基礎(chǔ)上,增加了tag功能
既然CVS和SVN已經(jīng)可以進(jìn)行滿足工程管理的需要麻汰,那為什么還會(huì)有g(shù)it呢速客?git是由Linux之父Linus Torvalds開發(fā)的,最初被用來管理Linux內(nèi)核五鲫,因?yàn)長(zhǎng)inux內(nèi)核的代碼量非常龐大溺职,它對(duì)版本管理軟件的性能要求很高,又因?yàn)楸局_源精神位喂,這套內(nèi)核代碼需要使用一款開源軟件來管理浪耘,而現(xiàn)成的CVS和SVN方案,由于架構(gòu)和性能欠佳不符合要求塑崖,所以Linus便親自花了十天的時(shí)間七冲,寫出了git的第一個(gè)版本。
git的性能極佳體現(xiàn)在它是一個(gè)分布式的系統(tǒng)规婆,每一個(gè)節(jié)點(diǎn)都是一個(gè)完整的代碼倉(cāng)庫(kù)澜躺,這和最近火熱的比特幣有點(diǎn)類似——每個(gè)節(jié)點(diǎn)都保存了一個(gè)完整的賬本。在我看來抒蚜,速度快體現(xiàn)在兩個(gè)方面:
- 幾乎所有操作都是本地操作
- 分支創(chuàng)建非常輕量
先說第1點(diǎn)掘鄙,由于每個(gè)節(jié)點(diǎn)都是一個(gè)完整的代碼倉(cāng)庫(kù),所以可以做到很多操作都在本地進(jìn)行嗡髓,也即可以在本地進(jìn)行“存檔”和“回退”操作操漠,甚至都不需要聯(lián)網(wǎng),你只用在必要的時(shí)候?qū)⒈镜卮a上傳到遠(yuǎn)程倉(cāng)庫(kù)饿这。操作快速和可以隨時(shí)“存檔”極大的提升了程序員的開發(fā)體驗(yàn)浊伙。
除了可以隨時(shí)“存檔”外,開發(fā)者還可以任性的創(chuàng)建分支长捧,這是我們要說的第2點(diǎn)嚣鄙,因?yàn)間it創(chuàng)建一個(gè)分支非常快串结,它不會(huì)做任何的文件復(fù)制操作拗慨,只會(huì)在已有分支的基礎(chǔ)上廓八,新建一個(gè)“分支名”,除此之外赵抢,git不會(huì)像其他版本管理系統(tǒng)一樣,將文件和改動(dòng)分開來管理声功,而是直接管理文件的快照烦却,對(duì)快照的管理會(huì)減少CPU的計(jì)算量,進(jìn)一步提升了分支的操作速度先巴。
由于分支的創(chuàng)建其爵、切換和刪除都非常迅速和輕量,開發(fā)者便可以在任意改動(dòng)前伸蚯,先創(chuàng)建一個(gè)分支摩渺,在新的分支上修改完畢后,再合并到主分支上剂邮,目前我所在的團(tuán)隊(duì)就是這樣的開發(fā)模式摇幻,同時(shí)這也是github的開發(fā)模式。下圖是這種模式的一個(gè)示例:
總結(jié)挥萌,以上簡(jiǎn)要的介紹了git是什么绰姻,git被用來解決什么問題,它在項(xiàng)目管理中的首要作用引瀑,以及它和其他版本管理系統(tǒng)的區(qū)別及優(yōu)勢(shì)狂芋,git是一個(gè)非常強(qiáng)大的軟件,它不僅可以解決開發(fā)過程中的問題憨栽,即便對(duì)于非開發(fā)者帜矾,你也可以使用git和其他人共同協(xié)作,甚至屑柔,你還可以用git來寫書屡萤。所以,不管是否是程序員锯蛀,學(xué)一下git還是很有必要的灭衷。
下一篇我會(huì)介紹一下項(xiàng)目協(xié)同中,git工作流的使用旁涤。