對Git Flow作點微創新 (2)

昨天改了git flow feature的實現,提供一個選項,finish時再也不保留feature分支上的提交歷史(http://www.jiangyouxin.net/2013/02/12/git_flow_1.html)。今天的主題是release分支。 html

在原版git flow的實現中,release分支與feature分支很像,都是基於develop建立,並在結束時合併回develop。所不一樣的是,release分支還要合併到master分支並打TAG。注意這裏的次序是合併(git merge no-ff)在前,TAG在後,這在兩個方面都是有點問題的: git

(1) 若是master上,存在沒有合併到develop和release分支的修改,則會有災難性後果。
固然,若是全部開發者都嚴格遵照git flow的規範,這種狀況不會出現;但git flow的原版中並無對此作sanity檢查。在準備發佈時,release分支上的代碼是通過測試的,但這個代碼與master(若是master有過修改)的合併結果是未經測試的。在把TAG打在合併結點上,就得保證合併先後代碼是一致的,不然就有些草率了。 安全

(2) TAG是極強的標誌(在gitk中有醒目的顯示),足以區分版本邊界;沒有必要再單首創建一個merge結點。
在nvie的原文中有一句話,能夠用來解釋他對--no-ff的偏心:the release branch is merged into master (since every commit on master is a new release by definition, remember)
也就是說,原做者指望每一次版本發佈,都在master分支上產生一個(有且只有一個)提交結點,--no-ff就是用來建立這個結點的。遺憾的是,這在SVN等線性提交的版本管理系統中成立,在git中則不成立。git中merge結點的兩個父親是對等的,整條被合併的release分支(而不只僅是最後那個合併結點)都是master分支的一部分,在這一點上,nvie畫的那張圖把他本身誤導了: 測試

上圖的master分支看上去特別乾淨,只有少數幾個結點,每一個結點都是一個發佈版本。但其實這張圖裏,除了develop分支最下面的那個黃色結點以外,都在master分支上。master只是一個指向最新發布版本的引用而已,要區分哪些結點表明發佈版本,只能靠TAG。因此這裏--no-ff是白費工夫的。 spa

在我對git flow的修改中,這裏git merge的參數反過來了,用的是--ff-only。若是出現上面的狀況(1),merge會失敗,此時報一個錯誤信息來警示用戶(有的時候出現這條錯誤信息是正常的,詳見下一篇 http://www.jiangyouxin.net/2013/02/14/git_flow_3.html);若是merge成功,因爲是Fast Forward,在當前位置打TAG是安全的.net

另外一個問題,是git flow原做者可能沒有去考慮,但廠裏的開發卻常有的狀況:release分支建立以後,由於種種緣由,該版本不須要再發布,但修改須要保留,下次發佈時間再議。git flow release finish命令(git flow一個讓人很不爽的地方就是命令太長)有一個參數-n(不打TAG),跟這個需求最接近。但光不打TAG不行,還得不向master合併才行。因此在個人版本中,-n的語義作了修改,至關於取消發佈,release分支退化爲feature分支,只向develop合併。 htm

而後就是和feature分支相似的問題了:release分支的提交歷史是否須要保留?我以爲大部分狀況是須要保留的。release分支在版本發佈以前建立,上面的提交大可能是bug fix,並且各個提交之間的關聯性較小,這一點與feature分支是大不同的。git flow原版對release分支也提供了-S(squash)參數,但遺憾的是,實現也是有問題的;由於我如今也沒把正確的實現寫出來,這個就等之後有空再說了。 開發

相關文章
相關標籤/搜索