前言
幾乎每一種版本控制系統(tǒng)都以某種形式支持分支。使用分支意味著你可以從開發(fā)主線上分離開來,然后在不影響主線的同時繼續(xù)工作。在很多版本控制系統(tǒng)中,這是個昂貴的過程,常常需要創(chuàng)建一個源代碼目錄的完整副本,對大型項目來說會花費很長時間。
有人把 Git的分支模型稱為“必殺技特性”,而正是因為它,將 Git 從版本控制系統(tǒng)家族里區(qū)分出來。Git 有何特別之處呢?Git 的分支可謂是難以置信的輕量級,它的新建操作幾乎可以在瞬間完成,并且在不同分支間切換起來也差不多一樣快。和許多其他版本控制系統(tǒng)不同,Git 鼓勵在工作流程中頻繁使用分支與合并,哪怕一天之內(nèi)進行許多次都沒有關系。理解分支的概念并熟練運用后,你才會意識到為什么 Git 是一個如此強大而獨特的工具,并從此真正改變你的開發(fā)方式。
一.概括
1、Git 是分布式的,SVN 不是:這是 Git 和其它非分布式的版本控制系統(tǒng),例如 SVN,CVS 等,最核心的區(qū)別。
2、Git 把內(nèi)容按元數(shù)據(jù)方式存儲,而 SVN 是按文件:所有的資源控制系統(tǒng)都是把文件的元信息隱藏在一個類似 .svn、.cvs 等的文件夾里。
3、Git 分支和 SVN 的分支不同:分支在 SVN 中一點都不特別,其實它就是版本庫中的另外一個目錄。
4、Git 沒有一個全局的版本號,而 SVN 有:目前為止這是跟 SVN 相比 Git 缺少的最大的一個特征。
5、Git 的內(nèi)容完整性要優(yōu)于 SVN:Git 的內(nèi)容存儲使用的是 SHA-1 哈希算法。這能確保代碼內(nèi)容的完整性,確保在遇到磁盤故障和網(wǎng)絡問題時降低對版本庫的破壞。
image.png
SVN的分支介紹
我們首先要創(chuàng)建一個分支,然后checkout分支。checkout完成后我們會發(fā)現(xiàn)分支branch在我們本地,其實就是對trunk(主干)的一個完全拷貝。
我們本地會多出一個branch的文件夾,目錄結構跟trunk(主干)一模一樣。
那么怎么樣來進行并行開發(fā)呢?試想一下,分支在開發(fā)的同時,trunk(主干)也在開發(fā),最后trunk(主干)開發(fā)完成需要合并到主分支時,可能會存在一堆的沖突。這個怎么避免呢?是這樣,在并行開發(fā)的同時,我們也要時常更新本地trunk(主干)并且把trunk合并到branch上,保持分支與倉庫的實時更新,這樣才不會產(chǎn)生大量沖突。等功能開發(fā)和測試完成,就可以把branch內(nèi)容合并到trunk(主干)中,然后刪除branch,提交trunk(主干)。這樣才是一個完整的svn分支開發(fā)流程。我們注意到,本地的branch其實是對trunk的一個完全拷貝。會發(fā)現(xiàn),使用SVN的分支開發(fā)還是挺麻煩的。
git分支的分支介紹
git分支與SVN分支顯然大不一樣。git創(chuàng)建一個本地分支只需要在初始化一個本地git倉庫后執(zhí)行 git branch <branchName>,就可以創(chuàng)建一個名字為branchName的本地分支。使用checkout命令可以切換分支,這個在上篇已經(jīng)介紹過了。我們會發(fā)現(xiàn),創(chuàng)建分支過后,本地倉庫并沒有多出分支文件夾,也就是說git創(chuàng)建分支并沒有對主分支進行完全拷貝,這個跟svn是大便不相同的。在git分支上進行的操作,提交過后,可以合并到主分支上,合并完成后,創(chuàng)建的git分支即可刪除。
在這里多說一下,使用git作為版本控制,每開發(fā)一個新功能或者修復一個bug都應該新建一個分支來進行操作。不然幾個模塊并行開發(fā)的時候,你都在主分支上操作,到時候有一個功能好了,需要提交測試,你應該怎么提交?需要人工識別哪些文件能提交,哪些文件不能提交。這顯然不是一種好的做法。好的做法是每個功能模塊使用分支進行開發(fā),功能好了過后在分支提交然后往主分支master上合并,這樣不用糾結那些文件能有提交推送哪些不能。
理解下 Git 工作區(qū)、暫存區(qū)和版本庫概念:
工作區(qū):圖中左側的,就是你在電腦里能看到的目錄。
暫存區(qū):圖中右側的,版本庫下面的,英文叫 stage 或 index。一般存放在 .git 目錄下的 index 文件(.git/index)中,所以我們把暫存區(qū)有時也叫作索引(index)。
版本庫:工作區(qū)有一個隱藏目錄 .git,這個不算工作區(qū),而是 Git 的版本庫。
image.png
git一般會存在一些這樣的分支:
image.png
master(線上),develop(開發(fā)),release(預發(fā)布),hotfix(線上bug修復)這四種常用的分支
master: 主分支;主要是穩(wěn)定的版本分支,正式發(fā)布的版本都從Master拉。develop:開發(fā)分支;更新和變動最頻繁的分支,正常情況下開發(fā)都是在Develop分支上進行的。release:預發(fā)行分支;一般來說,代表一個版本的功能全部開發(fā)完成后遞交測試,測試出Bug后進行修復的分支。features: 功能分支; 其實Features不是一個分支,而是一個分支文件夾。里面包含了每個程序員開發(fā)的功能點。Feature開發(fā)完成后合入Develop分支。hotfix: 緊急故障修復分支(如現(xiàn)場故障),內(nèi)部分支,從master拉出此分支,merge到master和develop分支。最希望不會被創(chuàng)建的分支;這個分支的存在是在已經(jīng)正式上線的版本中,發(fā)現(xiàn)了重大Bug進行修復的分支。
git分支就是在版本控制過程中,使用多條線同時推進多個任務。
每個新功能位于一個自己的分支,這樣可以push到中央倉庫以備份和協(xié)作。但功能分支不是從master分支上拉出來的新分支,而是使用develop分支作為父分支。當新功能完成時,合并回develop分支。新功能的提交不直接與master交互。
一旦develop分支上的功能到了發(fā)布日期,就從develop分支分一個發(fā)布分支(一般叫release)。
release分支用于預發(fā)布測試,所以從這個時間點開始后新的功能不再加到這個分支上,release分支只應該做bug修復、文檔生成和其他面向發(fā)布的任務。一旦release測試完畢并準備發(fā)布后,將其合并到master分支并分配一個版本號打上Tag。另外,release上做的bug修改要合并回develop分支。
使用一個專門用于發(fā)布的分支,是一個團隊可以在完善發(fā)布版本的同時,另一個團隊繼續(xù)開發(fā)下一個版本功能。
一個項目里,主分支master分為幾部分分支feature,處理不同的部分,如,一個游戲項目,可以分出搞圖像的、搞運算的、操作的等分支。在公司里,每個團隊處理屬于自己的分支,不同部門分支互不干擾,也不影響主分支,假如某個分支出現(xiàn)嚴重錯誤,只需要刪除這個分支重新來過,其他分支沒影響。當一個分支開發(fā)完成,就把他合并到主干中,全部分支開發(fā)完后,最終形成整個項目。
然而,主干master也可能出現(xiàn)bug,這個時候就有一個host_fix分支(臨時分支,用來修復bug,修復完及時合并為主干)
二. 分支的好處
- 同時并行推進多個功能開發(fā),提高開發(fā)效率
- 各個分支在開發(fā)過程中,如果某一個分支開發(fā)失敗,不會對其他分支有任何影響。失敗的分支刪除重新開發(fā)即可
三. 分支操作-(這里主要以gitlab為例進行說明)
這里講的是終端操作,很多第三方軟件有自己的快捷鍵,不做介紹。
下面是從dev拉取分支,拉取的時候選擇的是dev,然后代碼拉到本地。
- step1:創(chuàng)建分支
- step2:查看分支 并且切換到該分支
- step3:拉取需要合并的分支代碼比如dev分支
- step4:在當前分支下 合并dev
- step5:提交合并的代碼,到自己的遠程分支
- step6:推送 提交到服務器
- step7:然后去第三方平臺
gitlab上,去將自己分支代碼合并至dev,告訴審核人去審核和合并。
step1:創(chuàng)建分支 或者在第三方軟件上面操作
git branch 分支名
step2:查看分支 切換到該分支 或者在第三方軟件上面操作
git branch -v // git branch 這兩個命令一樣 查看分支,有個*標記的為當前分支
// git branch -a 列出所有分支
git checkout 分支名 //切換到該分支
注釋:這時候,已經(jīng)是當前分支了,去寫代碼了。。。開發(fā)完成,就再進行下面的操作。
step3:拉取需要合并的分支代碼比如dev分支 或者在第三方軟件上面操作
git checkout dev
git pull
step4:在當前分支下 合并dev
git checkout 分支名
git merge dev
這時候有沖突或者問題,需要修改沖突和問題
step5:提交合并的代碼,到自己的遠程分支
git add . #添加所有改動文件到緩存
git commit -m "注釋描述" #提交
git status #查看修改文件后的狀態(tài)
step6:推送 提交到服務器
git push
step7:然后去第三方平臺gitlab上,去將自己分支代碼合并至dev,告訴審核人去審核和合并。
下面有個step7操作的例子
①在界面中點擊New merge request新建一個 Merge Request
image.png
②左側選擇需要合并的show-overflow-tooltip分支為當前分支(Source branch),在右側選擇合并到的目標分支(Target branch)設置為dev,確認無誤,點擊Compare branches and continue提交
image.png
在界面中,單擊提交合并按鈕來Submit merge request進行合并。在gitlab中提交合并請求,Assignee 選中項目管理員。然后你就可以看到狀態(tài)被修改為合并了,你在分支中所有的修改將會合并到你希望合并到的分支中去了。
image.png
③最后,可以看到這個分支合并merge,可以直接粘貼在瀏覽器里面的地址,發(fā)給合并的負責人(假如他沒看到),告訴他需要合并。
image.png
經(jīng)過以上五個步驟之后我們在gitlab上就可以看到我們所做的改動了~
四:我們在項目里面的具體操作實例:
一:假如我們現(xiàn)在在自己本地的分支mapOrder上開發(fā),剛開發(fā)完項目,執(zhí)行了下列命令,將本地分支mapOrder代碼,推到遠端分支mapOrder上:
git add .
git commit -m '提交的備注信息'
git status #查看修改文件后的狀態(tài)
git push
二:現(xiàn)將主線v1.0.0分支合并到自己的分支本地mapOrder,解決完問題,再去提交和推送到遠端mapOrder,然后再去gitLab上創(chuàng)建合并請求,相關負責人去合并。
我們一開始一般是在自己的分支環(huán)境下,所以需要先拉取遠端的代碼,合并代碼,解決沖突等問題
## 1,查看分支列表 *標記的就是當前分支
$ git branch -a
## 2,切換到v1.0.0分支
$ git checkout v1.0.0
## 3,拉取v1.0.0 分支 代碼
$ git pull
## 4,切換到本地 mapOrder 分支
$ git checkout mapOrder
## 5,合并本地 v1.0.0 到 本地 mapOrder #或者在sourcetree上操作如下面的圖
git-merge命令是用于從指定的分支(v1.0.0) 合并到 當前分支(mapOrder)的操作
$ git merge v1.0.0
注意:
1,組件化的項目,需要刪除pod.lock,然后 pod install。
2,此時,可能會有沖突和問題,解決完成,再進行去下操作。
$ git add . #加到緩存區(qū)
$ git commit -m '提交的備注信息' #提交到本地倉庫
$ git status #查看修改文件后的狀態(tài)
## 6,在本地分支mapOrder的環(huán)境下,將 本地合并代碼 推到遠程mapOrder
$ git push
## 7,最后,去gitLab上創(chuàng)建合并請求。就是把遠端 mapOrder分支 合到遠端 v1.0.0 分支上去。
要注意:主要 source【mapOrder】和 taget【v1.0.0】,以及指定相關負責人,相關負責人去合并。
這一步可以看上面的 【 三. 分支操作-(這里主要以gitlab為例進行說明)】里面的【step7】 操作的例子。
上面第5步也可以在sourcetree上操作,sourcetree上的操作如下圖(##5,合并本地 v1.0.0 到 本地 mapOrder):需要在mapOrder分支環(huán)境下,右擊v1.0.0 合并到 mapOrder。
image.png
五 :git更改遠程倉庫指向 remote url
在我們的遠程倉庫地址變更后(比如:開發(fā)了一段時間,然后Git第三方的代碼托管平臺需要把項目換到另一個平臺或新地址(比如從gitlab一個項目地址換到gitlab上另外一個,或者從GitHub換到gitee),那么我們寫好的代碼怎么辦呢?怎么和新的代碼倉庫聯(lián)系起來,拉取和推送等管理呢?)
解決:更改遠程倉庫指向,就行了
git remote set-url origin 項目新的URL
//舉例子 git remote set-url origin git@github.com:test/thinkphp.git







