在git中,分支指的是從主線上分離出來進行另外的操作,既不影響主線,主線又可以繼續幹它的事,它可用於解決臨時需求;當分支做完事後可合併到主線上,而分支的任務完成可以刪掉了。
本教學操作環境:Windows7系統、Git2.30.0版、Dell G3電腦。
git的分支是什麼
顧名思義,分支就是從主線上分離出來進行另外的操作,而又不影響主線,主線又可以繼續幹它的事,是不是有點像線程,最後分支做完事後合併到主線上而分支的任務完成可以刪掉了。這樣是不是很方便,主線繼續做它的事,分支用來解決臨時需求,二者互不相干。
git的分支功能特別的強大,它不需要將所有資料進行複製,只要重新建立一個分支的指標指向你需要從哪裡開始創建分支的提交對象(commit),然後進行修改再提交,那麼新分支的指針就會指向你最新提交的這個commit對象,而原來分支的指針則指向你原來開發的位置,當你在哪個分支開發,HEAD就指向那個分支的最新提交對象commt。沒弄清楚沒關係,先有這麼一個概念,後面慢慢就會弄清楚的。
分支的新合併
我們可以用指令git branch來查看我們的git倉庫有幾個分支,而我們目前工作處於那個分支,前面有個*號的就為我們目前所處的分支。我們可以透過指令git branch name來建立分支,而這個分支的指標就指向最新的commit對象,也就和HEAD指向同一對象。我們可以透過指令git checkout name來切換到目的分支,我們預設的主分支為master。在分支的創建和切換,其實只是簡單的創建指針找指針而已,而根據找到的指針找到所指向的commit對象,然後將工作空間恢復成該commit對象所指的文件快照讓我們來工作。當提交一次,指針就重新指向這個最新提交的對象,特別的簡單。
當我們建立分支teset之前,只有master一個主分支,如圖一,我們所有的開發都是在這個分支上,而且HEAD是指向最近一次提交的commit物件c3,c3以前還有兩次提交c1和c2,這時我們透過git branch test建立test分支,如圖二,這時HEAD還是指向master分支最近一次提交的c3,當git checkout test切換到test分支後,HEAD就指向test分支最近一次的提交c3,這個時候其實在.git裡面都是指向同樣一份資料c3。
這個時候,當我們在test分支上進行了幾次開發提交了c4和c5兩個版本後,那麼test和HEAD都指向test分支的最近一次提交c5,如圖三,而master此時還沒有變化,任然指向的是c3,如果這個時候將test分支合併到master分支,那麼git根本不用做什麼,只要將master移動,指向c5就可以了,這個過程稱之為Fast-forward快轉。如果此時test的任務完成,我們就可以透過git branch -d test將它刪除掉,繼續在主分支master上進行開發。如果是這樣的話,那麼test分支就白建了。
那麼如果此時master分支上又進行另外的開發,提交了兩個版本c6和c7,那麼此時的master和HEAD指針都指向的是c7 ,如圖四,可以看出在哪個分支上開發,那麼HEAD就指向的是哪個分支上的commit,這個時候合併兩個分支的話,就如下。
如圖五,我們先切換到master分支,然後透過git merge test將test分支合併到master分支,這個時候,git就不是簡單的移動指針了,因為兩邊都有開發,所以git就要對於兩個分支的最新提交c5和c7還有兩個分支共同的祖先commit對象c3來進行一次簡單的三方合併,產生新的文件快照並用新的commit對象c8記錄,這個合併的過程不需要太在意,如果產生了衝突,也就是兩個分支對同一個檔案進行了修改,那麼git就會停下合併操作,讓你處理好衝突後,再提交(c8),然後再進行合併。這時master和HEAD都指向c8,但是test是沒有移動的,此時還可以在test上繼續開發,再合併到master,如果test已經沒有利用價值了就可以刪除了。
本地分支,追蹤分支和遠端分支
這裡有三個概念,本地分支就是我們可以透過git branch查看到的分支,也就是我們自己git倉庫所擁有的分支,我們都可以利用。遠端分支是遠端倉庫的分支的索引,它其實也是本地分支,只是我們無法移動它,必須要在和中心伺服器交互根據伺服器更新到本地來的程式碼移動的,遠端分支的作用就是我們上次和中心伺服器互動更新得到的最新版本,它也是個指標。追蹤分支比較難理解,它也是一個本地分支,只是它對應了一個遠端分支,如果我們本地的某個分支對應了一個特定的遠端分支,那麼它就是追蹤分支,例如我們最初的master分支就是一個追蹤分支,它對應遠端分支origin/master,這裡origin是遠端倉庫名,當我們在master分支裡執行更新(fetch,pull)或推送(push),在不指定分支的情況下,預設就是從origin/ master分支更新或提交到origin/mster分支。
從圖七和圖八很容易看出來,和我們本地建立分支很相似,只是origin/master遠端分支只有在連接伺服器並更新伺服器代碼到本地後才會移動,如下圖九:
#更新遠端程式碼到本機有兩個指令,fetch和pull,fetch是將遠端程式碼更新到本地,但不會執行合併操作,需要自己查看,解決衝突什麼的,然後自己再執行merge將更新來的程式碼合併到我們自己制定的分支,但是pull就將這兩個操作合成了一步,直接更新伺服器程式碼更新並合併到本機指定分支,當然遇到衝突也必須自己解決。所以我們通常都會使用fetch來實現更新,雖然麻煩了點,但是不容易出問題。
將本地程式碼推送到遠端倉庫,也就是中心伺服器,一般我們推送資料都是git push origin master:master,這裡指定遠端倉庫名,本地分支名和遠端分支,也就是將我們本地master分支的資料推送到遠端倉庫origin的master分支。如果本地的master分支是追蹤分支,那麼在不指定的情況下,它會自行找到遠端倉庫中對應的分支來推送資料。或者我們直接進行git push origin操作,只指定遠端倉庫名,那麼git會根據我們目前所在分支和它所對應的遠端倉庫的分支來實現資料推送,前提是我們目前所在分支必須是追蹤分支。當然如果是git push origin :master,這裡本地分支名是空的,這個操作就是將空分支推送到遠端倉庫的master分支,結果就是將master分支刪除。
既然追蹤分支這麼好用,那麼我們怎麼建立追蹤分支呢,有兩種方式,第一種方式是根絕遠程分支創建追蹤分支,如果不指定該追蹤分支的名字,預設和遠端倉庫的分支名字一樣:git checkout --track origin/test,這樣我們就建立了一個名為test的追蹤分支,如果重新指定追蹤分支的名字:git checkout -b name origin/test,這樣我們就建立了一個名為name的追蹤分支,它對應遠端倉庫的test分支。第二種方式是已經存在某個本地分支,要讓它對應某個遠端分支來成為追蹤分支,也有兩個指令可以用,git branch --set-upstream test origin/test 或git branch -f - -track test origin/test 這裡我們就讓我們本地已經存在的test分支來追蹤遠端的test分支。
git分支管理
#git創建分支於合併分支是如此簡單快捷,那麼在我們的開發過程中可以瘋狂的使用分支,而且git的核心玩法之一就是分支,非常提倡使用分支,但是是不是我們可以肆無忌憚的使用分支呢,創建這麼多的分支我們要如何來管理呢,分支不在多而在恰到好處,如果分支創建多了,管理起來就麻煩了,所以推荐一種分支的管理策略,git-flow,同時推荐一文章來了解這個策略:http://nvie.com/posts/a-successful-git-branching-model/,讓你的git使用更加順手。
推薦學習:《Git教學》
以上是git中分支是什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!