### 理解分支
一開始的時候,`master`分支是一條線,Git用`master`指向最新的提交,再用`HEAD`指向`master`,就能確定當前分支,以及當前分支的提交點:

每次提交,`master`分支都會向前移動一步,這樣,隨著你不斷提交,`master`分支的線也越來越長。
當我們創建新的分支,例如`dev`時,Git新建了一個指針叫`dev`,指向`master`相同的提交,再把`HEAD`指向`dev`,就表示當前分支在`dev`上:

你看,Git創建一個分支很快,因為除了增加一個`dev`指針,改改`HEAD`的指向,工作區的文件都沒有任何變化!
不過,從現在開始,對工作區的修改和提交就是針對`dev`分支了,比如新提交一次后,`dev`指針往前移動一步,而`master`指針不變:

假如我們在`dev`上的工作完成了,就可以把`dev`合并到`master`上。Git怎么合并呢?最簡單的方法,就是直接把`master`指向`dev`的當前提交,就完成了合并:

所以Git合并分支也很快!就改改指針,工作區內容也不變!
合并完分支后,甚至可以刪除`dev`分支。刪除`dev`分支就是把`dev`指針給刪掉,刪掉后,我們就剩下了一條`master`分支:

真是太神奇了,你看得出來有些提交是通過分支完成的嗎?
### 分支命令
* 查看分支:`git branch`
* 創建分支:`git branch <name>`
* 切換分支:`git checkout <name>`
* 創建+切換分支:`git checkout -b <name>`
* 合并某分支到當前分支:`git merge <name>`
* 刪除分支:`git branch -d <name>`
### 沖突處理
準備新的`feature1`分支,繼續我們的新分支開發:
~~~
$ git checkout -b feature1
Switched to a new branch 'feature1'
~~~
修改`readme.txt`最后一行,改為:
~~~
Creating a new branch is quick AND simple.
~~~
在`feature1`分支上提交:
~~~
$ git add readme.txt
$ git commit -m "AND simple"
[feature1 14096d0] AND simple
1 file changed, 1 insertion(+), 1 deletion(-)
~~~
切換到`master`分支:
~~~
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
~~~
Git還會自動提示我們當前`master`分支比遠程的`master`分支要超前1個提交。
在`master`分支上把`readme.txt`文件的最后一行改為:
~~~
Creating a new branch is quick & simple.
~~~
提交:
~~~
$ git add readme.txt
$ git commit -m "& simple"
[master 5dc6824] & simple
1 file changed, 1 insertion(+), 1 deletion(-)
~~~
現在,`master`分支和`feature1`分支各自都分別有新的提交,變成了這樣:

這種情況下,Git無法執行“快速合并”,只能試圖把各自的修改合并起來,但這種合并就可能會有沖突,我們試試看:
~~~
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
~~~
果然沖突了!Git告訴我們,`readme.txt`文件存在沖突,必須手動解決沖突后再提交。`git status`也可以告訴我們沖突的文件:
~~~
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
~~~
我們可以直接查看readme.txt的內容:
~~~
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
~~~
Git用`<<<<<<<`,`=======`,`>>>>>>>`標記出不同分支的內容,我們修改如下后保存:
~~~
Creating a new branch is quick and simple.
~~~
再提交:
~~~
$ git add readme.txt
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed
~~~
現在,`master`分支和`feature1`分支變成了下圖所示:

### 不使用fast forward 模式合并分支
通常,合并分支時,如果可能,Git會用`Fast forward`模式,但這種模式下,刪除分支后,會丟掉分支信息。
如果要強制禁用`Fast forward`模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
下面我們實戰一下`--no-ff`方式的`git merge`:
首先,仍然創建并切換`dev`分支:
~~~
$ git checkout -b dev
Switched to a new branch 'dev'
~~~
修改readme.txt文件,并提交一個新的commit:
~~~
$ git add readme.txt
$ git commit -m "add merge"
[dev f52c633] add merge
1 file changed, 1 insertion(+)
~~~
現在,我們切換回`master`:
~~~
$ git checkout master
Switched to branch 'master'
~~~
準備合并`dev`分支,請注意`--no-ff`參數,表示禁用`Fast forward`:
~~~
$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
~~~
因為本次合并要創建一個新的commit,所以加上`-m`參數,把commit描述寫進去。
合并后,我們用`git log`看看分支歷史:
~~~
$ git log --graph --pretty=oneline --abbrev-commit
* e1e9c68 (HEAD -> master) merge with no-ff
|\
| * f52c633 (dev) add merge
|/
* cf810e4 conflict fixed
...
~~~
可以看到,不使用`Fast forward`模式,merge后就像這樣:
