分支是什麼呢?
html
團隊開發的過程當中,每一個人都會有一個不一樣於別人的分支,各自都在本身的分支上編寫代碼,等到須要的時候,再把各分支合併起來,這樣既安全也不會相互影響。
git
在上一節中,咱們在本地建立了一個Git倉庫,但只有一個分支,就是 master 分支,它是主分支,HEAD指向 master ,master指向當前提交,因此,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"
有時候咱們在進行分支合併時,會遇到各類各樣的問題,下面咱們用實例來講明下。
咱們先建立一個新的分支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 來查看分支合併圖
上面咱們瞭解了合併分支,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上進行發佈了。
咱們在工做時會遇到各類各樣的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 來恢復咱們的工做場景。
咱們在開發的過程當中,可能隨時會接到新的任務,爲整個工程添加新的功能,這時,咱們最好的作法就是新建一個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>來強行刪除,若是已合併,請參考前面的版本回退。
當咱們從遠程倉庫克隆項目時,其實是把本地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>。