歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Git大法好——3.Git分支本地操作詳解

Git大法好——3.Git分支本地操作詳解

日期:2017/3/1 12:16:05   编辑:關於Linux

Git大法好——3.Git分支本地操作詳解

引言

在上一節中我們對Git的常用本地操作的命令進行詳解,而本節要講解的是Git的分支,
在講解之前補充兩點概念性的東西:

第一個
第一節中一個讀者提出的疑問,Git和SVN在版本控制中存儲方式版本信息的差異
答:Git關心文件的整體是否發生變化,而SVN則關心的是文件內容的具體差異!
SVN每次記錄的是有哪些文件進行了修改,以及修改了哪些行的哪些內容:

\

如上圖,比如版本2中記錄的是文件A以及文件C的變化,而版本3中僅僅記錄文件C
的變化這樣,以此類推;而Git並不保存這些前後變化的差異數據,而是保存整個當前
的工作空間(暫存區)所有文件,又叫快照,有變化的文件保存,沒變化的文件就不保存,
而是對上一次保存的快照作一個鏈接。

如上圖,每一次保存的都是所有文件,改變的保存,沒改變的鏈接指向上一次提交的文件!
因為這種不同的保存方式,Git切換分支的速度比SVN快幾條街!

第二個<喎?http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPqO6PGJyIC8+DQo8c3Ryb25nPkdpdMO/tM5jb21taXTKsbryo6zU2rLWv+LW0LXEyv2+3b3hubk8L3N0cm9uZz6hozwvcD4NCjxwPjxpbWcgYWx0PQ=="" src="http://www.2cto.com/uploadfile/Collfiles/20160226/2016022609160854.png" title="\" />

如上圖,Blob對象存儲的是文件的快照內容,tree對象則是記錄快照索引的目錄 .
當然,上面的內容知道下就好了,也不必過於深究,好的,開始學習本節Git分支的相關
內容吧~


1.什麼是分支?

我們知道每次我們commit的時候都會生成一個快照,或者說一個版本庫,從引言我們也知道
了通過Blob對象存儲文件快照內容,然後Tree對象記錄快照索引目錄,通過索引找到文件快照;
那麼問題來了:每一個快照(版本庫)又是怎樣的組合到一起的呢?
還記得我們上一節講解的版本回退嗎?我們可以根據一個版本號,讓當前工作空間的文件回退
到某個版本,其實Git會將這些快照串成一條條的時間線,而這些時間線就是我們的:分支
假如我們不創建並切換到其他分支上,那麼每次commit生成的快照都會被串到一條線上,而這
條時間線又叫master分支或者主分支,除了這個master分支外,我們還要知道一個東西
就是HEAD指針,這個指針是指向正在工作的本地分支,我們前面的版本回退,其實就是修改
HEAD指針的指向而已!比如:git reset HEAD^就是將HEAD指針前移,指向上一個快照
而已,可能你還不是很理解,沒事,我們撸一發命令,然後來波圖解就好~

這裡我們新建四個文件,然後每次add一個文件後commit,然後我們鍵入:git log –graph –all

\

上面的這道紅線就是版本的時間線(分支)了,而上面的每一個節點則是某一版本的快照,
這條紅線就是我們的master分支,而上面的結點就是我們的每個版本,下面我們畫圖幫助大家理解下:

第一次提交: 第二次提交:
第三次提交:
第四次提交:

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

當我們每次commit,我們的master都會向前移動一步,即指向最新的提交! 而HEAD則指向你正在工作的本地分支,而git reset修改的就是HEAD
指針的指向而已!

2.為什麼要創建其他分支?

看到這個標題,讀者可能會有疑問:不是已經有一個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:關於分支管理的詳細策略,我們後面講多人協作再細講,這裡知道最簡單的這種就可以了!


3.分支的創建與切換

1)創建分支

git branch 分支名

\

我們可以直接簡單git branch或者git branch -a來查看所有分支,而此時分支和HEAD
的情況如下:

此時,盡管我們創建了develop分支,但是HEAD指針還指向master分支,我們繼續commit
的話,都會在master分支上進行,我們需要切換一下當前分支,即修改HEAD指針的指向!

2)切換分支

git checkout 分支名

\

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

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

git checkout -b 分支名

接著我們來修改下某個文件的內容,改點東西,然後commit,然後此時版本線的情況如下:

\

接著我們切回master分支,鍵入:git checkout master,打開我們的note_1.txt,這個時候
你會發現並沒有發生更改,因為我們剛剛的提交是在develop分支上進行的,而master分支上
沒有變化,此時的版本線情況如下:


4.分支的合並

在Git中,我們可以使用git mergegit rebase兩個命令來進行分支的合並。
而本節我們主要講解如何使用merge指令來合並分支,另外合並的方式又分為兩種:
快速合並和普通合並,兩者的區別在於前者合並後看不出曾經做過合並,而後者合並
後的歷史會有分支記錄!作圖是快速合並,右圖是普通合並!

\ _______

1.快速合並

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

git merge develop

\

合並成功,此時我們打開note_1.txt文件,可以看到:

嘿嘿,果然develop分支上的做的更改都合並到master分支上了!這裡的cat命令是linux
下用來打印文件內容的一個指令!

2.普通合並

這裡的話我們切到develop分支下,修改note_2.txt的內容,然後再通過下面的指令合並分支:
–no-ff參數表示禁用快速合並!

git merge --no-ff -m "合並的信息(TAG)" develop

\

成功合並,然後我們可以鍵入:git log –graph -all來查看版本狀態,當然這裡我們只
關心的是分支線的情況,我們可以鍵入:

git log --graph --pretty=oneline --abbrev-commit

結果如下:

\

當然,不是每次合並分支都是順順利利的,有事會發生合並沖突,這個時候,我們
需要處理沖突,完成後才能夠進行合並!


5.解決合並沖突

這裡我們切到master分支下,修改note_3.txt,寫點東西,add後提交,然後切到develop分支,
也是修改note_3.txt文件,add後commit,最後切回master分支,然後再執行merge合並分支。
這個時候就會出現合並失敗,需要我們手動解決沖突後才能提交!

\

可能命令行看的不是很清楚,我們打開note_3.txt文件:

選擇要保留的內容,add後提交,成功後分支就合並成功了,接著鍵入git status看下狀態,
也可以鍵入:git log –graph –pretty=oneline –abbrev-commit 查看整個版本線的狀態!


6.刪除分支

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

git branch -d 分支名

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

\


7.恢復誤刪分支

當然有時可能我們會手多,或者不小心把某些分支給刪掉了,你後悔了,想恢復
被刪的分支,沒關系,我們先鍵入:

git log --branches="被刪的分支名"

獲取到該分支的最新版本的那個版本號id(取前七位即可),接著鍵入下述命令即可:

git branch develop 版本id

結果如下:

\

無壓力的說!


8.切換分支時保存未commit的更改

比如可能有這樣一個場景:
當你在某個分支上寫代碼寫得很嗨的時候,這個時候你的同事過來找你,他看不懂你寫的
某個分支上的代碼,要你解釋一波,這時候你需要切換到另外一個分支上,此時,你的代碼
還沒有提交,會提示切換失敗,比如我這裡在develop分支上新建一個Task分支,然後新建
一個note_5.txt文件,add,commit,接著修改文件內容,add,commit,再接著add,不commit
直接切換分支,就會出現切換分支失敗,提示我們要麼commit或者stash

\

你可以直接commit,不過,假如你的代碼才寫了幾行或者未完成,一般都不想去提交的,
你可能想保存當前的狀態,然後跟同事BB完後,又回來當前的狀態來,那麼git stash指令
能幫到你!直接鍵入:

git stash

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

git stash apply

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

\

另外,可以保存多個stash哦,他們會放在一個stash的列表中你可以根據表示符
來解除對應的stash並且恢復未提交的變更!鍵入下述命令可查看stash列表:

git stash list

\

標識符就是括號裡的,如果你想回復某個stash的話,比如這裡,你就可以鍵入:

git stash apply stash@{0}

你只要修改{}裡的標識符(數字)即可!


小結:

本節給大家講解了一波Git的本地分支操作的命令,基本涵蓋了一些日常的本地分支操作,
同樣建議你跟著筆者的文章,一步步走指令,動手更有助於理解!下節我們來講解遠程
倉庫和多人協作的分支管理策略!敬請期待~
假如你覺得本文簡單易懂,對你學習Git分支有幫助,點個贊留個評論如何?

\,晚安!

Copyright © Linux教程網 All Rights Reserved