[教學] git-20 合併分支 - 討論區

[教學] git-20 合併分支

文章瀏覽次數 815 文章回覆數 0

特種兵

特種兵圖像(預設)

2020-03-30 09:33:13

From:211.23.21.202

當分支的任務告一段落時我們會想把分支合併到主幹道上。

或者反過來說,如果每個月有例行更新的日子,此時會由主幹道來合併想更新的分支項目,然後一起推上正式系統。

舉個實例,最近正在 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 來紀錄合併。

也就是不使用快轉模式,結果上沒什麼差別,就看自己的著眼點在哪裡了。