Git 工作流

中心化的工作流

優(yōu)勢

  • 首先它讓每個開發(fā)者都有自己的本地的完整項目副本。隔離的環(huán)境使得每個開發(fā)都的工作獨立于項目的其它修改 —— 他們可以在自己的本地倉庫中添加提交,完全無視上游的開發(fā),直到需要的時候。
  • 其次,它讓你接觸到了 Git 分支和合并模型。Git 分支被設(shè)計為故障安全的機制,用來在倉庫之間整合代碼和共享更改。

如何工作

  • 中心化的工作將中央倉庫作為項目中所有修改的唯一入口。默認的開發(fā)分支叫做 master,所有的更改都被提交到這個分支。這種工作流不需要 master 之外的其它分支。
  • 開發(fā)者將中央倉庫克隆到本地后開始工作。在他們的本地項目副本中,他們可以像 SVN 一樣修改文件和提交更改;不過這些新的提交被保存在本地 —— 它們和中央倉庫完全隔離。這使得開發(fā)者可以將和上游的同步推遲到他們方便的時候。
  • 為了向官方項目發(fā)布修改,開發(fā)者將他們本地 master 分支“推送”到中央倉庫。這一步等同于 svn commit,除了 Git 添加的是所有不在中央 master 分支上的提交。

管理沖突

  • 中央倉庫代碼官方項目,因此它的提交歷史應(yīng)該被視為不可更改的。如果開發(fā)者的本地提交和中央倉庫分叉了,Git 會拒絕將它們的修改推送上去,因為這會覆蓋官方提交。
  • 在開發(fā)在提交功能之前,需要 fetch 更新中央提交,在它們之上 rebase 自己的更改。
  • 如果本地修改和上游提交的沖突時,Git 會暫停 rebase 流程,給你機會手工解決這些沖突。Git 很贊的一點是,它將 git status 和 git add 命令同時用來生成提交和解決合并沖突。這使得開發(fā)能夠輕而易舉的管理他們的合并。另外,如果他們改錯了什么,Git 能讓他們輕易的退出 rebase 過程,然后重試。

例子

  • 項目管理員生成一個空的版本庫

    ssh user@host git init --bare /path/to/repo.git
    
  • 三個人 A, B, C 同時編寫同一個項目,需要先在本地創(chuàng)建一個完整的項目副本。

    git clone ssh://user@host/path/to/repo.git
    

此時,Git 自動添加了一個名為 origin 的運程連接,指向中央倉庫,以方便提交。
A 可以使用標準 Git 提交流程開發(fā)功能:編輯、緩存、提交。

git status
git add <some file>
git commit

同時,B 也在本地進行自己的開發(fā)工作。

  • A 發(fā)布了他們修改

    git push origin master
    

此時中央倉庫會將 master -> origin/master

  • B 試圖發(fā)布修改

    git push origin master
    

但是因為 A 已經(jīng)提交了功能到中央倉庫,導致 B 的本地歷史和中央倉庫分叉,Git 會拒絕本次提交。

  • B 如果想提交,必須要先 rebase 本地倉庫

可以使用 git pull 來拉取并修改,

git pull --rebase origin master
  • --rebase 命令告訴 Git,在同步中央倉庫的修改之后,將 B 的所有提交移到 master 分支的頂端。
  • 如果沒有沖突的文件,B 就可以直接進行提交了,但是如果存在沖突,可以根據(jù)提示查找沖突的文件,修改之后,可以繼續(xù) rebase 操作。

    git add <some-file>
    git rebase --continue
    

同樣的,如果此時不知道自己做了什么,可以回滾一次操作。

git rebase --abort
  • 然后再進行 push 就可以提交到中央版本庫了。

基于功能人分支的工作流

Feature 分支工作流

  • 掌握了中心化工作流的使用姿勢,在你的開發(fā)流程中添加功能分支是一個簡單的方式,來促進協(xié)作和開發(fā)者之間的交流。這種封裝使得多個開發(fā)專注自己的功能,而不會打擾主代碼庫。它還能保證 master 分支永遠不會包含損壞的代碼,給持續(xù)集成環(huán)境帶來了很大的好處。
  • 封裝功能的開發(fā)使得 pull request 的使用成為可能,用來啟動圍繞一個分支的討論。它給了其他開發(fā)者在功能并入主項目之前參與決策的機會。或者,如果你開發(fā)功能時卡在一半,可以發(fā)起一個 pull request,向同事尋求建議。重點是:pull request 使得團隊在評論其他人的工作時,變得非常簡單。

如何工作

  • Feature 分支工作流同樣使用中央倉庫,master 同樣代碼官方的項目歷史。但是與其直接提交在本地的 master 分支,開發(fā)者每次進行新的工作時創(chuàng)建一個新的分支。Feature 分支應(yīng)該包含描述性的名稱,比如 animated-menu-items(菜單項動畫)或 issue-*1061。每個分支都應(yīng)該有一個清晰、高度集中的目的。
  • Git 在技術(shù)上無法區(qū)別 master 和功能分支,所以開發(fā)者可以在 feature 分支上編輯、緩存、提交,就和中心化工作流中一樣。
  • 此外,feature 分支可以被推送到中央倉庫。這使得你和其他開發(fā)者共享這個功能,而又不改變官方代碼。既然 master 只是一個“特殊”的分支,在中央倉庫中儲存多個 feature 分支不會引出什么問題。當然,這也是備份每個開發(fā)者本地提交的好辦法。

Pull Request

  • 除了隔離功能開發(fā)之外,分支使得通過 pull request 討論修改成為可能。一旦有人完成了一個功能,他們不會立即將它并入 master。他們將 feature 分支推送到中央服務(wù)器上,發(fā)布一個 pull request,請求將他們的修改并入 master。這給了其他開發(fā)者在修改并入主代碼庫之前審查的機會。
  • 代碼審查是 pull request 的主要好處,但他們事實上被設(shè)計成為討論代碼的一般場所。你可以把 pull request 看作是專注某個分支的討論版。也就是說他們可以用于開發(fā)流程之前。比如,一個開發(fā)者在某個功能上需要幫助,他只需要發(fā)起一個 pull request。感興趣的小伙伴會自動收到通知,看到相關(guān)提交中的問題。
  • 一旦 pull request 被接受了,發(fā)布功能的行為和中心化的工作流是一樣的。首先,確定你本地的 master 和上游的 master 已經(jīng)同步。然后,將 feature 分支并入 master 已經(jīng)同步。然后可以將 feature 分支并入 master,將更新的 master 推送回中央倉庫。

Gitflow 工作流

  • GitFlow 工作流圍繞項目發(fā)布定義了一個嚴格的分支模型。有些地方比功能分支工作流更復雜,為管理大型項目提供了框架。
  • 和功能分支工作流相比,這種工作流沒有增加任何新的概念或命令。它給不同的分支指定了特定的角色,定義它們應(yīng)該如何、什么時候交流。除了功能分支之外,它還為準備發(fā)布、維護發(fā)布、記錄發(fā)布分別使用了單獨的分支。當然,還能享受到功能分支工作流帶來的所有好處:pull request、隔離實驗和更高效的協(xié)作。

如何工作

  • GitFlow 工作流仍然使用中央倉庫作為開發(fā)者溝通的中心。和其它工作流一樣,開發(fā)者在本地工作,將分支推送到中央倉庫。唯一的區(qū)別在于項目的分支結(jié)構(gòu)。

歷史分支

  • 和單獨的 master 分支不同,這種工作流使用兩個分支來記錄項目歷史。master 分支儲存官方發(fā)布歷史,develop 分支用來整合功能分支。同時,這還方便了在 master 分支上給所有提交打上版本號標簽。
  • 工作流剩下的部分圍繞這兩個分支的差別展開。

功能分支

  • 每個新功能都放置在自己的分支中,可以在備份/協(xié)作時推送到中央倉庫。但是與其合并到 master,功能分支將開發(fā)分支作為父分支。當一個功能完成時,它將被合并回 develop。功能永遠不應(yīng)該支持在 master 上交互。
  • 功能分支加上 develop 分支就是我們之前據(jù)說的功能分支工作流。

發(fā)布分支

  • 一旦 develop 分支的新功能足夠發(fā)布,你可以從 develop 分支 fork 一個發(fā)布分支。這個分支的創(chuàng)建開始了下個發(fā)布周期,只有和發(fā)布相關(guān)的任務(wù)應(yīng)該在這個分支進行,如修復 bug、生成文檔等。一旦準備好發(fā)布,發(fā)布分支將合并進 master,打上版本號的標簽。另外,它也應(yīng)該合并回 develop,后者可能在發(fā)布啟動之后有了新的進展。
  • 使用一個專門的分支來準備發(fā)布確保一個團隊完善當前的發(fā)布,其它團隊可以繼續(xù)開發(fā)下一個發(fā)布的功能。它還建立了清晰的開發(fā)階段。
  • 通常約定:
    • 從 develop 創(chuàng)建分支
    • 合并進 master 分支
    • 命名規(guī)范 release-* 或者 release/*

維護分支

  • 維護或者“緊急修復”分支用來快速給產(chǎn)品發(fā)布打上補丁。這是唯一可以從 master 上 fork 的分支。一旦修復完成了,它應(yīng)該被并入 master 和 develop 分支,master 應(yīng)該打上更新的版本號的標簽。
  • 有一個專門的 bug 修復開發(fā)線使得團隊能夠處理 issue,而不打斷其它工作流或是要等到下一個發(fā)布周期。你可以將維護分支看作在 master 分支上工作的臨時發(fā)布分支。

例子

創(chuàng)建一個開發(fā)分支

  • 為默認的 master 分支創(chuàng)建一個互補的 develop 分支。最簡單的辦法是在本地創(chuàng)建一個空的 develop 分支,將他推送到服務(wù)器上:

    git branch develop
    git push -u origin develop
    
  • 這個分支將會包含項目中所有的歷史,而 master 將包含不完全的版本。其他開發(fā)者應(yīng)該將中央倉庫克隆到本地,創(chuàng)建一個分支來追蹤 develop 分支:

    git clone http://xxx/xx/repo.git
    git checkout -b develop origin/develop
    

開始了新的功能

  • 當兩個人都需要在不同分支上開始工作,即為自己的功能創(chuàng)建單獨的分支。且他們的分支都是基于 develop 而不是 master:

    git checkout -b some-feature develop
    
  • 他們都使用“編輯、緩存、提交”的一般約定來向功能分支添加提交:

    git status
    git add <some-file>
    git commit
    

完成功能

  • 添加了一些提交后,可以使用 pull request,現(xiàn)在正是發(fā)起的好時機,請求將新功能并入 develop 分支。否則可以先并入本地的 develop 分支,推送到中央倉庫:

    git pull origin develop
    git checkout develop
    git merge some-feature
    git push
    git branch -d some-feature
    
  • 第一個命令在嘗試并入功能分支之前確保 develop 分支已經(jīng)是最新的。注意,功能絕不該直接并入 master。沖突的處理方式和中心化工作流相同。

發(fā)布新功能

  • 當另外的開發(fā)人員,仍在他自己的分支上工作時,開始準備項目的第一個官方發(fā)布。和開發(fā)功能一樣,新建一個分支來封裝發(fā)布的準備工作。這也正是發(fā)布的版本號創(chuàng)建的第一步:

    git checkout -b release-0.1 develop
    
  • 這個分支用來整理提交,充分測試,更新文檔,為即將到來的發(fā)布做各種準備。它就像是一個專門用來完善發(fā)布的功能分支。

  • 一旦發(fā)布準備穩(wěn)妥,即將其并入 master 和 develop,然后刪除發(fā)布分支。合并回 develop 很重要,因為可能已經(jīng)有關(guān)鍵的更新添加到發(fā)布分支上,而開發(fā)新功能需要用到它們。同樣的,如果團隊重視代碼審查,現(xiàn)在將是發(fā)起 pull request 的完美時機。

    git checkout master
    git merge release-0.1
    git push
    git checkout develop
    git merge release-0.1
    git push
    git branch -d release-0.1
    
  • 發(fā)布分支是功能開發(fā)(develop)分支和公開發(fā)布(master)之間的過渡階段。不論什么時候,將提交并入 msater 時,你應(yīng)該為提交打上方便引用的標簽:

    git tag -a 0.1 -m "Initial public release" master
    git push --tags
    
  • Git 提供了許多鉤子,即倉庫中特定事件發(fā)生時被執(zhí)行的腳本。當你向中央倉庫推送 master 分支或者標簽時,你可以配置一個鉤子來自動化構(gòu)建公開發(fā)布。

終端用戶發(fā)現(xiàn)一個 Bug

  • 正式發(fā)布之后,兩個開發(fā)一起為下一個發(fā)布開發(fā)功能。這時,一個終端用戶開了一個 issue 抱怨說當前發(fā)布中存在一個 Bug。為了解決這個 bug,先從 master 創(chuàng)建一個維護分支,用幾個提交修復這個 issue,然后直接合并回 master。

    git checkout -b issue*001 master
    ##Fix the bug
    git checkout master
    git merge issue-*001
    git push
    
  • 和發(fā)布分支一樣,維護分支包含了 develop 中需要的重要更新,因此需要執(zhí)行同樣的合并。接下來,可以刪除這個分支:

    git checkout develop
    git merge issue-*001
    git push
    git branch -d issue-*001
    

各分支的意義

  • feature (多個) 主要是自己玩了,差不多的時候要合并回 develop 去。不與 master 交互。
  • develop (同時間一個) 主要是和 feature 以及 release 交互
  • release (同時間一個) 總是基于 develop,最后又合并回 develop。當然對應(yīng)的 tag 要合并到 master 分支,生命周期短,僅是為了發(fā)布程序
  • hotfix (同一時間一個) 總是基于 master,并最后合并到 master 和 develop。生命同期較短,用來修復 bug 或小粒度修改發(fā)布
  • master (僅一個) 關(guān)聯(lián) tag 和發(fā)布

模型中各個模塊內(nèi)容的使用

  • 在這個模型中,master 和 develop 都具有象征意義。master 分支上的代碼總是穩(wěn)定的 (stable build),隨時可以發(fā)布出去。develop 上的代碼總是從 feature 上合并過來的,可以進行 Nightly Builds,但不直接在 develop 上進行開發(fā)。當 develop 上的 featur 足夠多以致于可以進行新版本的發(fā)布時,可以創(chuàng)建 release 分支。
  • release 分支基于 develop,進行委陰簡單的修改后就被合并到 master,并打上 tag,表示可以發(fā)布了。緊接著 release 將被合并到 develop;此時 Develop 可能往前跑了一段,出現(xiàn)合并沖突,需要手工解決沖突后再次合并,這步完成后就刪除 release 分支
  • 當從已發(fā)布版本中發(fā)現(xiàn) bug 要修復時,就應(yīng)用到 hotfix 分支了。hotfix 基于 master 分支,完成 bug 修復或者緊急修改后,要 merge 回 master,打上一個新的 tag,并 merge 回 develop,刪除 hotfix 分支。
  • 由此可見 release 和 hotfix 的生命周期都較短,而 master 和 develop 雖然總是存在,但去不常使用。

文章首發(fā)于:https://www.zucchiniy.cn

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 多種多樣的工作流使得在項目中實施Git時變得難以選擇。這份教程提供了一個出發(fā)點,調(diào)查企業(yè)團隊最常見的Git工作流。...
    JSErik閱讀 4,614評論 2 8
  • 集中式工作流 每個開發(fā)可以有屬于自己的整個工程的本地拷貝。隔離的環(huán)境讓各個開發(fā)者的工作和項目的其他部分(修改)獨立...
    yohn閱讀 541評論 0 0
  • Git 工作流的一些經(jīng)驗分享原創(chuàng) 2017-02-16 巫山老妖小巫技術(shù)博客 筆者使用git有一段時間了,踩過不...
    Karma1026閱讀 457評論 0 1
  • 一、Gitflow工作流概述 工作流(Workflow),指“業(yè)務(wù)過程的部分或整體在計算機應(yīng)用環(huán)境下的自動化”。是...
    大海螺Utopia閱讀 1,346評論 4 3
  • “姐姐,我給你帶禮物了”小寶一進門就朝正在和我說話的姐姐走過來,哈哈,原來是手工做的面食“小魚兒和小刺猬”,我:你...
    鴨蛋媽媽閱讀 187評論 0 0

友情鏈接更多精彩內(nèi)容