合併分支- 為你自己學Git | 高見龍 - gitbook.tw

文章推薦指數: 80 %
投票人數:10人

git checkout master Switched to branch 'master'. 接下來,要合併分支是使用 git merge 指令:. $ git merge cat Updating 35c42e..f17acb Fast-forward cat1.html ... 讓您精通業界最常用Git版本控制!Git線上直播課程熱烈報名中現在就報名!學員評價 為你自己學Git 目錄 勘誤表 電子書 單元劇 面試題 系列文章 練習場 關於我 ←上一章:對分支的誤解 下一章:【狀況題】為什麼我的分支都沒有「小耳朵」?→ 合併分支 在前面章節的例子中,我從master分支開了一個cat分支,並且做了兩次Commit,現在看起來的樣子大概像這樣: 任務執行的差不多了,就要準備合併回來了。

如果我想要master分支來合併cat分支的話,我會先切回master分支: $gitcheckoutmaster Switchedtobranch'master' 接下來,要合併分支是使用gitmerge指令: $gitmergecat Updating35c42e..f17acb Fast-forward cat1.html|0 cat2.html|0 2fileschanged,0insertions(+),0deletions(-) createmode100644cat1.html createmode100644cat2.html 看一下檔案列表: $ls-al total16 drwxr-xr-x9eddiewheel306Aug1805:14. drwxrwxrwt84rootwheel2856Aug1804:29.. drwxr-xr-x16eddiewheel544Aug1805:15.git -rw-r--r--1eddiewheel0Aug1805:14cat1.html -rw-r--r--1eddiewheel0Aug1805:14cat2.html drwxr-xr-x3eddiewheel102Aug1715:06config -rw-r--r--1eddiewheel0Aug1803:27hello.html -rw-r--r--1eddiewheel161Aug1804:24index.html -rw-r--r--1eddiewheel11Aug1714:56welcome.html 在cat分支新增的cat1.html跟cat2.html,因為master現在已經合併cat分支,所以現在在master分支也有一份了。

回到SourceTree看一下目前的狀況: 從左邊的「BRANCHES」選單看得出來現在正處於master分支,同時從右方的Commit紀錄也看得出來cat分支現在領先master分支2個Commit: 如果要合併cat分支,在分支上按滑鼠右鍵,選擇「Mergecatintomaster」: 它會跳出一個對話框,點擊OK按鈕便可完成合併。

這時候再看一下右邊的Commit紀錄: 本來落後2個Commit的master分支,在進行合併之後,進度也已經跟上cat分支,跟它在同一個Commit上。

至於已經合併的分支要不要留下來?請見「【常見問題】合併過的分支要留著嗎?」章節說明。

A合併B,跟B合併A有什麼不同? 這個問題在我一開始學Git的時候也曾經困擾過我好一陣子,到底誰合併誰有那麼重要嗎?這就要看你著眼的重點是什麼了。

如果以最終結果來看是一樣的,但過程可能會有些差別。

我先各別從master分支做出了cat跟dog這兩個分支,並且現在正在cat分支: cat跟dog這兩個分支都是來自master分支,可以想像成是「cat分支跟dog分支啊,你們身上都流著我master的血…」的意思,所以如果是master不管是要合併cat或是dog分支,Git會直接使用快轉模式(FastForward)進行合併,說得白一點就是master直接「收割」cat或dog的成果了。

但如果是cat跟dog這兩個分支要互相合併就不一樣了,雖然它們有同樣的來源,但各自長大之後要合併就不會這麼順利了(想想看要你把你的家產跟你哥哥或姐姐的家產合併在一起…)。

在這個情況下,Git會產生一個額外的Commit來處理這件事。

一般的Commit只會指向某一個Commit,但這個Commit會指向二個Commit,明確的標記是來自哪兩個分支,親兄弟也是要明算帳啊! 來看看會怎麼演變。

假設我想用cat分支來合併dog分支: $gitmergedog Mergemadebythe'recursive'strategy. dog1.html|0 dog2.html|0 2fileschanged,0insertions(+),0deletions(-) createmode100644dog1.html createmode100644dog2.html 執行這個指令的時候會跳出一個Vim編輯器視窗,如果忘記Vim怎麼操作,請再回顧一下「超精簡Vim操作介紹」章節。

為了要進行這次的合併,Git做出了這個額外的Commit物件,這個Commit會分別指向cat跟dog這兩個分支,HEAD隨著cat分支往前,而dog分支停留在原地: 如果用SourceTree來看會像這樣: 如果改由dog分支來合併cat分支: $gitmergecat Mergemadebythe'recursive'strategy. cat1.html|0 cat2.html|0 2fileschanged,0insertions(+),0deletions(-) createmode100644cat1.html createmode100644cat2.html 流程上跟剛才幾乎是一樣的。

這時候的狀態會變成這樣: 如果用SourceTree來看會像這樣: 哪裡不一樣? 你有看出哪裡不一樣嗎?其實就以結果來看,不管是誰合併誰,這兩個分支的檔案最後都拿到了。

你可能看SourceTree的畫面,會認為誰合併誰會有誰在前面、誰在後面的差別,但事實上並不是這樣,那只是因為軟體沒辦法畫出來「平行」的效果而已。

事實上不管誰合併誰,這兩個分支上的Commit都是對等的。

硬是要說哪裡不一樣,就是cat分支合併dog分支的時候,cat分支會往前移動,反之亦然。

不過前面曾經提到分支就像貼紙一樣,隨時要刪掉或改名都不會影響現在已經存在的Commit。

有啦,真的不一樣的還有一點,就是這個為了合併而產生的這個額外的Commit物件,裡面會記錄兩個老爸是誰,誰合併誰就會有「誰放前面」的差別,不過這可能就有點太過細節了。

這是cat分支合併dog分支,所以cat分支b174a5a95a放前面: 這是dog分支合併cat分支,所以dog分支053fb212bb放前面: 這很重要嗎?國外曾經有一個Ruby跟Python一起合辦的研討會名字叫做RuPy(後來已改名成PolyConf),那為什麼Ruby要放前面?Python的人可能會想為什麼不叫PyRu?這大概就跟A合併B跟A合併B的差別差不多吧。

←上一章:對分支的誤解 下一章:【狀況題】為什麼我的分支都沒有「小耳朵」?→ Comments



請為這篇文章評分?