GIT 分支管理:建立與合併分支、解決合併衝突

分支就是科幻電影裏面的平行宇宙,當你正在電腦前努力學習Git的時候,另外一個你正在另外一個平行宇宙裏努力學習SVN。git

若是兩個平行宇宙互不干擾,那對如今的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合併了,結果,你既學會了Git又學會了SVN!安全

分支在實際中有什麼用呢?假設你準備開發一個新功能,可是須要兩週才能完成,第一週你寫了50%的代碼,若是馬上提交,因爲代碼還沒寫完,不完整的代碼庫會致使別人不能幹活了。若是等代碼所有寫完再一次提交,又存在丟失天天進度的巨大風險。學習

如今有了分支,就不用怕了。你建立了一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工做。spa

其餘版本控制系統如SVN等都有分支管理,可是用過以後你會發現,這些版本控制系統建立和切換分支比蝸牛還慢,簡直讓人沒法忍受,結果分支功能成了擺設,你們都不去用。3d

但Git的分支是不同凡響的,不管建立、切換和刪除分支,Git在1秒鐘以內就能完成!不管你的版本庫是1個文件仍是1萬個文件。版本控制

建立與合併分支

在版本回退裏,你已經知道,每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git裏,這個分支叫主分支,即master分支。HEAD嚴格來講不是指向提交,而是指向mastermaster纔是指向提交的,因此,HEAD指向的就是當前分支。指針

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

每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也愈來愈長:blog

當咱們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:three

你看,Git建立一個分支很快,由於除了增長一個dev指針,改改HEAD的指向,工做區的文件都沒有任何變化!

不過,從如今開始,對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變:

假如咱們在dev上的工做完成了,就能夠把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併:

因此Git合併分支也很快!就改改指針,工做區內容也不變!

合併完分支後,甚至能夠刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,咱們就剩下了一條master分支:

真是太神奇了,你看得出來有些提交是經過分支完成的嗎?

下面開始實戰。

首先,咱們建立dev分支,而後切換到dev分支:

$ git checkout -b dev Switched to a new branch 'dev'

git checkout命令加上-b參數表示建立並切換,至關於如下兩條命令:

$ git branch dev $ git checkout dev Switched to branch 'dev'

而後,用git branch命令查看當前分支:

$ git branch * dev master

git branch命令會列出全部分支,當前分支前面會標一個*號。

而後,咱們就能夠在dev分支上正常提交,好比對readme.txt作個修改,加上一行:

create new branch dev..

而後提交:

$ git add readme.txt $ git commit -m "create new branch...." [dev 45ae9a9] create new branch.... 1 file changed, 1 insertion(+)

如今,dev分支的工做完成,咱們就能夠切換回master分支:

$ git checkout master Switched to branch 'master' Your branch is up-to-date with 'origin/master'.

切換回master分支後,再查看一個readme.txt文件,剛纔添加的內容不見了!由於那個提交是在dev分支上,而master分支此刻的提交點並無變:

如今,咱們把dev分支的工做成果合併到master分支上:

$ git merge dev Updating 90bc1f7..45ae9a9 Fast-forward readme.txt | 1 +
 1 file changed, 1 insertion(+)

git merge命令用於合併指定分支到當前分支。合併後,再查看readme.txt的內容,就能夠看到,和dev分支的最新提交是徹底同樣的。

注意到上面的Fast-forward信息,Git告訴咱們,此次合併是「快進模式」,也就是直接把master指向dev的當前提交,因此合併速度很是快。

固然,也不是每次合併都能Fast-forward,咱們後面會講其餘方式的合併。

合併完成後,就能夠放心地刪除dev分支了:

$ git branch -d dev Deleted branch dev (was 45ae9a9).

刪除後,查看branch,就只剩下master分支了:

$ git branch * master

由於建立、合併和刪除分支很是快,因此Git鼓勵你使用分支完成某個任務,合併後再刪掉分支,這和直接在master分支上工做效果是同樣的,但過程更安全。

小結

Git鼓勵大量使用分支:

查看分支: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最後一行,改成:

create new branch feature1..

 

feature1分支上提交:

$ git add readme.txt $ git commit -m "create new branch feature1 first modify" [feature1 b4309b0] create new branch feature1 first modify 1 file changed, 1 insertion(+)

切換到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文件的最後一行改成:

goback master....

提交:

$ git add readme.txt $ git commit -m "goback master first modify" [master 0b56936] goback master first modify 1 file changed, 1 insertion(+)

如今,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") 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的內容:

test git modify second study git three add four add modify five add modify six add modify seven add modify eight add modify ... create new branch dev.. <<<<<<< HEAD goback master.... ======= create new branch feature1.. >>>>>>> feature1

Git用<<<<<<<=======>>>>>>>標記出不一樣分支的內容,咱們修改以下後保存:

test git modify second
study git
three add
four add modify
five add modify
six add modify
seven add modify
eight add modify ...
create new branch dev..
create new branch feature1..
goback master....

再提交:

$ git add readme.txt $ git commit -m "fixed conflicts" [master 0f3d64a] fixed conflicts

如今,master分支和feature1分支變成了下圖所示:

用帶參數的git log也能夠看到分支的合併狀況:

$ git log --graph --pretty=oneline --abbrev-commit * 0f3d64a fixed conflicts |\ | * b4309b0 create new branch feature1 first modify * | 0b56936 goback master first modify |/
* 45ae9a9 create new branch.... * 90bc1f7 test name * c1bdf43 test commit * dd34c9a no add but commit,because use other parameter * 4ed30d1 eight modify dify * b45ca96 eight modify * 9332d40 seven modify * 72c6f9b six modify * f64b5a0 five modify * de8fd65 four modify * 83a4b1e three modify * 01c05cf two modify * 1acafa7 first modify * 09c1bba first git

最後,刪除feature1分支:

$ git branch -d feature1 Deleted branch feature1 (was b4309b0).

小結

當Git沒法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。

git log --graph命令能夠看到分支合併圖。

相關文章
相關標籤/搜索