Git系列筆記之四:分支管理

分支是什麼呢?
html

團隊開發的過程當中,每一個人都會有一個不一樣於別人的分支,各自都在本身的分支上編寫代碼,等到須要的時候,再把各分支合併起來,這樣既安全也不會相互影響。
git

1、建立與合併分支

在上一節中,咱們在本地建立了一個Git倉庫,但只有一個分支,就是 master 分支,它是主分支,HEAD指向 mastermaster指向當前提交,因此,HEAD指向的就是當前分支。github

每次提交,master都會向前移動一步,隨着不斷的提交,這條分支線會愈來愈長
安全

當咱們建立了新的分支,好比叫 myBranch ,git就會新建一個指針叫 myBranch,指向 master 相同的提交,在把HEAD指向 myBranch,就表示當前分支在 myBranch 上。
app


從如今開始,對工做區的修改和提交都是針對 myBranch 分支了,若是咱們修改後再提交一次,myBranch指針就會向前移動一步,而master指針不變測試


當咱們在myBranch分支上的工做完成後,就能夠把myBranch合併到master,也就是把master指針移動到myBranch的當前提交。spa

當合並完成後,咱們就能夠刪除掉myBranch分支,也就是把myBranch指針刪除掉,而後咱們就只剩下master分支了.net

OK,咱們如今經過實際的例子來講明上面分支的使用。咱們先看看當前分支:指針

$ git branch        //查看分支


能夠看到,目前咱們只有一個master主分支,咱們來建立一個bra分支:code

$ git checkout -b bra


git checkout 命令加上-b參數,表示建立分支並切換,它至關於下面的兩個命令:

$ git branch dev        //建立分支
$ git checkout dev      //切換到建立的分支

咱們再次查看下當前分支狀況

咱們能夠看到有兩個分支,分別是master和bra,當前在bra分支上。

git branch命令會列出全部分支,當前分支前面會標註一個 * 號,如今咱們在bra分支上對index.html作一些修改

保存退出後,咱們進行提交

如今咱們在bra分支上的工做完成,切換到master分支:

$ git checkout master

咱們發現,剛纔添加的第三個P標籤不見了,這是由於剛纔的提交時在bra分支上,而master分支此刻的提交點沒有變化



如今咱們可使用 git merge 命令來將bra分支上的更改合併到master分支上:

$ git merge bra

而後咱們再次查看index.html的內容

OK,在bra分支上添加的第三個P標籤回來了,而當前咱們是在master主分支上。你們可能注意到了在咱們合併時,出現了 'Fast-forward',它告訴咱們此次合併是'快進模式',也就是將master指針直接指向bra分支的提交,因此速度很快,固然除了這種模式,還有其餘模式。

合併完成後,咱們就能夠刪除bra分支了

$ git branch -d bra

而後咱們再次查看分支狀況:

如今只剩下master分支了。GIT鼓勵咱們使用分支來進行開發,下面咱們來總結下上面使用過的命令:

查看分支: git branch

建立分支: git branch "branch name"

切換分支: git checkout "branch name"

建立並切換分支: git checkout -b "branch name"

合併某分支到當前分支: git merge "branch name"

刪除分支: git branch -d "branch name"


2、 解決衝突

有時候咱們在進行分支合併時,會遇到各類各樣的問題,下面咱們用實例來講明下。

咱們先建立一個新的分支fea,在這個分支上對index.html再添加一個p標籤,而後在這個分支上提交。

$ git checkout -b fea    //建立並切換到fea分支
//對index.html作出修改
$ git add index.html    //提交
$ git commit -m "modifyed and commit on fea branch"

切換到master分支上

$ git checkout master


上面的代碼還提示咱們當前的master分支比遠程的master還要多2個提交,可使用 git push 命令推送本地的提交

接下來,咱們在master分支上對index.html作出修改,並提交修改

如今,master分支和fea分支都有了各自的提交

這個時候,git是沒法進行快速合併的,只能把各自的修改合併起來,但這種合併可能會形成衝突。下面咱們嘗試着合併一下

看到了嗎? Automatic merge failed,合併失敗了。git告訴咱們文件有衝突,必須手動解決,咱們用 git status 來看下,也提示有問題

查看文件內容,也有提示

咱們進入index.html進行修改,保存退出後,提交。

最後,咱們刪除fea分支

當git沒法自動合併分支時,就必須手動去解決問題,再進行合併。咱們還可使用 git log --graph 來查看分支合併圖


3、分支管理

上面咱們瞭解了合併分支,git會使用 Fast forward 模式,在這種模式下合併,刪除分支後,會丟失分支信息,因此咱們強制禁用 Fast forward模式,在合併分支的時候使用 --on--ff

如今咱們新建並切換到dev分支上

修改index.html文件並提交

切換到master分支

OK,關鍵在這裏,咱們合併dev分支, 使用--no--ff參數,表示禁用 Fast forward

$ git merge --no-ff -m "merge with no-ff" dev

合併後,咱們使用git log 查看分支歷史

在實際的開發中,master分支是主分支,是很是穩定的,僅僅只能用來發布新的版本,平時不能在它上面工做。

在一個項目開始的時候,咱們能夠在git上新建一個dev分支,那麼若是團隊有3我的,分別是A,B,C,那麼他們都分別會有本身的分支,你們都在本身的分支上幹活,完成以後都提交到dev分支上,但這是不穩定的,通過屢次的測試,發現bug,修改,再次合併到dev分支,通過不少次的迭代,版本穩定了,OK,如今能夠把dev分支合併到master上進行發佈了。


4、BUG分支

咱們在工做時會遇到各類各樣的BUG,有時候,有些bug須要馬上修復,可是你手上的任務尚未完成,怎麼辦?這時,Git爲咱們提供了 stash 功能,它能夠將咱們當前分支上的任務存儲起來,放在另一個地方,咱們就能夠放心的切換到有bug的分支去進行修復。

當前有以下的情景,我在dev分支上工做,寫了一些代碼,但並無提交

這時,有任務來了,須要去Fix一個編號爲88的bug,咱們能夠在master分支上建立一個臨時的分支來修復這個bug,OK,咱們利用 stash 功能將當前的工做保存起來。

咱們在利用 status 來查看下當前工做區狀態

咱們看到當前在dev分支上,並且工做區是乾淨的,而剛剛咱們在dev分支上作的工做並無提交。

好了,咱們如今須要去master分支上建立一個fix88分支來修復bug,先切換到master分支

建立fix88分支來修復bug

咱們進入index.html修復bug,並提交

切換到master分支,合併修改,並刪除fix88分支

修復bug後的index.html內容以下,咱們在最後一個p標籤裏,把原來的內容加上了一個span標籤,並添加了另一個span標籤,插入了一些說明的內容。

而後咱們再來看看當前的分支狀態和工做區狀態

切換到咱們原來的工做分支dev上,並查看工做區狀態

工做區是乾淨的,下面咱們使用 git stash list 命令來查看下剛剛咱們隱藏的工做場景

OK,咱們來恢復咱們在dev分支上的工做場景 ,這裏有兩個方法能夠來恢復

一是使用 git stash apply,這個方法恢復以後,並不會刪除stash裏的內容,還須要使用 git stash drop來刪除 stash裏的內容

二是使用 git stash pop ,這個方法恢復以後,會直接刪除stash裏的內容

能夠看到工做場景恢復了,咱們再來看看stash裏的內容,git stash list

沒有了。

咱們還能夠屢次使用stash,最後須要恢復的時候,使用下面的命令:

git stash apply stash@{0}

修復bug多是咱們會長期作的事,它會隨時出現,而bug須要馬上解決,這時,咱們就須要把現有的手上的工做stash下,而後建立一個新的分支去修復bug,提交合並後刪除這個分支,最後再使用 git stash pop 來恢復咱們的工做場景。


5、Feature分支

咱們在開發的過程當中,可能隨時會接到新的任務,爲整個工程添加新的功能,這時,咱們最好的作法就是新建一個feature分支,在這個分支上開發,合併,最後刪除該分支

假設有這樣一個場景,咱們接到了Boss的一個任務,要在當前工程上開發一個新的功能,命名爲feature-new01,ok, let's go work...

建立新功能分支feature-new01

在當前新功能分支上,咱們對index.html添加一個新的東西

提交修改

切換回dev分支,並準備進行合併。(新功能合併到dev工做分支上)


這時,Boss說新能取消,再也不開發,因此咱們必須刪除,若是咱們使用 git branch -d feature-new01 ,這時git會提示咱們,這個分支的內容尚未被合併,不能刪除,因此,咱們須要使用 git branch -D feature-new01 來強行刪除這個分支。

若是團隊須要在現有工程上開發新的功能,請新建一個分支進行,完成後,提交,並切換回團隊工做分支(不是master),進行合併,若是在合併以前須要刪除,使用 git branch -D <branch name>來強行刪除,若是已合併,請參考前面的版本回退。

6、多人協做

當咱們從遠程倉庫克隆項目時,其實是把本地master分支和遠程master分支對應起來了,遠程倉庫的默認名稱是 origin ,要查看遠程倉庫的信息,使用 git remote

或者咱們可使用 git remote -v 來顯示更詳細的信息

推送分支,就是把該分支上的全部本地提交都推送到遠程倉庫,推送時,須要指定本地分支,好比咱們須要推送master分支,使用 git push origin master

若是要推送其餘分支,如dev,則可使用 git push origin dev 

但不是全部的本地分支都須要推送到遠程倉庫

master分支是主分支,它是須要推送到遠程的。

dev分支做爲開發分支,也是須要推送到遠程分支的。

處理bug的某些分支,由於處理完成以後會被刪除,因此就麼有必要了,除非團隊須要,好比能夠查看那些人在何時處理了哪些bug

新功能的開發分支,如feature分支,視本身的團隊狀況而定。

因此,咱們本身在本地的分支,是否推送,徹底取決於咱們本身,某些分支徹底就能夠放在本身的本地電腦上玩。

多人團隊開發時,團隊成員都會往master和dev分支上推送本身的修改,下面咱們來模擬一個2人的團隊開發,我在本身的Mac上的虛擬機中裝了一個Ubuntu,咱們在這裏來模擬。

在Ubuntu上裝好git,而後從github上克隆gitTest項目。(注意:在這以前必須把當前機器的SSH Key添加到github)。

建立用戶

當前,咱們在遠程倉庫中有兩個分支,分別是mastet主分支和dev開發分支,但其餘開發成員從遠程克隆項目下來以後,會發現只有master分支,看剛纔咱們在Ubuntu上克隆的項目

咱們看到只有一個master分支,若是團隊成員lz須要在dev分支上進行開發,那麼必須建立遠程的dev分支到本地,可使用 git checkout -b dev origin/dev 命令建立

如今,團隊成員lz就能夠在dev分支上進行開發,並提交,push到遠程。咱們來試試

修改完成,最後一行的div是團隊成員lz在本地dev分支上添加的。咱們保存退出並提交,最後push到遠程倉庫

OK,如今團隊成員lz對index.html作了添加並推送到了遠程,當另一個成員也對這個文件作了修改,並推送,是一個怎麼樣的狀況呢?咱們來試試

呀,提示推送失敗了,緣由是剛纔lz已經對index.html文件作除了修改並推送到了dev分支,我再提交推送就會出現衝突,這時咱們須要先把最新的修改pull下來到個人本地,合併修改後再推送

pull也失敗了,緣由是咱們須要將本地dev和遠程的origin/dev創建連接

再次pull

成功了,咱們打開inex.html看看

看到了嗎?剛纔成員lz的代碼和我剛纔寫入的代碼都在裏面了,並且git也給咱們作出了提示,若是如今合併會起衝突,咱們須要手動調整代碼,而後再提交推送

一般狀況下,在團隊協做開發中,咱們能夠先推送本身的修改,使用 git push origin <branch name>

若是推送失敗,說明遠程的分支比本地更新,咱們須要使用 git pull 來合併

若是 git pull 提示 「no tracking information」, 說明咱們本地的分支沒有和遠程進行關聯,咱們須要使用 

git branch --set-upstream-to=origin/dev dev 來進行關聯,以後再次使用 git pull

若是存在衝突,在本地解決衝突的代碼,最後 git push origin <branch name>。

相關文章
相關標籤/搜索