gitflow 流程是很是專業並且標準的 git 處理流程,由於要學習其核心思想和應用,故有此文章系列,本文章系列會分爲兩部分,第一部分學習基本的內容和基礎的流程,第二部分會學習其餘流程和hotfix,release 和 tag 之類的高級用法。html
項目中長期存在的兩個分支:git
在 gitlab 裏面能夠設置這2個分支的權限是受保護的,只容許某些人才能進行操做。
其它分支爲短時間分支,其完成功能開發以後須要刪除:github
feature/*
:特性(功能)分支,用於開發新的功能,不一樣的功能建立不一樣的功能分支,功能分支開發完成並自測經過以後,須要合併到 develop 分支,以後刪除該分支。bugfix/*
:bug修復分支,用於修復不緊急的bug,普通bug均須要建立bugfix分支開發,開發完成自測沒問題後合併到 develop 分支後,刪除該分支。release/*
:發佈分支,用於代碼上線準備,該分支從develop分支建立,建立以後由測試同窗發佈到測試環境進行測試,測試過程當中發現bug須要開發人員在該release分支上進行bug修復,全部bug修復完後,在上線以前,須要合併該release分支到master分支和develop分支。hotfix/*
:緊急bug修復分支,該分支只有在緊急狀況下使用,從master分支建立,用於緊急修復線上bug,修復完成後,須要合併該分支到master分支以便上線,同時須要再合併到develop分支。標準的流程以下圖:npm
由於這些圖涉及的流程太多,一會兒很難接受,因此須要逐個分解來學習。ruby
項目背景:有一羣人共同開發一個 blog 系統。服務器
須要角色:網絡
項目人員:app
項目分工:less
首先學習一個基本的流程,相似下圖,可是本次暫時不涉及 tag 處理:koa
先建立一個服務端代碼倉庫,用 gitlab 來管理這個倉庫,名字叫作 blog-project,倉庫地址是git@xxx服務器地址/blog-project.git
。
項目剛開始,分支並不須要那麼多,在代碼倉庫裏只須要建兩個分支便可:
// 遠程服務器上代碼 master // 默認主分支(受保護) develop // 開發分支(受保護)
備註:
開發者 clone 這個庫下來到本地:
// git 命令 git clone git@xxx服務器地址/blog-project.git // clone 後每一個人的本地倉庫都以下: master // 默認主分支 develop // 開發分支
備註:
項目正式開始後,咱們須要分工開發,有如下兩種狀況咱們會遇到:
人手充足,時間充足,各自功能都能歸到各人頭上,而且可以很好的開發完成。
feature/articles
功能。feature/login
功能。feature/login
和feature/articles
功能都成爲共享分支,全部人都參與開發// 開發者 a 執行 git 命令 // 建立feature/articles 功能分支,並直接切換到該分支上進行開發 git checkout -b feature/articles // 開發者 b 執行 git 命令 // 建立feature/login 功能分支,並直接切換到該分支上進行開發 git checkout -b feature/login
那麼如今開發者 a 和 b 本地的代碼庫以下:
// 開發者 a master // 默認主分支 develop // 開發分支 feature/articles // 功能分支 articles 模塊 // 開發者 b master // 默認主分支 develop // 開發分支 feature/login // 功能分支 login 模塊
備註:
開發完成後各自提交代碼到遠端代碼倉庫:
// 開發者 a git add . // 添加當前目錄全部文件的改動到本地 git 倉庫 git commit --m "Add user API" // 須要按照 commit 規範,這個只是樣例 git push origin feature/articles // // 開發者 b git add . // 添加當前目錄全部文件的改動到本地 git 倉庫 git commit --m "Add user API" // 須要按照 commit 規範,這個只是樣例 git push origin feature/login
備註:
git add
是添加文件到本地git倉庫緩衝區,換句話來講,是將有改動的文件放在本地的 git 代碼倉庫中,以便記錄版本和提交版本。
// 開發者 a 執行命令,切換到相應到分支 git fetch // 取回遠端全部分支(branch)的更新 git checkout feature/articles // a 切換到feature/articles分支 git pull origin feature/articles // 拉取遠端feature/articles分支的全部更新到本地代碼 git checkout feature/login // a 切換到feature/login分支 git pull origin feature/login // 拉取遠端feature/login分支的全部更新到本地代碼 // 開發者 a 的本地代碼 master // 默認主分支 develop // 開發分支 feature/articles // 功能分支 articles 模塊 feature/login // 功能分支 login 模塊
// 開發者 b 執行命令,切換到相應到分支 git fetch // 取回遠端全部分支(branch)的更新 git checkout feature/articles // b 切換到feature/articles分支 git pull origin feature/articles // 拉取遠端feature/articles分支的全部更新到本地代碼 git checkout feature/login // b 切換到feature/login分支 git pull origin feature/login // 拉取遠端feature/login分支的全部更新到本地代碼 // 開發者 b 的本地代碼 master // 默認主分支 develop // 開發分支 feature/articles // 功能分支 articles 模塊 feature/login // 功能分支 login 模塊
解釋:
feature/articles
分支和feature/login
分支都會由開發者 a 或者 b 同時開發,由於是在共享分支開發,全部有可能會有共享衝突的問題, 在代碼開發以前, 應先更新好本地代碼倉庫,能夠減小衝突的發生。git merge conflict
)備註:
這裏先使用 fetch 的用意在這裏:與git pull
相比git fetch
至關因而從遠程獲取最新版本到本地,但不會自動merge。若是須要有選擇的合併git fetch
是更好的選擇。
git pull
把過程的細節都隱藏了起來,以致於你不用去了解git中各類類型分支的區別和使用方法。固然,多數時候這是沒問題的,但一旦代碼有問題,你很難找到出錯的地方。git pull
,多用git fetch
和merge
。開發者本地進行來基本的測試驗證,確認功能知足需求,而且沒有大的問題,而後會由開發者 leader 在 gitlab 上進行分支合併:
由開發者 leader c 來進行合併,將feature/articles
和 feature/login
分支合併到 develop 分支,合併完成後刪除源分支(feature/articles
和 feature/login
)。
至此使用基本流程完成開發。
發生衝突的地方不止 pull 還有 merge 和 rebase,只要發生合併的地方就可能會有衝突的發生。
如下例子以 git pull
來樣例:
// git pull 拉取代碼的時候發生衝突了 git pull XXXXX // 報錯提示 Auto-merging test.txt CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result.
// 衝突文件 test.txt 內容 a123 <<<<<<< HEAD b789 ======= b45678910 >>>>>>> 6853e5ff961e684d3a6c02d4d06183b5ff330dcc c
解釋:
其中:衝突標記<<<<<<<
與=======
之間的內容是個人修改,=======
與>>>>>>>
之間的內容是別人的修改。
備註:
git status
命令查看。// 執行 git 命令 git status // 輸出提示 On branch master Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) // 你能夠放棄合併,git merge --abort 選項會嘗試恢復到你運行合併前的狀態。 You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) // 衝突的文件 both modified: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
git diff --base
來查看文件在兩邊是如何改動的。// 執行 git 命令 git diff --base -b // -b 是爲了去除空白內容 // 輸出信息 * Unmerged path hello.rb // 結果爲git格式的diff。 // 進行比較的是,a版本的f1(即變更前)和b版本的f1(即變更後)。 diff --git a/hello.rb b/hello.rb index ac51efd..44d0a25 100755 // "---"表示變更前的文件,"+++"表示變更後的文件。 --- a/hello.rb +++ b/hello.rb // 前面的"-1,7"分紅三個部分:減號表示第一個文件(即f1),"1"表示第1行,"7"表示連續7行。合在一塊兒,就表示下面是第一個文件從第1行開始的連續7行。一樣的,"+1,8"表示變更後,成爲第二個文件從第1行開始的連續9行 @@ -1,7 +1,8 @@ // 文件內容的每一行最前面,還有一個標記位。若是爲空,表示該行無變化;若是是感嘆號(!),表示該行有改動;若是是減號(-),表示該行被刪除;若是是加號(+),表示該行爲新增。 #! /usr/bin/env ruby +# prints out a greeting def hello - puts 'hello world' + puts 'hello mundo' end hello()
若是有強烈意願只保留本身的代碼的狀況下也是能夠的:
gitpush origin master --force
或gitpush origin master -f
。可是這種方式存在覆蓋掉其餘人提交的危險,當肯定不會影響到其餘人提交的狀況下可使用,好比使用gitcommit –amend
修改提交日誌等狀況。爲何須要 commit 規範?主要是爲了看清楚每次 commit 的內容,清楚知道 commit 變更的地方,從而方便排錯和控制代碼。
// 提交類型 feat: 添加新特性 fix: 修復bug docs: 僅僅修改了文檔 style: 僅僅修改了空格、格式縮進、都好等等,不改變代碼邏輯 refactor: 代碼重構,沒有加新功能或者修復bug perf: 增長代碼進行性能測試 test: 增長測試用例 chore: 改變構建流程、或者增長依賴庫、工具等 // 提交範圍 scope scope用於說明 commit 影響的範圍,好比數據層、控制層、視圖層等等,視項目不一樣而不一樣。 // 提交的subject內容 subject是 commit 目的的簡短描述,不超過50個字符。 以動詞開頭,使用第一人稱如今時,好比change,而不是changed或changes 第一個字母小寫,結尾不加句號(.) // 提交的 body 內容 Body 部分是對本次 commit 的詳細描述,能夠分紅多行。
npm install -g commitizen
這個是一個格式化commit message的工具。npm install -g conventional-changelog-cli
這個是生成changelog的工具,changelog 是爲了將這些格式化的 commit message 生成一個 CHANGELOG.md
文件的,這個文件能夠規範看到提交的內容(如上圖一個標準且優美的 git 提交記錄圖)。// 執行git 命令 git cz // 輸出 cz-cli@2.10.1, cz-conventional-changelog@2.1.0 Line 1 will be cropped at 100 characters. All other lines will be wrapped after 100 characters. // 提示輸入你的 commit類型,他會彈出提示給你選擇 ? Select the type of change that you're committing: fix: A bug fix // 提示輸入你的 scope類型,沒有能夠跳過 ? What is the scope of this change (e.g. component or file name)? (press enter to skip) test // 提示輸入你的 subject,即標題 ? Write a short, imperative tense description of the change: 我來測試這個 commit 格式 // 提示輸入你的 body 內容,就是詳細信息 ? Provide a longer description of the change: (press enter to skip) 詳細 ? Are there any breaking changes? No // 當你有使用 issues 的時候就會關聯到 issues ? Does this change affect any open issues? No [master a4fd22c] fix(test): 我來測試這個 commit 格式 3 files changed, 14 insertions(+), 1 deletion(-)
提交記錄會變成這樣(使用 git log
命令能夠查看):
// 輸出結果是 fix(test): 我來測試這個 commit 格式 詳細
至於 CHANGELOG.md
內容則以下:
<a name="1.0.0"></a> # 1.0.0 (2017-03-05) ### Bug Fixes * fixed ([a9c3110](https://192.168.2.107/zpu/hello-koa/commits/a9c3110)) ### Features * add something ([53becaa](https://192.168.2.107/zpu/hello-koa/commits/53becaa))
解析 md 文件以後,會很清晰的知道每一個版本或者提交都負責了那些內容,相似這樣:
本文參考到的資料地址:
文章轉自 gitflow 開發流程學習(第一部分)