天天看點

Git分支本地操作詳解

在上一節中我們對git的常用本地操作的指令進行詳解,而本節要講解的是git的分支,

在講解之前補充兩點概念性的東西:

第一個:

第一節中一個讀者提出的疑問,git和svn在版本控制中存儲方式版本資訊的差異。

答:git關心檔案的整體是否發生變化,而svn則關心的是檔案内容的具體差異!

svn每次記錄的是有哪些檔案進行了修改,以及修改了哪些行的哪些内容:

Git分支本地操作詳解

如上圖,比如版本2中記錄的是檔案a以及檔案c的變化,而版本3中僅僅記錄檔案c

的變化這樣,以此類推;而git并不儲存這些前後變化的差異資料,而是儲存整個目前

的工作空間(暫存區)所有檔案,又叫快照,有變化的檔案儲存,沒變化的檔案就不儲存,

而是對上一次儲存的快照作一個連結。

Git分支本地操作詳解

如上圖,每一次儲存的都是所有檔案,改變的儲存,沒改變的連結指向上一次送出的檔案!

因為這種不同的儲存方式,git切換分支的速度比svn快幾條街!

第二個:

git每次commit時候,在倉庫中的資料結構。

Git分支本地操作詳解

如上圖,blob對象存儲的是檔案的快照内容,tree對象則是記錄快照索引的目錄 .

當然,上面的内容知道下就好了,也不必過于深究,好的,開始學習本節git分支的相關

内容吧~

我們知道每次我們commit的時候都會生成一個快照,或者說一個版本庫,從引言我們也知道

了通過blob對象存儲檔案快照内容,然後tree對象記錄快照索引目錄,通過索引找到檔案快照;

那麼問題來了:每一個快照(版本庫)又是怎樣的組合到一起的呢?

還記得我們上一節講解的版本回退嗎?我們可以根據一個版本号,讓目前工作空間的檔案回退

到某個版本,其實git會将這些快照串成一條條的時間線,而這些時間線就是我們的:分支。

假如我們不建立并切換到其他分支上,那麼每次commit生成的快照都會被串到一條線上,而這

條時間線又叫master分支或者主分支,除了這個master分支外,我們還要知道一個東西

就是head指針,這個指針是指向正在工作的本地分支,我們前面的版本回退,其實就是修改

的head指針的指向而已!比如:git reset head^就是将head指針前移,指向上一個快照

而已,可能你還不是很了解,沒事,我們撸一發指令,然後來波圖解就好~

這裡我們建立四個檔案,然後每次add一個檔案後commit,然後我們鍵入:git log --graph --all
Git分支本地操作詳解

上面的這道紅線就是版本的時間線(分支)了,而上面的每一個節點則是某一版本的快照,

這條紅線就是我們的master分支,而上面的結點就是我們的每個版本,下面我們畫圖幫助大家了解下:

第一次送出:

Git分支本地操作詳解

第二次送出:

Git分支本地操作詳解

第三次送出:

Git分支本地操作詳解

第四次送出:

Git分支本地操作詳解

由上面的圖,我們不難發現這樣的規律:

當我們每次commit,我們的master都會向前移動一步,即指向最新的送出!

而head則指向你正在工作的本地分支,而git reset修改的就是head

指針的指向而已!

看到這個标題,讀者可能會有疑問:不是已經有一個master分支了嗎,為什麼還要另外建立

其他分支?我們每次commit就好,假如是遠端協作的話,就都push到遠端伺服器上,有沖突

就解決沖突,然後每個人在pull一下伺服器上的代碼不就好了,另外建立新分支好像沒什麼

必要吧?

答:我以前也是這樣想的,在上一家公司,我和另外的同僚就是這樣幹的...把東西都丢到

master分支上,感覺沒什麼不對,當然,這種做法是可以的,項目小可以,整個項目就一個master分支,

但是這樣做其實并不好!下面列舉兩點吧:

第一點,我們一般的項目都是一步步疊代更新的,一般都會有大版本和小版本的更新,

大版本更新一般是改頭換面的一個更新,比如ui大改或者架構大改之類的,然後版本是:v2.0.0這樣;

而小版本的更新一般是一些細節的小改,比如ui修改和bug的修複,或者優化等,然後版本是:v2.0.11這樣;

隻有一條master分支,意味着你的分支線會非常非常的長,假如你釋出了第二個大版本,而使用者回報

你的第一個版本有一個很嚴重的bug,你要切回之前的版本,夠嗆的哈!

第二點,效率問題,假如某一次送出後出現沖突了,而這個沖突很難解決,那麼就會卡在這裡,

那麼就無法向後再開發了,又或者說master上的分支出現了很大的問題,同樣也無法接着開發。

當然,不好的地方遠遠不止上面兩個,我們得想辦法來解決這個問題,而一個簡單而有效的

方法就是建立其他的分支,然後按照一定的分支政策來管理我們的項目版本!一種最簡單和

常用的分支政策就是:

在master分支上開辟一個新的develop分支,然後我們根據功能或者業務,再在develop 分支上另外開辟其他分支,完成分支上的任務後,再将這個分支合并到develop分支上!

master分支和develop分支都是長期分支,而我們建立的其他分支則是臨時性分支!

簡單概括下各個分支都拿來幹嘛吧:

master分支:可直接用于産品釋出的代碼,就是正式版的代碼

develop分支:日常開發用的分支,團隊中的人都在這個分支上進行開發

臨時性分支:根據特定目的開辟的分支,包括功能(feature)分支,或者預釋出(release)分支,

又或者是修複bug(fixbug)分支,臨時性分支用完之後一般都會删除,使得代碼庫的常用分支始終

隻有兩個長期分支!

ps:關于分支管理的詳細政策,我們後面講多人協作再細講,這裡知道最簡單的這種就可以了!

Git分支本地操作詳解

我們可以直接簡單git branch或者git branch -a來檢視所有分支,而此時分支和head

的情況如下:

Git分支本地操作詳解

此時,盡管我們建立了develop分支,但是head指針還指向master分支,我們繼續commit

的話,都會在master分支上進行,我們需要切換一下目前分支,即修改head指針的指向!

Git分支本地操作詳解

好的,通過上面的指令我們就切換到develop分支下了,切換後的情況是這樣的:

Git分支本地操作詳解

其實,分支的建立和切換隻需要下面的一個指令就可以完成了:

接着我們來修改下某個檔案的内容,改點東西,然後commit,然後此時版本線的情況如下:

Git分支本地操作詳解
Git分支本地操作詳解

接着我們切回master分支,鍵入:git checkout master,打開我們的note_1.txt,這個時候

你會發現并沒有發生更改,因為我們剛剛的送出是在develop分支上進行的,而master分支上

沒有變化,此時的版本線情況如下:

Git分支本地操作詳解

在git中,我們可以使用git merge和git rebase兩個指令來進行分支的合并。

而本節我們主要講解如何使用merge指令來合并分支,另外合并的方式又分為兩種:

快速合并和普通合并,兩者的差別在于前者合并後看不出曾經做過合并,而後者合并

後的曆史會有分支記錄!作圖是快速合并,右圖是普通合并!

Git分支本地操作詳解

_

Git分支本地操作詳解

我們把develop分支合并到master分支上,來到master分支後,鍵入下述指令:

Git分支本地操作詳解

合并成功,此時我們打開note_1.txt檔案,可以看到:

Git分支本地操作詳解

嘿嘿,果然develop分支上的做的更改都合并到master分支上了!這裡的cat指令是linux

下用來列印檔案内容的一個指令!

這裡的話我們切到develop分支下,修改note_2.txt的内容,然後再通過下面的指令合并分支:

--no-ff參數表示禁用快速合并!

Git分支本地操作詳解

成功合并,然後我們可以鍵入:git log --graph -all來檢視版本狀态,當然這裡我們隻

關心的是分支線的情況,我們可以鍵入:

結果如下:

Git分支本地操作詳解

當然,不是每次合并分支都是順順利利的,有事會發生合并沖突,這個時候,我們

需要處理沖突,完成後才能夠進行合并!

這裡我們切到master分支下,修改note_3.txt,寫點東西,add後送出,然後切到develop分支,

也是修改note_3.txt檔案,add後commit,最後切回master分支,然後再執行merge合并分支。

這個時候就會出現合并失敗,需要我們手動解決沖突後才能送出!

Git分支本地操作詳解

可能指令行看的不是很清楚,我們打開note_3.txt檔案:

Git分支本地操作詳解

選擇要保留的内容,add後送出,成功後分支就合并成功了,接着鍵入git status看下狀态,

也可以鍵入:git log --graph --pretty=oneline --abbrev-commit 檢視整個版本線的狀态!

Git分支本地操作詳解

删除分支就簡單很多了,直接鍵入:

這裡我們把dev分支删除掉:

Git分支本地操作詳解

當然有時可能我們會手多,或者不小心把某些分支給删掉了,你後悔了,想恢複

被删的分支,沒關系,我們先鍵入:

擷取到該分支的最新版本的那個版本号id(取前七位即可),接着鍵入下述指令即可:

Git分支本地操作詳解
Git分支本地操作詳解

無壓力的說!

比如可能有這樣一個場景:

當你在某個分支上寫代碼寫得很嗨的時候,這個時候你的同僚過來找你,他看不懂你寫的

某個分支上的代碼,要你解釋一波,這時候你需要切換到另外一個分支上,此時,你的代碼

還沒有送出,會提示切換失敗,比如我這裡在develop分支上建立一個task分支,然後建立

一個note_5.txt檔案,add,commit,接着修改檔案内容,add,commit,再接着add,不commit

直接切換分支,就會出現切換分支失敗,提示我們要麼commit或者stash!

Git分支本地操作詳解

你可以直接commit,不過,假如你的代碼才寫了幾行或者未完成,一般都不想去送出的,

你可能想儲存目前的狀态,然後跟同僚bb完後,又回來目前的狀态來,那麼git stash指令

能幫到你!直接鍵入:

然後就可以切換分支了,切換分支後,招呼完同僚,你可以鍵入:

恢複你之前的狀态,比如note_5.txt我們add後還沒commit!

Git分支本地操作詳解

另外,可以儲存多個stash哦,他們會放在一個stash的清單中你可以根據表示符

來解除對應的stash并且恢複未送出的變更!鍵入下述指令可檢視stash清單:

Git分支本地操作詳解

辨別符就是括号裡的,如果你想回複某個stash的話,比如這裡,你就可以鍵入:

你隻要修改{}裡的辨別符(數字)即可!

本節給大家講解了一波git的本地分支操作的指令,基本涵蓋了一些日常的本地分支操作,

同樣建議你跟着筆者的文章,一步步走指令,動手更有助于了解!下節我們來講解遠端

倉庫和多人協作的分支管理政策!敬請期待~

參考文獻:

pro git(官方) pro git(oschina)

——作者:coder-pig,本教程不收取任何費用,歡迎轉載,轉載請注明出處,尊重作者

勞動成果,請勿用于商業用途,侵權必究!

繼續閱讀