讓我們來看一個(gè)簡(jiǎn)單的分支新建與分支合并的例子,實(shí)際工作中你可能會(huì)用到類似的工作流葡粒。 你將經(jīng)歷如下步驟:
1.開發(fā)某個(gè)網(wǎng)站看锉。
2.為實(shí)現(xiàn)某個(gè)新的需求,創(chuàng)建一個(gè)分支塔鳍。
3.在這個(gè)分支上開展工作伯铣。
正在此時(shí),你突然接到一個(gè)電話說有個(gè)很嚴(yán)重的問題需要緊急修補(bǔ)轮纫。 你將按照如下方式來處理:
1.切換到你的線上分支(production branch)腔寡。
2.為這個(gè)緊急任務(wù)新建一個(gè)分支,并在其中修復(fù)它掌唾。
3.在測(cè)試通過之后放前,切換回線上分支,然后合并這個(gè)修補(bǔ)分支糯彬,最后將改動(dòng)推送到線上分支凭语。
4.切換回你最初工作的分支上,繼續(xù)工作撩扒。
新建分支
首先似扔,我們假設(shè)你正在你的項(xiàng)目上工作,并且已經(jīng)有一些提交搓谆。
現(xiàn)在炒辉,你已經(jīng)決定要解決你的公司使用的問題追蹤系統(tǒng)中的 #53 問題。 想要新建一個(gè)分支并同時(shí)切換到那個(gè)分支上泉手,你可以運(yùn)行一個(gè)帶有 -b
參數(shù)的 git checkout
命令:
$ git checkout -b iss53
Switched to a new branch "iss53"
它是下面兩條命令的簡(jiǎn)寫:
$ git branch iss53
$ git checkout iss53
你繼續(xù)在 #53 問題上工作黔寇,并且做了一些提交。 在此過程中斩萌,iss53
分支在不斷的向前推進(jìn)缝裤,因?yàn)槟阋呀?jīng)檢出到該分支(也就是說,你的HEAD
指針指向了iss53
分支)
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
現(xiàn)在你接到那個(gè)電話颊郎,有個(gè)緊急問題等待你來解決憋飞。 有了 Git 的幫助,你不必把這個(gè)緊急問題和 iss53 的修改混在一起袭艺,你也不需要花大力氣來還原關(guān)于 53# 問題的修改搀崭,然后再添加關(guān)于這個(gè)緊急問題的修改叨粘,最后將這個(gè)修改提交到線上分支猾编。 你所要做的僅僅是切換回master
分支瘤睹。
但是,在你這么做之前答倡,要留意你的工作目錄和暫存區(qū)里那些還沒有被提交的修改轰传,它可能會(huì)和你即將檢出的分支產(chǎn)生沖突從而阻止 Git 切換到該分支。 最好的方法是瘪撇,在你切換分支之前获茬,保持好一個(gè)干凈的狀態(tài)。 有一些方法可以繞過這個(gè)問題(即倔既,保存進(jìn)度(stashing) 和 修補(bǔ)提交(commit amending))∷∏現(xiàn)在,我們假設(shè)你已經(jīng)把你的修改全部提交了渤涌,這時(shí)你可以切換回master
分支了:
$ git checkout master
Switched to branch 'master'
這個(gè)時(shí)候佩谣,你的工作目錄和你在開始 #53 問題之前一模一樣,現(xiàn)在你可以專心修復(fù)緊急問題了实蓬。 請(qǐng)牢記:當(dāng)你切換分支的時(shí)候茸俭,Git 會(huì)重置你的工作目錄,使其看起來像回到了你在那個(gè)分支上最后一次提交的樣子安皱。 Git 會(huì)自動(dòng)添加调鬓、刪除、修改文件以確保此時(shí)你的工作目錄和這個(gè)分支最后一次提交時(shí)的樣子一模一樣酌伊。
接下來腾窝,你要修復(fù)這個(gè)緊急問題。 讓我們建立一個(gè)針對(duì)該緊急問題的分支(hotfix branch)居砖,在該分支上工作直到問題解決:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
你可以運(yùn)行你的測(cè)試燕锥,確保你的修改是正確的,然后將其合并回你的 master 分支來部署到線上悯蝉。 你可以使用 git merge 命令來達(dá)到上述目的:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
在合并的時(shí)候归形,你應(yīng)該注意到了"快進(jìn)(fast-forward)"這個(gè)詞。 由于當(dāng)前master
分支所指向的提交是你當(dāng)前提交(有關(guān) hotfix 的提交)的直接上游鼻由,所以 Git 只是簡(jiǎn)單的將指針向前移動(dòng)暇榴。 換句話說,當(dāng)你試圖合并兩個(gè)分支時(shí)蕉世,如果順著一個(gè)分支走下去能夠到達(dá)另一個(gè)分支蔼紧,那么 Git 在合并兩者的時(shí)候,只會(huì)簡(jiǎn)單的將指針向前推進(jìn)(指針右移)狠轻,因?yàn)檫@種情況下的合并操作沒有需要解決的分歧——這就叫做 “快進(jìn)(fast-forward)”奸例。
現(xiàn)在,最新的修改已經(jīng)在master
分支所指向的提交快照中,你可以著手發(fā)布該修復(fù)了查吊。
關(guān)于這個(gè)緊急問題的解決方案發(fā)布之后谐区,你準(zhǔn)備回到被打斷之前時(shí)的工作中。 然而逻卖,你應(yīng)該先刪除hotfix
分支宋列,因?yàn)槟阋呀?jīng)不再需要它了 —— master
分支已經(jīng)指向了同一個(gè)位置。 你可以使用帶-d
選項(xiàng)的git branch
命令來刪除分支:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
現(xiàn)在你可以切換回你正在工作的分支繼續(xù)你的工作评也,也就是針對(duì) #53 問題的那個(gè)分支(iss53 分支)炼杖。
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
你在hotfix
分支上所做的工作并沒有包含到 iss53 分支中。 如果你需要拉取hotfix
所做的修改盗迟,你可以使用git merge master
命令將master
分支合并入 iss53 分支坤邪,或者你也可以等到 iss53 分支完成其使命,再將其合并回master
分支罚缕。
分支的合并
假設(shè)你已經(jīng)修正了 #53
問題罩扇,并且打算將你的工作合并入master
分支。 為此怕磨,你需要合并iss53
分支到 master
分支喂饥,這和之前你合并 hotfix
分支所做的工作差不多。 你只需要檢出到你想合并入的分支肠鲫,然后運(yùn)行 git merge
命令:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
這和你之前合并 hotfix 分支的時(shí)候看起來有一點(diǎn)不一樣员帮。 在這種情況下,你的開發(fā)歷史從一個(gè)更早的地方開始分叉開來(diverged)导饲。 因?yàn)槔谈撸琺aster 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些額外的工作渣锦。 出現(xiàn)這種情況的時(shí)候硝岗,Git 會(huì)使用兩個(gè)分支的末端所指的快照(C4 和 C5)以及這兩個(gè)分支的工作祖先(C2),做一個(gè)簡(jiǎn)單的三方合并袋毙。
和之間將分支指針向前推進(jìn)所不同的是型檀,Git 將此次三方合并的結(jié)果做了一個(gè)新的快照并且自動(dòng)創(chuàng)建一個(gè)新的提交指向它。 這個(gè)被稱作一次合并提交听盖,它的特別之處在于他有不止一個(gè)父提交胀溺。
需要指出的是,Git 會(huì)自行決定選取哪一個(gè)提交作為最優(yōu)的共同祖先皆看,并以此作為合并的基礎(chǔ)仓坞;這和更加古老的 CVS 系統(tǒng)或者 Subversion (1.5 版本之前)不同,在這些古老的版本管理系統(tǒng)中腰吟,用戶需要自己選擇最佳的合并基礎(chǔ)无埃。 Git 的這個(gè)優(yōu)勢(shì)使其在合并操作上比其他系統(tǒng)要簡(jiǎn)單很多。
既然你的修改已經(jīng)合并進(jìn)來了,你已經(jīng)不再需要 iss53 分支了嫉称。 現(xiàn)在你可以在任務(wù)追蹤系統(tǒng)中關(guān)閉此項(xiàng)任務(wù)侦镇,并刪除這個(gè)分支。
$ git branch -d iss53