​Git flow 開發流程

2015-05-12 23:26:00
hainuo
转贴:
ihower { blogging }
2205
摘要:git-flow 开发流程 转贴过来方便自己理解
# Git flow 開發流程 [February 13, 2011](https://ihower.tw/blog/archives/5140 "Permalink to Git flow 開發流程")[Git](https://ihower.tw/blog/archives/category/git)[ihower](https://ihower.tw/blog/archives/author/hower "View all posts by ihower") Update: 2011/3/19 受邀有場分享 [Git介紹,使用與開發流程 at Facebook 軟體開發團隊工具心得分享](https://ihower.tw/blog/archives/5391) 大家都知道 Git 開 branch 很方便,非常鼓勵 topic branch,但有沒有一套模型流程告訴我們應該怎麼管理 branch 呢? 有人便整理出一套最佳實踐慣例 [A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/),[我們團隊](http://optimisdev.com/)就採用了這套流程。簡單來說,他將 branch 分成兩個主要分支,三種支援性分支: [![](http://ihower.tw/blog/wp-content/uploads/2011/02/Screen-shot-2009-12-24-at-11.32.03.png)](http://nvie.com/posts/a-successful-git-branching-model/) * 主要分支 * master: 永遠處在 production-ready 狀態 * develop: 最新的下次發佈開發狀態 * 支援性分支 作者還提供了 [git-flow](https://github.com/nvie/gitflow) 指令工具幫助我們很容易的實踐,用法如下: 首先是初始化動作: `git flow init `初始化動作會問你一些問題,大抵是命名慣例: ``` No branches exist yet. Base branches must be created now. Branch name for production releases: [master] Branch name for "next release" development: [develop] How to name your supporting branch prefixes? Feature branches? [feature/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] ``` 設定完之後,預設的 branch 就變成 develop 了。有任何開發,一律都先開 branch: `git flow feature start some_awesome_feature` (以此類推 `git flow release` 和 `git flow hotfix`) 完成之後輸入 `git flow feature finish some_awesome_feature` 就會合併回 `develop` 並幫你刪除這個 (local) branch。 ### 關於 remote branch 這個 git-flow 工具並沒有幫我們處理 remote branch,所以如果你的 branch 要 push 出去分享給別人,就要自己打 git 指令啦 同事留言說有支援啦: push 一個 feature branch 到遠端: `git flow feature publish some_awesome_feature` 或 `git push origin feature/some_awesome_feature` 追蹤一個遠端的 branch: `git flow feature track some_awesome_feature` 或 `git checkout -b feature/some_awesome_feature -t origin/feature/some_awesome_feature` 刪除遠端的 branch:` git push origin :feature/some_awesome_feature ` [我們](http://optimisdev.com/)還碰到一個問題是輸入 `git flow feature finish` 時出現以下錯誤: ``` warning: not deleting branch 'feature/some_awesome_feature' that is not yet merged to 'refs/remotes/origin/feature/some_awesome_feature', even though it is merged to HEAD. error: The branch 'feature/some_awesome_feature' is not fully merged. If you are sure you want to delete it, run 'git branch -D feature/some_awesome_feature'. ``` 原因是這個 feature branch 一開始是從遠端 checkout 出來的,以及這個 feature branch 有 commit 沒有 push 回去 ,所以 `git flow` 不敢幫你刪除 local branch,這時候其實 merge 動作已經完成了,所以你可以手動輸入 `git branch -D feature/some_awesome_feature` 強制刪除 local branch 即可。 (小結論:git-flow 只是個輔助工具,了解 git 還是必要的) ### 關於 feature branch 的合併 如果是開發時間比較久的 feature branch,很可能會因為 1. 不定時的 merge develop 與新版同步 2. 實驗性質的修改 3. 需求的變更 等等因素,而讓這個 feature branch 的 commit 記錄變成髒髒的,這時候[我們](http://optimisdev.com/)會用以下的方式來做 merge 動作: 1. 先對 feature branch 做 `git rebase develop`。會很苦,但是弄完會很有成就感,整個 branch commit history 會變成很乾淨。請學 interactive mode,可以讓你拿掉一些 commit、合併或修改,你也可以 rebase 多次直到滿意為止。 2. 在從 develop bracnh 做 `git merge feature/some_awesome_feature –no-ff`,`–no-ff` 的意思是會強制留一個 merge commit log 記錄,這可以讓 commit tree 看清楚發生了 merge 動作。(因為我們剛做了 rebase,而 git 預設的合併模式是 fast-forward,所以如果不加 –no-ff 是不會有 merge commit 的) 這個 merge commit 的另一個額外方便之處是,如果想要 reset/revert 整個 branch 只要 reset/revert 這個 commit 就可以了。 3. 如果此 feature branch 有 remote branch,要先砍掉 `git push origin :feature/some_awesome_feature` 再 `git push origin develop` (這是因為 rebase 一個已經 push 出去的 repository,然後又把修改的 history push 出去,會造成超級大災難啊~) 先 rebase 再 merge –no-ff 這樣做的好處到底是什麼? 看圖體會一下吧: ![](http://ihower.tw/blog/wp-content/uploads/2011/02/git-branch1.jpg "git-branch") 每一次的 merge 就代表了一個 feature 完成,也可以很清楚看到這個 feature branch 底下包含哪些 commit。 對了,如果有用 Github 的話,請記得務必用一用它的 [pull request](https://github.com/blog/785-pull-request-diff-comments) 功能,我們會在 branch 完成後發一個 pull request,好讓大家可以對一整個 branch 做 code review 留言。 註:什麼是 rebase 可以參考舊作: [Git 版本控制系統(3) 還沒 push 前可以做的事](https://ihower.tw/blog/archives/2622)