一個(gè)故事帶你了解版本控制
本文轉(zhuǎn)載自微信公眾號(hào)「 武培軒」,作者 武培軒 。轉(zhuǎn)載本文請(qǐng)聯(lián)系 武培軒公眾號(hào)。
當(dāng)我們初次在項(xiàng)目中使用版本控制時(shí),這個(gè)概念可能難以理解。我看到很多人(也包括我)都在運(yùn)行諸如 git pull,git push 以及運(yùn)行其他一些我不理解的命令。為什么我既要 commit 還要 push?為什么每個(gè)新特性都需要新建一個(gè)分支?
在使用 Git 進(jìn)行協(xié)同工作幾個(gè)月后,對(duì)于版本控制這個(gè)概念就比較清晰了,可以更好地理解和使用版本控制來(lái)進(jìn)行協(xié)作。下面通過(guò)一個(gè)小故事來(lái)說(shuō)明版本控制的工作方式及其在項(xiàng)目中的優(yōu)勢(shì)吧!
一起蓋房子吧
在這個(gè)美好的合作項(xiàng)目中,我們將嘗試一起蓋房子。簡(jiǎn)單點(diǎn)說(shuō),我們只有兩個(gè)人在這棟房子里工作。我們不是房子的主人,我們?yōu)閯e人(利益相關(guān)者)處理房子的內(nèi)容,他告訴我們他想要什么,想要在哪里。
我們有 4 面墻—主(Master)分支
我們從 4 面墻和屋頂開始,這是堅(jiān)固的,耐久且非常好的,這四堵墻代表我們的 Master 分支,它們目前已經(jīng)實(shí)施,并且不會(huì)被刪除。利益相關(guān)者批準(zhǔn)了這四堵墻,他甚至可能親自選擇了它們,并且希望保留它們。我們需要做的就是改善這四堵墻,在上面或周圍建造。無(wú)論如何,我們要建造的任何東西都將以這四堵墻為基礎(chǔ)。
業(yè)主想要一間客廳和一間廚房-特性(Feature)分支
正如我之前提到的,有兩個(gè)人在做這個(gè)項(xiàng)目,我和另外一個(gè)同事張三。每個(gè)房間都是一個(gè)特性,在這種情況下,為了使結(jié)果最大化,我和張三將研究不同的特性,我將設(shè)計(jì)客廳,張三將設(shè)計(jì)廚房,到目前為止一切都很順利。
我們都創(chuàng)建了一個(gè)特性分支,我們還知道必須使用約定來(lái)命名我們的分支,因此,我們將以正在處理的工作(在本例中,是一個(gè)新特性)、該特性的名稱和我們的名字。
- feature-living_room-wupx
- feature-kitchen-zhangs
命名分支有多種約定,這只是其中一個(gè)建議。
我們都從主分支創(chuàng)建特性分支,所以我們一開始都有相同的四面墻,然而,我們的特性分支完全是主分支的獨(dú)立副本,對(duì)主分支的內(nèi)容沒有直接影響,這就保證了如果我和張三完全破壞了四面墻其中的一個(gè),主分支的四面墻仍然是站立的。
我想將設(shè)計(jì)保存在本地—git commit
提交就像將更改保存在本地,每一次新的提交都有一個(gè)數(shù)字,也代表了你可以返回的保存點(diǎn),就像在任務(wù)游戲中你可以返回到之前的保存點(diǎn)一樣,所以當(dāng)張三建造櫥柜的時(shí)候,他可以提交它們以保證他的更改不會(huì)丟失,并且如果他建造的下一個(gè)部分危及到櫥柜的質(zhì)量,他還可以回滾回去。因此,當(dāng)Bob建造廚柜時(shí),他可以提交它們,以免丟失更改,并承諾如果他制造的下一部分會(huì)危害廚柜的質(zhì)量。
每次提交還需要一條消息,因?yàn)閷懸恍╆P(guān)于你的提交的內(nèi)容以便讓每個(gè)人都知道這個(gè)“保存點(diǎn)”包括什么是一個(gè)很好的實(shí)踐,張三提交的消息寫道“創(chuàng)建紅色廚房櫥柜”。
我想將設(shè)計(jì)保存在存儲(chǔ)庫(kù)中的安全位置—git push
存儲(chǔ)庫(kù)是存儲(chǔ)所有分支的地方,包括主分支,它就像一個(gè)文件夾,里面有關(guān)于項(xiàng)目的所有文件,包括它們的修訂歷史。
Git push 獲取你的所有提交并將它們發(fā)送到分支的遠(yuǎn)程版本,該版本可以在在線存儲(chǔ)庫(kù)中獲得,所有參與其中的的開發(fā)人員都可以看到對(duì)分支所做的更改。因此,張三將他的提交推到他的遠(yuǎn)程分支,我現(xiàn)在可以看到張三關(guān)于紅色櫥柜的提交。
我的客廳裝修好了,現(xiàn)在怎么辦呢?-開發(fā)分支和合并(merge)請(qǐng)求
我們的開發(fā)分支是一個(gè)集成我們的房間(或功能)的地方,在這里,我們嘗試把我們的設(shè)計(jì)(或功能)結(jié)合在一起,看看我們的客廳和廚房的功能是否很好地結(jié)合在一起。
如果我想把我的客廳添加到開發(fā)分支,我必須做一個(gè)合并請(qǐng)求(pull request),通常,在遠(yuǎn)程分支上發(fā)生合并之前,至少必須有一個(gè)其他開發(fā)人員批準(zhǔn)你的合并請(qǐng)求。
張三的廚房做完了,我們的設(shè)計(jì)不匹配—合并沖突(Merge conflicts)
我試圖將張三的新變更合并到我的分支中,但是如果我沒有把張三的開放式廚房一側(cè)的墻砌好,會(huì)發(fā)生什么呢?我們的設(shè)計(jì)存在沖突,Git 可以自動(dòng)解決一些沖突,但不能解決所有沖突,Git 有時(shí)需要你的幫助來(lái)確定應(yīng)該保留哪些更改,因?yàn)槠渲幸恍└氖窍嗷_突的。換句話說(shuō),它需要知道保留誰(shuí)的“設(shè)計(jì)”(或代碼)是正確的選擇。
假設(shè)我是犯錯(cuò)的人,我可以告訴 Git 在設(shè)計(jì)廚房墻壁時(shí)保留Bob的部分,而不是我的。
我們什么時(shí)候可以把廚房和客廳加到主分支?
項(xiàng)目的這一部分通常包括測(cè)試、批準(zhǔn),一旦我們的設(shè)計(jì)經(jīng)過(guò)了全面的測(cè)試,這意味著它們也能很好地一起工作,并且我們的利益相關(guān)者,房屋所有者批準(zhǔn)了這些設(shè)計(jì),我們就可以決定將我們的更改合并到主分支,這意味著從現(xiàn)在開始,我們房子的穩(wěn)定版也將包括我們的客廳和廚房,因此所有的新分支至少應(yīng)該包括這些房間。
在某些情況下,明智的方法可能是將主分支以前的每個(gè)版本都保存在不同的分支中,然而,處理主分支的正確方法取決于你的團(tuán)隊(duì)和公司的需求或準(zhǔn)則。
總之,版本控制是簡(jiǎn)單和安全協(xié)作的核心
在團(tuán)隊(duì)項(xiàng)目中使用 Git 允許多個(gè)開發(fā)人員獨(dú)立地處理同一個(gè)項(xiàng)目,而不會(huì)經(jīng)常干擾彼此的輸入。每個(gè)開發(fā)人員都可以獲得一個(gè)獨(dú)立的代碼版本,他們可以修改這個(gè)版本,而不必承擔(dān)破壞穩(wěn)定版本代碼的風(fēng)險(xiǎn)。
Git 能夠復(fù)制代碼并在不同版本上獨(dú)立工作,這使它成為構(gòu)建應(yīng)用程序的任何人(甚至是單獨(dú)工作的開發(fā)人員)的一個(gè)很好的選擇,它使您有機(jī)會(huì)保留代碼的多個(gè)版本,并跟蹤每個(gè)更改的所有特征,比如誰(shuí)做了更改以及何時(shí)做的更改。