當分支的任務告一段落時我們會想把分支合併到主幹道上。
或者反過來說,如果每個月有例行更新的日子,此時會由主幹道來合併想更新的分支項目,然後一起推上正式系統。
舉個實例,最近正在 A 分支新增一個功能,還沒寫完,但收到使用者緊急回報正式系統某功能有重大 bug 必須立刻修,
那我就會開個 B 分支來修這個 bug 修好後由主幹道合併 B 分支,然後將主幹道推上系統。
接著繼續開發我的新增功能,也就是回到 A 分支去寫程式。
等寫好測好都沒問題時再利用主幹道將 A 分支合併推上正式系統。
直接看操作:
# 確認現在有哪些分支與處在哪個分支
$ git branch
* master
test
# 切到 test 分支
$ git checkout test
Switched to branch 'test'
# 新增一個 ooqq.txt 檔案
$ touch ooqq.txt
# 在 ooqq.txt 加入一行字
$ echo '第一行' > ooqq.txt
# 看一下狀態
$ git status
On branch test
Untracked files:
(use "git add <file>..." to include in what will be committed)
ooqq.txt
nothing added to commit but untracked files present (use "git add" to track)
# 將工作目錄結果存到暫存區
$ git add .
# 從暫存區存到儲存庫
$ git commit -m '新增 ooqq.txt 並寫了一行字'
[test 40ff865] 新增 ooqq.txt 並寫了一行字
1 file changed, 1 insertion(+)
create mode 100644 ooqq.txt
# 查看檔案列表
$ ls
abc.txt hello.txt log.txt ooqq.txt test.py
# 查看 ooqq.txt 內容
$ cat ooqq.txt
第一行
# 假設任務完成,切到 master 合併分支
$ git checkout master
Switched to branch 'master'
# 還沒合併分支,所以沒有 ooqq.txt 檔案
$ ls
abc.txt hello.txt log.txt test.py
# 使用 merge 合併 test 分支
$ git merge test
Updating aa5f7ec..40ff865
Fast-forward
abc.txt | 1 +
hello.txt | 4 ----
ooqq.txt | 1 +
3 files changed, 2 insertions(+), 4 deletions(-)
create mode 100644 ooqq.txt
# 查看檔案列表
$ ls
abc.txt hello.txt log.txt ooqq.txt test.py
# 查看 ooqq.txt 內容
$ cat ooqq.txt
第一行
# 查看紀錄
$ git log -1
commit 40ff865ee973cbd18111bf45ab5d6fc3dc73ccd5 (HEAD -> master, test)
Author: Logo Kuo <logo@forblind.org.tw>
Date: Sun Mar 29 23:10:55 2020 +0800
新增 ooqq.txt 並寫了一行字
很順利完成了,因為之前在 test 分支還有做其他事情還沒合併,所以上面合併訊息可能大家會覺得奇怪,
明明增加一個檔案,為什麼是變成 3 個檔案有更動了。
那如果是改到相同的檔案再合併會怎樣,這次我們快一點,
我先在 master 主幹道裡的 ooqq.txt 新增第二行與第三行,提交後,
切到 test 分支把 ooqq.txt 第一行字改成「我是第一行」,提交後回到 master 準備合併,
我們只顯示合併的部分:
$ git merge test
Auto-merging ooqq.txt
CONFLICT (content): Merge conflict in ooqq.txt
Automatic merge failed; fix conflicts and then commit the result.
如果是沒有衝突的修改,就會自動合併,但當改到相同檔案且有衝突時就要開啟檔案來手動合併了。
上面的資訊跟你說, ooqq.txt 合併失敗,要用編輯器打開來手動合併一下。
# 顯示一下檔案內容
$ cat ooqq.txt
<<<<<<< HEAD
第一行
第二行
第三行
=======
我是第一行
>>>>>>> test
小於到等號那段是 master 目前 ooqq.txt 的內容
等號到大於是 test 分支的 ooqq.txt 內容
應該有看到大於後面寫的 test 分支吧。
這時候就看我們想要把檔案變怎樣,使用編輯器打開來改一改並存檔,
不要的符號記得都刪掉喔。
# 我們修改完後顯示一下 ooqq.txt 的檔案內容
$ cat ooqq.txt
我是第一行
第二行
第三行
# 改好後就提交囉
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: ooqq.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 有看到 both modified 關鍵字吧,就是我們合併了兩個分支的 ooqq.txt
$ git add .
$ git commit -m '將 ooqq.txt 改成我想要的'
[master f0230ed] 將 ooqq.txt 改成我想要的
# 看一下最近三筆的紀錄
$ git log -3
commit f0230ed91c295b0a34875cc037a094a566261543 (HEAD -> master)
Merge: 71188bf 6c5b3f7
Author: Logo Kuo <logo@forblind.org.tw>
Date: Sun Mar 29 23:41:43 2020 +0800
將 ooqq.txt 改成我想要的
commit 6c5b3f7f060c09a8ad5a07f1a3639524b8466512 (test)
Author: Logo Kuo <logo@forblind.org.tw>
Date: Sun Mar 29 23:27:06 2020 +0800
把 ooqq.txt 的第一行改成我是第一行
commit 71188bf29387da3a928d1747ed067cd042ca00fa
Author: Logo Kuo <logo@forblind.org.tw>
Date: Sun Mar 29 23:25:34 2020 +0800
在 ooqq.txt 新增第二與三行
沒錯,原本在 test 的提交也都來了,目前 ooqq.txt 的內容兩邊是不同的,
master 是我們合併好的,而分支 test 是原本 test 的內容,log 也是一樣。
那合併好了後,test 分支需不需要刪掉,就看個人囉,我有時會繼續在上面做另外的開發,
有時就會把已被合併的分支砍掉再另外開一個新的出來。
另外,誰合併誰的過程不一樣,但結果是相同的。
如果 B 與 C 分支都是由 A 分出來的,
那從 A 去合併 B 或從 A 去合併 C 像我們剛剛那樣,會啟用快轉模式,也就是 Fast Forward
剛剛在合併時應該有看到這個關鍵字,這種合併會比較順利,
反之,想用 B 合併 C 或 C 合併 B 就會很有可能發生衝突,
畢竟他們兩個已經各自有不同的天空了,合併起來比較費力點,但方法是一樣的。
此時會產生一個合併的 commit 來處理這個合併,通常會跳出 git 預設編輯器的視窗讓你輸入 commit 內容,
通常可以總結一下這次合併增加了哪些功能,因為光看一個個 commit 可能會太細節,
如果不寫也沒事,他會自己有個合併的系統 commit 資訊。
合併好了,對分支來說,合併別人的 HEAD 會往前,被合併的還停留在原地,就像上述 master 與 test 那樣,
master 的 HEAD 往前走了,test 還在原地。
最後,在 merge 時加入 --no-ff
參數就一定會強制產生 commit 來紀錄合併。
也就是不使用快轉模式,結果上沒什麼差別,就看自己的著眼點在哪裡了。