0.引言
本文參考最后的幾篇文章,將git的分支管理整理如下。學習git的分支管理將可以版本進行靈活有效的控制。
1.如何建立與合並分支
1.1分支的新建與合並指令
新建分支 newBranch,並進入新分支:
$ git checkout -b newBranch
相當於:
$ git branch newBranch
$ git checkout newBranch
合並分支 mergeBranch,例如要把mergeBranch,合並入master:
$ git checkout master $ git merge mergeBranch
合並后,master和mergeBranch都指向同一個版本,可以刪除掉mergeBranch了:
$ git branch -d mergeBranch
1.2 分支創建與合並的實例
Task:
- 開發某項目。
- 為實現某個新的需求,創建一個分支iss53。
- 在這個分支上開展工作。
假設臨時有個很嚴重的其他問題需要緊急修補,按照下面的方式處理:
- 返回master分支。
- 為這次緊急修補建立一個新分支hotfix,並在其中修復問題。
- 通過測試后,回到服務器所在的master分支,將修補分支合並進來,然后再推送到服務器上。
- 刪除hotfix
- 切換到之前實現新需求的分支iss53,繼續工作。
工作完成以后,將分支iss53合並入master
如果iss53與hotfix工作沒有沖突,則合並成功,如果有沖突則需要再進行處理判斷后,再合並。
Do:
1、假設當前,master更新為C2版本:
2、為實現某功能創建iss53分支,創建index.html,並上傳
這個時候,狀態是這樣的:
3、緊急任務來了,要先返回master分支
4、現在接到進行緊急修改的要求,然后創建hotfix
5、進行了相應的開發,包括修改index.html(注意,在iss53中也進行了修改)
然后git push origin hotfix。
Git 會把工作目錄的內容恢復為檢出某分支時它所指向的那個提交對象的快照。它會自動添加、刪除和修改文件以確保目錄的內容和你當時提交時完全一樣。
於是當前的狀態是:
6、當分支hotfix的內容測試通過確認后,就可以合並到master中,並刪除hotfix
如果順着一個分支走下去可以到達另一個分支的話,那么 Git 在合並兩者時,只會簡單地把指針右移,因為這種單線的歷史分支不存在任何需要解決的分歧,所以這種合並過程可以稱為快進(Fast forward)。
現在最新的修改已經合並到master分支了。可以發布啦。
接下來刪除hotfix
7、現在我們回到iss35繼續工作
我們繼續推進iss35:
8、現在接下來要合並master和iss53
合並后,刪除iss53分支,即可。
請注意,這次合並操作的底層實現,並不同於之前 hotfix
的並入方式。因為這次你的開發歷史是從更早的地方開始分叉的。由於當前 master
分支所指向的提交對象(C4)並不是 iss53
分支的直接祖先,Git 不得不進行一些額外處理。就此例而言,Git 會用兩個分支的末端(C4 和 C5)以及它們的共同祖先(C2)進行一次簡單的三方合並計算。
這次,Git 沒有簡單地把分支指針右移,而是對三方合並后的結果重新做一個新的快照,並自動創建一個指向它的提交對象(C6)(見圖 3-17)。這個提交對象比較特殊,它有兩個祖先(C4 和 C5)。
值得一提的是 Git 可以自己裁決哪個共同祖先才是最佳合並基礎;這和 CVS 或 Subversion(1.5 以后的版本)不同,它們需要開發者手工指定合並基礎。所以此特性讓 Git 的合並操作比其他系統都要簡單不少。
9、但是如果在不同的分支中都修改了同一個文件的同一部分,Git 就無法干凈地把兩者合到一起(譯注:邏輯上說,這種問題只能由人來裁決。)。如果你在解決問題 #53 的過程中修改了 hotfix
中修改的部分,則會出現:
我們先看一下狀態:
接下來我們可以打開 index.html
git 已經自動對其做了區分,HEAD表示master分支的內容,=====下面的是iss53分支做的修改
你可以對其再做調整和修改。
再用git add index.html,git commit表示他們已經解決沖突。
然后再融合和刪除iss53分支。完成工作。
也可以使用mergetool:
2. Git分支在實際項目中的靈活運用
這是Git版本控制的分支管理總體圖:
其中最重要的是主分支:
- master:用來版本發布,主要反映當前線上運行的代碼。
- develop:作為開發分支,用來存放最新開發的代碼,有時候會叫它“集成分支”。
develop分支用來存放開發完成的代碼,當develop分支上的代碼測試沒有問題后,merge到master分支上,並發布。
輔助分支:
- feature branches
feature分支也可以叫做主題分支。例如在新版中要開發的新功能,可以用feature來存放。名字可以另外取,例如要增加insert和search功能,可以增加insertFeature和searcheFeature的分支,開發好后,再分別merge到develop分支中。
從 develop 分支建一個 feature 分支,並切換到 feature 分支
$ git checkout -b myfeature develop Switched to a new branch "myfeature"
合並feature 分支到 develop
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff myfeature Updating ea1b82a..05e9557 (Summary of changes) $ git branch -d myfeature Deleted branch myfeature (was 05e9557). $ git push origin develop
其中--no-ff 的參數,ff表示fastforward,--no--ff,就表示會對歷史的分支做一個新的提交對象。加參數和不加參數的區別如下:(可以使用 sourceTree 或者命令git log --graph
查看)
- release branches
這個分支可以是來自develop;必須合並到develop和master。release分支可以理解為更多的是作為版本控制、缺陷鏡像修復和最后發布前的復查工作。
創建一個realase分支
$ git checkout -b release-1.2 develop Switched to a new branch "release-1.2" $ ./bump-version.sh 1.2 Files modified successfully, version bumped to 1.2. $ git commit -a -m "Bumped version number to 1.2" [release-1.2 74d9424] Bumped version number to 1.2 1 files changed, 1 insertions(+), 1 deletions(-)
這里的bump-version.sh ,只是一個虛擬的腳本,是要求讀者自己去編寫這樣的腳本,實現相應的地方都統一更改版本號。
完成release分支:
$ git checkout master Switched to branch 'master' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes) $ git tag -a 1.2
融合到develop分支
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes)
刪除release分支
$ git branch -d release-1.2 Deleted branch release-1.2 (was ff452fe).
- hotfix branches
這個是一個需要緊急修復bug的分支。當線上產品有bug,我們可以開一個hotfix分支,修復完bug后,再merge,刪除。
它來自master,融合向develop和master。
關系如下:
具體代碼如下:
創建hotfix分支:
$ git checkout -b hotfix-1.2.1 master Switched to a new branch "hotfix-1.2.1" $ ./bump-version.sh 1.2.1 Files modified successfully, version bumped to 1.2.1. $ git commit -a -m "Bumped version number to 1.2.1" [hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1 1 files changed, 1 insertions(+), 1 deletions(-)
$ git commit -m "Fixed severe production problem" [hotfix-1.2.1 abbe5d6] Fixed severe production problem 5 files changed, 32 insertions(+), 17 deletions(-)
完成了hotfix分支:
$ git checkout master Switched to branch 'master' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes) $ git tag -a 1.2.1
合並到develop分支
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff hotfix-1.2.1 Merge made by recursive. (Summary of changes)
最后刪除hotfix分支
$ git branch -d hotfix-1.2.1 Deleted branch hotfix-1.2.1 (was abbe5d6).
參考:
【1】 http://nvie.com/posts/a-successful-git-branching-model/
【2】http://blog.jobbole.com/109466/
【3】https://git-scm.com/book/zh/v1/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6