Git三大特點之Branch(分支)

我習慣每篇博客都有個開篇

還記得 Git 系列第一篇 Git 自我介紹的話嗎?其中有 Git 本身都贊同的三大特點git

cheap local branching, convenient staging areas, and multiple workflowsbash

輕量的本地分支, 方便的暫存,以及多工做流。其中由於有分支的存在,才構成了多工做流的特點,因此 Branch 不愧爲 Git 的王牌特點。這篇博客,主要和你們一塊兒學習一下輕若鴻毛,帥到炸裂的分支兒。微信

Branch 的概念

分支的概念,在我看來,分兩個版本:學習

從使用場景上解釋,是這麼個概念spa

Git 的分支,就是開發過程當中,要選擇的一條路,你能夠選擇和其餘小夥伴一塊兒走同一條路,也能夠本身走一條路,路與路之間相互沒有影響,做爲路的主人,你也隨時可讓兩條路合併。命令行

簡筆畫 Git 分支

深刻一點的話,是這麼個概念3d

Git 的分支,其實本質上僅僅是指向提交對象的可變指針,這個可變指針,指向路的終點。同時,還有一個比較特別的 HEAD 指針,用於記錄當前工做的位置,借用上面的例子,這個 HEAD 指針等於在路上走的你本身,你在哪,指針就在哪,你在哪一個分支,HEAD 指針就指向哪一個分支的指針。 指針

深層次的分支概念圖

實際上,當咱們使用 Git 的時候,咱們就使用了分支,由於 Git 的默認分支名字是 master,若是你有心的話,會發現執行 git init後,命令行的輸出頭部已經默認在 master 分支了。 可是這個時候,還並未建立 master 分支,只有當有一個提交的時候,纔會建立 master 分支。緣由在於,分支的指針要指向提交的呀,忽然明白了,當初看 Android Studio 的教程,爲何每一個都讓有一個初步提交了呢。code

無圖無真相,不信的看下面:cdn

git 默認分支 master

玩轉 Branch 必備技能

有關分支的命令很少,無非是換着花樣的增刪改查,掌握好如下基本的命令,之後就能夠在 Branch 的草原上策馬奔騰瀟瀟灑灑啦

建立分支

git branch <name>
複製代碼

這個命令看起來,彷佛簡單到你只須要想個分支的名字就行了。
可是在建立分支的時候,要想下,是否要從當前分支的內容基礎上去開闢一條新分支。

查看分支

三個命令,讓你想看什麼分支就看什麼分支,就是這麼方便

git branch //查看本地分支
 git branch -r //查看遠程分支
 git branch -a //查看本地和遠程的全部分支
複製代碼

刪除分支

當本地分支刪除後,推進到遠程倉庫後,遠程倉庫並不能自動刪除遠程分支(緣由,下回分解)。因此,分支的徹底刪除是分兩個部分的,一個是本地,一個是遠程。

本地刪除操做須要加上 -d或者 -D 參數,參數的名稱來自英語 delete的縮寫,Remember it so easy!

二者的區別在於-D-d要粗暴一點。當被刪除分支有新內容沒有被合併的時候,使用-D,會直接刪除, 使用-d,會提示該分支有新內容沒有被合併,不執行刪除。刪除需謹慎,建議非特殊狀況下,使用溫柔的-d要好一點,以避免小手一抖,眼淚長流。

git branch -d <name>
 git branch -D <name> //強制刪除

複製代碼

刪除遠程分支須要 push 操做。

git push origin :<name>
複製代碼

重命名分支

其實,這是個僞命題。

可是有不少人,包括我,都有過對分支名稱不滿意想該修改一下的想法,因此,就有了這個僞命題的存在。

事實上,分支不存在重命名,沒有 rename 的這個命令。若是你起的名字不滿意,想從新起的話,那隻要建立一個和要修改分支內容同樣的分支,起上你喜歡的名字,而後再把以前的給刪掉。

檢出分支

這個檢出分支的「檢出」二字,算是個關於 Git 分支的專業術語了,你能夠理解爲切換當前分支。
本質上, checkout 操做是移動 HEAD 指針,將 HEAD 指針指向要切換的分支的指針處。

使用場景有兩個:

  1. 已經存在的分支,如今要切換過去。
git checkout <name>
複製代碼
  1. 建立一個新分支,並切換到新分支,這個一步到位的話須要 -b 參數。

    以當前分支爲基礎,建立一個新分支

    git checkout -b <branch name>
    複製代碼

    以指定的某一個提交,建立一個新分支

    git checkout -b <branch name> <SHA1>
    複製代碼

合併分支

以上,是分支的增刪改查獨立操做,可是 Git 創造這個分支,並不僅是爲了讓它們自個兒和自個兒玩的,還須要它們之間的相互協做和配合。 就像寫項目的時候,分好開發任務,你和你的小夥伴新建了兩個分支,你寫你的 Anglela,他寫他的 baby,到開發完成以後,確定要合在一塊兒,才能成就 Anglelababy。合的這個動做,就涉及到了分支合併的概念。

分支合併使用到的命令是

git merge <branch name>
複製代碼

分支合併相對分支的其餘操做,是相對要複雜一點的,怎麼說也是多分支操做,至少要對得起它一聽就比較高端的名字吧,因而我決定把分支的合併做爲一個大標題。

Branch 合併是大事

git 的兩種合併模式

分支的合併是很是智能的,目前有兩種模式,兩種模式的選擇,不須要咱們參與,而是 Git 根據分支狀況不一樣,自行判斷選擇的。在我使用 Git 的過程當中,執行分支合併,有時須要輸入提交信息,有時不須要,做爲小白的我懵的不知因此然,後來才知道是由於合併模式的問題。

兩種模式是:

  1. Fast-Forward(快進式)(PS:這個名字是官方的)
  2. Recursive Strategy Merge(策略合併式)(PS:這個名字非官方,我本身起的,有時也叫三方合併式)
  • Fast-Forward(快進式)

如圖,有兩個分支,master 分支和 feature 分支。當這兩個分支處於上面的關係時,當進行合併操做時,就會出現 fast-forward。

緣由是;因爲當前 master 分支所指向的提交是 feature 分支的直接上游,因此 Git 只是簡單的將指針向前移動。 換句話說,當你試圖合併兩個分支時,若是順着一個分支走下去可以到達另外一個分支,那麼 Git 在合併二者的時候,只會簡單的將指針向前推動(指針右移),由於這種狀況下的合併操做沒有須要解決的分歧——這就叫作 「快進(fast-forward)」。

合併後的分支指針位置以下:

  • Recursive Strategy Merge(策略合併式)

這個合併方式,是爲補充 fast-forward 而出現的,由於你知道,在項目開發過程當中,不少人開發的狀況下,出現 fast-forward 的狀況並非不少,不少是相似下面這種。提交歷史是分叉的,沒法知足執行 fast-forward 的條件:

由於,master 分支所在提交併非 feature 分支所在提交的直接祖先,Git 不得不作一些額外的工做。 出現這種狀況的時候,Git 會使用兩個分支的末端所指的快照(C4 和 C5)以及這兩個分支的工做祖先(C3),作一個簡單的三方合併,生成一個新的提交(C6)。

實戰演練一下

提及來就是一堆理論,我本身都記不住,找個例子演示一下:

//建立一個文件夾,並初始化 Git
mkdir GitDemo
git init

//初次提交,建立 master 分支
touch master.txt
git add.
git commit -m '添加master文件'

//從master分支末尾,建立並切換 featureA 分支,並建立一個提交
git checkout -b featureA
touch A.txt
git add.
git commit -m '添加A文件'

//從master分支末尾,建立並切換 featureB 分支,並建立一個提交
git checkout master
git checkout -b featureB
touch B.txt
git add.
git commit -m '添加B文件'

//切換 master 分支
git checkout master

//master 合併 featureA 分支
git merge featureA

//master 合併featureA 後再合併 featureB 分支
git merge featureB

複製代碼

博主不想給你說話,並向你投擲了一大串命令,快去敲敲看啊,會看到兩種合併模式的!

master 分支合併 featureA 時,是快進式合併:

master 分支合併 featureA 後, 再合併 featureB 時,已經不知足快進式條件了,此時合併會觸發一個三方合併,產生一個新的提交。因此,執行合併命令,會跳到下面的頁面,讓咱們編輯這個新提交的提交信息,默認提交信息是「Merge branch 'branch name'」. 按 i編輯提交信息, :wq!保存並退出頁面。

合併成功後的提示信息:

畫出上面小例子的分支合併,示意圖,以下:

master 合併 featureA

master 合併 featureB

和平解決 Branch 合併衝突

有人在的地方就有江湖,有分支在的地方,就有衝突。有時候合併操做不會如此順利。 若是你在兩個不一樣的分支中,對同一個文件的同一個部分進行了不一樣的修改,Git 就無法乾淨的合併它們,因而就會發生衝突。

以下,分別在 master 和 featureA ,在 master.txt 文件第一行添加一句話,而後兩個分支合併,就會發生衝突。

衝突提示信息中,指明衝突文件爲 master.txt。同時,也能夠經過 git status 命令,查看衝突的詳細信息

須要說明的是,若是遇到衝突的話,git 就沒法自動合併了,接下來要靠咱們本身手動解決衝突,方法是:

  1. 查看形成衝突的文件,修改衝突部分
  2. 對修改後衝突文件,執行 git add操做
  3. 建立一個修改衝突的提交。

先知道一下思路,有個簡單的概念在腦子裏,接下來,一步一步仔細看~

第一步:查看形成衝突的文件,修改衝突部分

衝突文件 master.txt 以下,git 雖然沒法解決衝突, 可是已經幫咱們幫到最後了,使用簡單的三個符號,標明瞭衝突的地方,以及衝突的兩個分支在該地方發生衝突內容。

符號 意義
======= 分隔符
<<<<<<< HEAD 至 ======= master 分支中該地方的內容
======= 至 >>>>>>> featureA featureA 分支中該地方爲內容

接下來編輯 master.txt 文件,完成合並,確認以後,把 git 衝突標識符號給刪除掉便可。

第二步 & 第三步:修改後衝突文件,add && commit

分支回滾, 有後悔路能夠走

現實中,不免有些時候,你會有後悔的念頭。例如天天我遲到的時候,都會後悔爲何第一遍鬧鐘響的時候沒有起牀,可是這個世界,沒有後悔路能夠走,我只能努力作到明天早起。

可是,Git 中有!由於神奇的 reset 和 revert 命令~,兩個命令均可以達到回滾的效果,二者之間的區別之後會專門說,這裏咱們使用 reset 。

提早聲明:回滾以前,不要忘記作好備份,有備無患吶。

本地分支回滾:

肯定回滾到哪一個提交,找到該提交的 commit id,執行如下命令,就行了

git reset --hard commit id
複製代碼

遠程分支回滾

依舊是個僞命題。遠程分支不存在什麼回滾,要想達到回滾的效果,就是刪除以前的遠程分支,而後把本地回滾好的本地分支,push 到遠程。

git reset --hard commit id //本地分支回滾
git push origin :<name> //刪除遠程分支
git push origin <name> //用回滾後的本地分支從新創建遠程分支
複製代碼

我習慣每篇博客都有個結束語

這篇博客用了我很多洪荒之力,但願對你們理解 Git 分支有所幫助,不對之處還請指出。
最近 Git 系列走起,下篇博客見!


歡迎關注博主的微信公衆號,快快加入哦,期待與你一塊兒成長!

歡迎關注博主的微信公衆號,快快加入哦,期待與你一塊兒成長!
相關文章
相關標籤/搜索