9 - 合併

git容許兩個開發人員在任什麼時候候合併修改,這一切並不須要一箇中央倉庫。一個合併會結合兩個或者多個歷史提交分支。儘管git支持同時合併三個、四個或者多個分支,但大多數狀況下,一次合併只結合兩個分支。git

git中的合併,必須發生在一個版本庫中,就是所要進行的合併必須在一個版本庫中。code

當一個分支的修改和另外一個分支的修改不發生衝突的時候,git會計算合併結果,並建立一個新的提交來表明統一的狀態。當分支衝突時,git並不解決衝突,衝突一般出如今對同一個文件的同一行進行修改的時候。git會把這種有爭議的修改在索引中標記爲未合併(unmerged),留給開發人員處理。索引

9.1 - 合併的例子

爲了把other_branch合併到branch中,應該檢出branch,並把other_branch分支合併到branch中。以下所示:開發

$ git checkout branch
$ git merge other_branch

9.1.1 - 沒有衝突的合併

下面的例子,建立一個只有一個文件的版本庫,而後建立兩個分支,再把這兩個分支合併在一塊兒。it

$ git init
Initialized empty Git repository in /Users/iEpac/Documents/git/merge_test/.git/

$ git config user.email 'iepac4srv@163.com'
$ git config user.name 'jEpac'
$ cat > file
Line 1 stuff
Line 2 stuff
Line 3 stuff

$ git add file 
$ git commit -m "init 3 line file"
[master (root-commit) f391dda] init 3 line file
 1 file changed, 3 insertions(+)
 create mode 100644 file

在master分支上建立另外一個提交:io

$ cat > other_file
here is stuff on another file

$ git add other_file 
$ git commit -m "another file"
[master 5cb5fea] another file
 1 file changed, 1 insertion(+)
 create mode 100644 other_file

到如今爲止,版本庫中已經有了兩個提交的master分支,每次提交都建立了一個新文件。而後,切換到另個分支,修改第一個文件:ast

$ git checkout -b alternate master^
Switched to a new branch 'alternate'

$ git branch
* alternate
  master
$ git show-branch
* [alternate] init 3 line file
 ! [master] another file
--
 + [master] another file
*+ [alternate] init 3 line file

alternate分支是從master^分支派生來的。接下來,對文件作一些修改以便有內容來合併。test

$ cat >> file
init 4 alternate stuff

$ git add file 
$ git commit -m 'add alternate`s line 4'
[alternate 3985336] add alternate`s line 4
 1 file changed, 1 insertion(+)

如今已經有了兩個分支,master和alternate,每一個分支都有不一樣的開發工做:email

  1. master分支提交了file和other_file
  2. alternate分支對other_file作了修改

注意:git merge是區分上下文的。file

  • 當前分支始終是目標分支
  • 其餘分支始終是合併到當前分支

因此,alternate分支應該合併到mater分支中。因此,在合併前必需要切到master分支上。

$ git checkout master
Switched to branch 'master'
$ git show-branch
! [alternate] add alternate`s line 4
 * [master] another file
--
+  [alternate] add alternate`s line 4
 * [master] another file
+* [alternate^] init 3 line file

$ git status
On branch master
nothing to commit, working directory clean
$ git merge alternate
Merge made by the 'recursive' strategy.
 file | 1 +
 1 file changed, 1 insertion(+)

$ git ls-files
file
other_file

$ git show-branch
! [alternate] add alternate`s line 4
 * [master] Merge branch 'alternate'
--
 - [master] Merge branch 'alternate'
+* [alternate] add alternate`s line 4

可使用提交圖看一下:

$ git log --graph --pretty=oneline --abbrev-commit
*   37b02aa Merge branch 'alternate'
|\  
| * 3985336 add alternate`s line 4
* | 5cb5fea another file
|/  
* f391dda init 3 line file
  • 兩個分支在f391dda提交處分開
  • 每一個分支顯示一個提交,5cb5fea3985336
  • 兩個分支在37b02aa處合併

9.1.2 - 有衝突的合併

$ git merge alternate
自動合併 file
衝突(內容):合併衝突於 file
自動合併失敗,修正衝忽然後提交修正的結果

當合並出現衝突的時候, 首先要使用git diff查看文件的衝突程度

# git diff file
diff --cc file
index 39b21ea,a892d57..0000000
--- a/file
+++ b/file
@@@ -2,5 -2,5 +2,10 @@@ line 1 stuf
  line 2 stuff
  line 3 stuff
  line 4 alternate stuff
++<<<<<<< HEAD
 +line 5 stuff
 +line 6 stuff
++=======
+ line 5 alternate stuff
+ line 6 alternate stuff
++>>>>>>> alternate
  • <<<<和=====之間的:改變的內容
  • ====和>>>>>之間的:替代的內容

這時候須要手動解決衝突, 而後git add git commit。從新提交修改過的版本。

9.2 - 處理合並衝突

有衝突的修改不能自動合併

9.2.1 - 定位衝突的文件

git會對有問題的文件進行追蹤,並在索引中把他們標記爲衝突的(conflicted)或者未合併(unmerged)的。使用以下命令來查看工做目錄中仍然未合併的一組文件

git status
git ls-files -u

9.2.2 - 檢查衝突

移除衝突標記,而後執行git add和git commit. 下面是git提供的解決衝突。

對衝突使用git diff

有衝突的文件合併後, 工做目錄中的這個文件內容被修改成衝突後的合併內容,並有衝突標識.

對衝突使用git log命令

git log --merge --left-right -p

不要對有衝突標記的文件執行git add命令, 這會清除索引中的衝突並容許提交, 可是文件是錯誤的

9.3 - 合併策略

相關文章
相關標籤/搜索