天天看點

Git:合并分支----git merge指令應用的三種情景

Git:合并分支----git merge指令應用的三種情景

版權聲明:本文為CSDN部落客「Samven_7」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/qq_42780289/article/details/97945300

文章目錄

一、git merge 指令應用的三種情景

1.1 “快進”(無沖突)

1.2 非“快進”,修改不同檔案。(無沖突)

1.3 非“快進”,修改相同檔案。(有沖突)

master分支

假設現在隻有一個預設的 master 分支,并送出了3次,B0、B1和B2都是送出對象。

首先要清楚,每次産生的送出對象會包含一個指向上次送出對象(父對象)的指針,是以圖中B0、B1和B2之間的箭頭是指針指向父對象的意思,真正的送出順序還是B0到B1再到B2。同時 master 指針指向最新的送出B2。

另外Git中還有一個名為 HEAD 的特殊指針,它是一個指針,指向目前所在的本地分支(可以将 HEAD想象為目前分支的别名)。

dev新分支

現在建立一個分支并切換到新分支。

$ git checkout -b dev

Switched to a new branch 'dev'

1

2

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

$ git branch dev

$ git checkout dev

因為是在B2建立 dev,是以新分支 dev 指向B2。另外從分支 master 切換到分支 dev,是以HEAD指向目前分支 dev。

在 dev 分支工作并送出了2次:

合并dev和master

在分支 dev 的工作結束,切換到分支 master ,然後把 dev 合并到 master 上:

$ git checkout master

Switched to branch 'master'

$ git merge dev

Merge made by the 'recursive' strategy.

test-2.txt | 3 ++-

1 file changed, 2 insertions(+), 1 deletion(-)

3

4

5

6

由于目前 master 分支所指向的送出是你目前送出(dev的送出)的直接上遊,是以 Git 隻是簡單的将 master 指針向前移動。 換句話說,當你試圖合并兩個分支時,如果順着一個分支走下去能夠到達另一個分支,那麼 Git 在合并兩者的時候,隻會簡單的将指針向前推進(指針右移),因為這種情況下的合并操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。合并結果如下:

最後,你可以删除 dev 分支,因為你已經不再需要它了 —— master 分支已經指向了同一個位置。 你可以使用帶 -d 選項的 git branch 指令來删除分支:

$ git branch -d dev

當在新分支 dev 進行了一次送出B3,再回到分支 master 又進行一次送出 B4。

這裡用 git merge 合并分為兩種情況,現在講第一種情況:

在 master 分支和 dev 分支的公共祖先 B2 後,master 和 dev 的送出是對不同檔案或者同一檔案的不同部分進行了修改,Git 可以合并它們。(比如說原來有 test-1 和 test-2 兩個檔案,B4修改的是 test-1 檔案,而B3修改的是 test-2 檔案,然後合并兩個分支。)

合并是成功的。

出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(B3 和 B4)以及這兩個分支的公共祖先(B2),做一個簡單的三方合并。注意這裡合并後 master 自動 commit 送出了一次,産生了送出B5。而B5中的結果是三方合并的結果。合并結果如下:

最後,合并完成,你已經不再需要dev分支了。 現在你可以删除這個分支。

上面講的是第一種情況,現在講第二種情況:

在 master 分支和 dev 分支的公共祖先 B2 後,master 和 dev 的送出是對同一個檔案的同一個部分進行了不同的修改,Git 就沒法幹淨的合并它們。(比如說原來有 test-1 和 test-2 兩個檔案,B4修改的是 test-1 檔案,而B3修改的也是 test-1 檔案的同一部分,然後合并兩個分支。)

Auto-merging test-1.txt

CONFLICT (content): Merge conflict in test-1.txt

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

合并是失敗的。

此時 Git 做了合并,但是沒有自動地建立一個新的合并送出。 Git 會暫停下來,等待你去解決合并産生的沖突。 你可以在合并沖突後的任意時刻使用 git status 指令來檢視那些因包含合并沖突而處于未合并(unmerged)狀态的檔案:

$ 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: test-1.txt

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

7

8

9

10

11

12

任何因包含合并沖突而有待解決的檔案,都會以未合并狀态辨別出來。 Git 會在有沖突的檔案中加入标準的沖突解決标記,這樣你可以打開這些包含沖突的檔案然後手動解決沖突。 出現沖突的檔案會包含一些特殊區段,看起來像下面這個樣子:

This is test-1.

update test-1.

add test-1.

<<<<<<< HEAD

test master.

=======

test dev.

>>>>>>> dev

這裡 HEAD 表示所訓示的版本(也就是你的 master 分支所在的位置,因為你在運作 merge 指令的時候已經檢出到了這個分支)在這個區段的上半部分(======= 的上半部分),而 dev 分支所訓示的版本在 ======= 的下半部分。 為了解決沖突,你必須選擇使用由 ======= 分割的兩部分中的一個,或者你也可以自行合并這些内容。 例如,你可以通過把這段内容換成下面的樣子來解決沖突:

然後手動送出:

$ git add .

$ git commit -m "connection"

[master f7daa6b] connection

然後沖突就解決了。合并結果如下: