Git 分支 - 分支的新建與合并

分支的新建與合并

讓我們來看一個簡單的分支新建與分支合并的例子止毕,實際工作中你可能會用到類似的工作流尝盼。

你將經(jīng)歷如下步驟:

開發(fā)某個網(wǎng)站吞滞。

為實現(xiàn)某個新的需求,創(chuàng)建一個分支盾沫。

在這個分支上開展工作裁赠。

正在此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補赴精。

你將按照如下方式來處理:

切換到你的線上分支(production branch)佩捞。

為這個緊急任務新建一個分支,并在其中修復它蕾哟。

在測試通過之后一忱,切換回線上分支莲蜘,然后合并這個修補分支,最后將改動推送到線上分支帘营。

切換回你最初工作的分支上票渠,繼續(xù)工作。

新建分支

首先芬迄,我們假設你正在你的項目上工作庄新,并且已經(jīng)有一些提交。

Figure 18. 一個簡單提交歷史

現(xiàn)在薯鼠,你已經(jīng)決定要解決你的公司使用的問題追蹤系統(tǒng)中的 #53 問題择诈。想要新建一個分支并同時切換到那個分支上,你可以運行一個帶有-b參數(shù)的git checkout命令:

$ git checkout -b iss53

Switched to a new branch "iss53"

它是下面兩條命令的簡寫:

$ git branch iss53

$ git checkout iss53

Figure 19. 創(chuàng)建一個新分支指針

你繼續(xù)在 #53 問題上工作出皇,并且做了一些提交羞芍。在此過程中,iss53分支在不斷的向前推進郊艘,因為你已經(jīng)檢出到該分支(也就是說荷科,你的HEAD指針指向了iss53分支)

$ vim index.html

$ git commit -a -m 'added a new footer [issue 53]'

Figure 20. iss53 分支隨著工作的進展向前推進

現(xiàn)在你接到那個電話,有個緊急問題等待你來解決纱注。有了 Git 的幫助畏浆,你不必把這個緊急問題和iss53的修改混在一起,你也不需要花大力氣來還原關(guān)于 53# 問題的修改狞贱,然后再添加關(guān)于這個緊急問題的修改刻获,最后將這個修改提交到線上分支。你所要做的僅僅是切換回master分支瞎嬉。

但是蝎毡,在你這么做之前,要留意你的工作目錄和暫存區(qū)里那些還沒有被提交的修改氧枣,它可能會和你即將檢出的分支產(chǎn)生沖突從而阻止 Git 切換到該分支沐兵。最好的方法是,在你切換分支之前便监,保持好一個干凈的狀態(tài)扎谎。有一些方法可以繞過這個問題(即,保存進度(stashing) 和 修補提交(commit amending))烧董,我們會在儲藏與清理中看到關(guān)于這兩個命令的介紹』侔校現(xiàn)在,我們假設你已經(jīng)把你的修改全部提交了解藻,這時你可以切換回master分支了:

$ git checkout master

Switched to branch 'master'

這個時候老充,你的工作目錄和你在開始 #53 問題之前一模一樣葡盗,現(xiàn)在你可以專心修復緊急問題了螟左。

請牢記:當你切換分支的時候啡浊,Git 會重置你的工作目錄,使其看起來像回到了你在那個分支上最后一次提交的樣子胶背。

Git 會自動添加巷嚣、刪除、修改文件以確保此時你的工作目錄和這個分支最后一次提交時的樣子一模一樣钳吟。

接下來廷粒,你要修復這個緊急問題。

讓我們建立一個針對該緊急問題的分支(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(+)

Figure 21. 基于master分支的緊急問題分支hotfix branch

你可以運行你的測試坝茎,確保你的修改是正確的,然后將其合并回你的master分支來部署到線上暇番。你可以使用git merge命令來達到上述目的:

$ git checkout master

$ git merge hotfix

Updating f42c576..3a0874c

Fast-forward

index.html | 2 ++

1 file changed, 2 insertions(+)

在合并的時候嗤放,你應該注意到了"快進(fast-forward)"這個詞。由于當前master分支所指向的提交是你當前提交(有關(guān) hotfix 的提交)的直接上游壁酬,所以 Git 只是簡單的將指針向前移動次酌。換句話說,當你試圖合并兩個分支時舆乔,如果順著一個分支走下去能夠到達另一個分支岳服,那么 Git 在合并兩者的時候,只會簡單的將指針向前推進(指針右移)希俩,因為這種情況下的合并操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”吊宋。

現(xiàn)在,最新的修改已經(jīng)在master分支所指向的提交快照中颜武,你可以著手發(fā)布該修復了贫母。

Figure 22.master被快進到hotfix

關(guān)于這個緊急問題的解決方案發(fā)布之后,你準備回到被打斷之前時的工作中盒刚。然而腺劣,你應該先刪除hotfix分支,因為你已經(jīng)不再需要它了 ——master分支已經(jīng)指向了同一個位置因块。你可以使用帶-d選項的git branch命令來刪除分支:

$ git branch -d hotfix

Deleted branch hotfix (3a0874c).

現(xiàn)在你可以切換回你正在工作的分支繼續(xù)你的工作橘原,也就是針對 #53 問題的那個分支(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(+)

Figure 23. 繼續(xù)在iss53分支上的工作

你在hotfix分支上所做的工作并沒有包含到iss53分支中涡上。如果你需要拉取hotfix所做的修改趾断,你可以使用git merge master命令將master分支合并入iss53分支,或者你也可以等到iss53分支完成其使命吩愧,再將其合并回master分支芋酌。

分支的合并

假設你已經(jīng)修正了 #53 問題,并且打算將你的工作合并入master分支雁佳。為此脐帝,你需要合并iss53分支到master分支同云,這和之前你合并hotfix分支所做的工作差不多。你只需要檢出到你想合并入的分支堵腹,然后運行g(shù)it 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分支的時候看起來有一點不一樣炸站。在這種情況下,你的開發(fā)歷史從一個更早的地方開始分叉開來(diverged)疚顷。因為旱易,master分支所在提交并不是iss53分支所在提交的直接祖先,Git 不得不做一些額外的工作腿堤。出現(xiàn)這種情況的時候阀坏,Git 會使用兩個分支的末端所指的快照(C4和C5)以及這兩個分支的工作祖先(C2),做一個簡單的三方合并笆檀。

Figure 24. 一次典型合并中所用到的三個快照

和之前將分支指針向前推進所不同的是全释,Git 將此次三方合并的結(jié)果做了一個新的快照并且自動創(chuàng)建一個新的提交指向它。

這個被稱作一次合并提交误债,它的特別之處在于他有不止一個父提交浸船。

Figure 25. 一個合并提交

需要指出的是,Git 會自行決定選取哪一個提交作為最優(yōu)的共同祖先寝蹈,并以此作為合并的基礎李命;這和更加古老的 CVS 系統(tǒng)或者 Subversion (1.5 版本之前)不同,在這些古老的版本管理系統(tǒng)中箫老,用戶需要自己選擇最佳的合并基礎封字。

Git 的這個優(yōu)勢使其在合并操作上比其他系統(tǒng)要簡單很多。

既然你的修改已經(jīng)合并進來了耍鬓,你已經(jīng)不再需要iss53分支了±眩現(xiàn)在你可以在任務追蹤系統(tǒng)中關(guān)閉此項任務,并刪除這個分支牲蜀。

$ git branch -d iss53

遇到?jīng)_突時的分支合并

有時候合并操作不會如此順利笆制。如果你在兩個不同的分支中,對同一個文件的同一個部分進行了不同的修改涣达,Git 就沒法干凈的合并它們在辆。如果你對 #53 問題的修改和有關(guān)hotfix的修改都涉及到同一個文件的同一處,在合并它們的時候就會產(chǎn)生合并沖突:

$ git merge iss53

Auto-merging index.html

CONFLICT (content): Merge conflict in index.html

Automatic merge failed; fix conflicts and then commit the result.

此時 Git 做了合并度苔,但是沒有自動地創(chuàng)建一個新的合并提交匆篓。Git 會暫停下來,等待你去解決合并產(chǎn)生的沖突寇窑。你可以在合并沖突后的任意時刻使用git status命令來查看那些因包含合并沖突而處于未合并(unmerged)狀態(tài)的文件:

$ git status

On branch master

You have unmerged paths.

(fix conflicts and run "git commit")

Unmerged paths:

(use "git add ..." to mark resolution)

both modified:? ? ? index.html

no changes added to commit (use "git add" and/or "git commit -a")

任何因包含合并沖突而有待解決的文件鸦概,都會以未合并狀態(tài)標識出來。

Git 會在有沖突的文件中加入標準的沖突解決標記甩骏,這樣你可以打開這些包含沖突的文件然后手動解決沖突窗市。

出現(xiàn)沖突的文件會包含一些特殊區(qū)段先慷,看起來像下面這個樣子:

<<<<<<< HEAD:index.html

contact : email.support@github.com

=======

please contact us at support@github.com

>>>>>>> iss53:index.html

這表示HEAD所指示的版本(也就是你的master分支所在的位置,因為你在運行 merge 命令的時候已經(jīng)檢出到了這個分支)在這個區(qū)段的上半部分(=======的上半部分)谨设,而iss53分支所指示的版本在=======的下半部分。為了解決沖突缎浇,你必須選擇使用由=======分割的兩部分中的一個扎拣,或者你也可以自行合并這些內(nèi)容。例如素跺,你可以通過把這段內(nèi)容換成下面的樣子來解決沖突:

please contact us at email.support@github.com

上述的沖突解決方案僅保留了其中一個分支的修改二蓝,并且<<<<<<<,=======, 和>>>>>>>這些行被完全刪除了。在你解決了所有文件里的沖突之后指厌,對每個文件使用git add命令來將其標記為沖突已解決刊愚。一旦暫存這些原本有沖突的文件,Git 就會將它們標記為沖突已解決踩验。

如果你想使用圖形化工具來解決沖突鸥诽,你可以運行g(shù)it mergetool,該命令會為你啟動一個合適的可視化合并工具箕憾,并帶領你一步一步解決這些沖突:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.

See 'git mergetool --tool-help' or 'git help config' for more details.

'git mergetool' will now attempt to use one of the following tools:

opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge

Merging:

index.html

Normal merge conflict for 'index.html':

{local}: modified file

{remote}: modified file

Hit return to start merge resolution tool (opendiff):

如果你想使用除默認工具(在這里 Git 使用opendiff做為默認的合并工具牡借,因為作者在 Mac 上運行該程序)外的其他合并工具,你可以在 “下列工具中(one of the following tools)” 這句后面看到所有支持的合并工具袭异。然后輸入你喜歡的工具名字就可以了钠龙。

Note

如果你需要更加高級的工具來解決復雜的合并沖突,我們會在高級合并介紹更多關(guān)于分支合并的內(nèi)容御铃。

等你退出合并工具之后碴里,Git 會詢問剛才的合并是否成功。如果你回答是上真,Git 會暫存那些文件以表明沖突已解決:你可以再次運行g(shù)it status來確認所有的合并沖突都已被解決:

$ git status

On branch master

All conflicts fixed but you are still merging.

(use "git commit" to conclude merge)

Changes to be committed:

modified:? index.html

如果你對結(jié)果感到滿意咬腋,并且確定之前有沖突的的文件都已經(jīng)暫存了,這時你可以輸入git commit來完成合并提交睡互。默認情況下提交信息看起來像下面這個樣子:

Merge branch 'iss53'

Conflicts:

index.html

#

# It looks like you may be committing a merge.

# If this is not correct, please remove the file

# .git/MERGE_HEAD

# and try again.

# Please enter the commit message for your changes. Lines starting

# with '#' will be ignored, and an empty message aborts the commit.

# On branch master

# All conflicts fixed but you are still merging.

#

# Changes to be committed:

# modified:? index.html

#

如果你覺得上述的信息不夠充分帝火,不能完全體現(xiàn)分支合并的過程,你可以修改上述信息湃缎,添加一些細節(jié)給未來檢視這個合并的讀者一些幫助犀填,告訴他們你是如何解決合并沖突的,以及理由是什么嗓违。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末九巡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蹂季,更是在濱河造成了極大的恐慌冕广,老刑警劉巖疏日,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撒汉,居然都是意外死亡沟优,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門睬辐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挠阁,“玉大人,你說我怎么就攤上這事溯饵∏炙祝” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵丰刊,是天一觀的道長隘谣。 經(jīng)常有香客問我,道長啄巧,這世上最難降的妖魔是什么寻歧? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮秩仆,結(jié)果婚禮上熄求,老公的妹妹穿的比我還像新娘。我一直安慰自己逗概,他們只是感情好弟晚,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逾苫,像睡著了一般卿城。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上铅搓,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天瑟押,我揣著相機與錄音,去河邊找鬼星掰。 笑死多望,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的氢烘。 我是一名探鬼主播怀偷,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼播玖!你這毒婦竟也來了椎工?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎维蒙,沒想到半個月后掰吕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡颅痊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年殖熟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斑响。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡菱属,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恋捆,到底是詐尸還是另有隱情照皆,我是刑警寧澤重绷,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布沸停,位于F島的核電站,受9級特大地震影響昭卓,放射性物質(zhì)發(fā)生泄漏愤钾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一候醒、第九天 我趴在偏房一處隱蔽的房頂上張望能颁。 院中可真熱鬧,春花似錦倒淫、人聲如沸伙菊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镜硕。三九已至,卻和暖如春返干,著一層夾襖步出監(jiān)牢的瞬間兴枯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工矩欠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留财剖,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓癌淮,卻偏偏與公主長得像躺坟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乳蓄,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容