1. 程式人生 > >深入理解和實踐git merge.md

深入理解和實踐git merge.md

1.git merge的簡單理解

看下git merge的命令:

git merge hotfix

例如當前的分支是master,那麼這條命令的意思就是,將hofix分支的的修改同步到master分支。

2. git merge 的兩種實質操作過程

2.1 結果為“快進”的git merge

我們看一下操作過程:

master分支的指標位於C2的節點,現在master出現了問題,我們從master上切出一個分支命名為hotfix。hotfix分支指標指向新的節點C4.如下圖
在這裡插入圖片描述

中間執行的命令:

git checkout master
git checkout -b hotfix 
vim .... # fixed bug
git commit -a -m 'fixed bug'

經過測試之後hotfix已經解決了bug,現在要將hotfix的修改合併到master:

$ git checkout master
$ git merge hotfix 
Updating f42c576..3a0874c
Fast-forward...

在這裡插入圖片描述

注意這個詞“fast-forward(快進)”。由於當前 master 分支所指向的提交是當前提交(有關 hotfix 的提交)的直接上游,所以 Git 只是簡單的將指標向前移動。也就是說當你試圖合併兩個分支時,如果順著一個分支走下去能夠到達另一個分支,那麼 Git 在合併兩者的時候,只會簡單的將指標向前推進(指標右移),因為這種情況下的合併操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。

現在你可以把hotfix分支刪掉了git branch -d hotfix。

2.2 結果為“合併提交”的merge

在hotfix之前,還一直存一個問題,我們建了一個分支命名為iss53。iss53從C2(之前的master指向的快照)切出,提交了兩個commit。現在iss53問題已經解決,需要將這部分的修改合併回master分支。
在這裡插入圖片描述

執行如下指令:
$ git checkout master
$ git merge iss53
Merge made by the ‘recursive’ strategy…

這種方式和“快進”不同,因為開發歷史從一個更早的地方開始分叉開來(diverged)。master 分支所在提交併不是 iss53 分支所在提交的直接祖先。這時Git 會使用兩個分支的末端所指的快照(C4 和 C5)以及這兩個分支的工作祖先(C2),做一個簡單的三方合併。Git 將此次三方合併的結果做了一個新的快照並且自動建立一個新的提交指向它。 這個被稱作一次合併提交,它的特別之處在於他有不止一個父提交。
在這裡插入圖片描述

3.合併時遇到衝突

如果你在兩個不同的分支中,對同一個檔案的同一個部分進行了不同的修改,Git 就沒法乾淨的合併它們。 如果你對 #53 問題的修改和有關 hotfix 的修改都涉及到同一個檔案的同一處,在合併它們的時候就會產生合併衝突。

不要害怕。此時 Git 做了合併,但是沒有自動地建立一個新的合併提交。 Git 會暫停下來,等待你去解決合併產生的衝突。你只需要解決衝突即可。衝突標識很明顯,git會用“<<<<<<<” 和“=======”將衝突包裹。

解決衝突之後,可以使用git status檢視當前的狀態:

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

這時你可以使用 git commit 來完成合並提交。

通過本篇我們加深了對一個知識點的理解——git在進行一些重要操作時,會產生新檔案(其中一些是為快照),分支只是一個指標,指向快照。

注:本篇參考Git官方文件-分支的新建與合併