Git workflow 詳談

zphuang 8年前發布 | 31K 次閱讀 Git 工作流 版本控制系統

作為一名工程師, Git 在日常開發中是不可或缺的工具。

這里詳細介紹幾種比較常用的基于 Git 的工作流模型, 以便于團隊協作的規范化和效率提升。

中心化工作流

使用過SVN的應該都知道, SVN使用的是集中式管理流程, 如果你剛從SVN 切換到 Git , 你可以嘗試使用中心化工作流的方式。這樣,你幾乎不需要變更之前的工作方式, 就可以完成平滑的過渡了。 而且在使用過程中還可以看到 Git 優于 SVN 的地方:

第一,每個成員都可以在本地擁有一份完整的項目代碼倉庫,而不只是一個工作區的副本,任何人都可以在本地執行 add 和 commit ,而不需要考慮遠端倉庫是否有變更,直到需要的時候再去提交即可。

第二,Git 的工作區、暫存區、引用更新等設計,可以給開發者更多自由來切換當前工作,且不會造成代碼丟失。

工作細節

中心化工作流的方式是:在遠端(遠端可以是服務器端,也可以是本地的任意目錄)新建一個倉庫,默認是 master 分支,作為唯一的中心倉庫。 所有人都 clone 這個倉庫作為本地倉庫,并在本地倉庫進行開發。本地的提交是和遠端倉庫無關的,等需要的時候再 push 進主倉庫的 master 分支即可。

在這種方式下, 遠端是唯一確定的中心倉庫, 所有人都要以這個倉庫為準。 所以,在提交之前要先 fetch 最新提交,在這些提交之上作出自己的更改(一般我們使用 rebase 來完成)。

如果本地的修改和遠端倉庫中的變更發生了沖突,那么 Git 會暫停 rebase ,并讓你來解決這些沖突。我們可以很簡單的使用 git status 和 git add 等命令完成沖突的合并。 另外, 如果我們解決不了沖突, 我們也可以使用 git rebase --abort 很容易的退出 rebase 的過程。

這樣每天的工作方式就變成了,從中心倉庫拉取最新代碼, 然后開始一天的工作, 開發完成后,拉取中心倉庫的更新, 合并代碼后, 再提交至中心倉庫, 結束一天的工作。 這樣的好處就是不需要變更原先(使用SVN)的工作方式。當然弊端也很明顯,你并不知道中心倉庫的代碼是否是穩定的,或者說并不能確定當你的代碼和中心倉庫代碼合并后,是否是穩定的,帶來的問題就是開發進度和回滾不那么方便控制。

示例

我們有兩位程序員, A 和 B, 兩人同時在對一個項目做開發, 并且使用 Git 的中心化工作流方式。

1.創建遠端中心倉庫

這里我們有兩種方式:

  • 借助于已經搭建好的平臺 GitHub/GitLab 之類的,點擊 create repo 即可。

  • 在遠端(這里只是為了區別本地倉庫,事實上,使用任何一個其他人可以連通的機器都可以,包括自己本地其他目錄) 創建一個 裸倉庫 ,創建裸倉庫和我們平時創建本地倉庫的區別,可以參考我另一篇文章Git 本地倉庫和裸倉庫 。

這里以第二種方式為例:

# --bare 參數必須有
git init --bare /the/repo/path.git

2.所有人都 clone 中心倉庫到本地作為本地倉庫

git clone /the/repo/path.git

注意倉庫地址必須是正確的, 且有權限訪問才能 clone 成功。

3.程序員 A 在他的本地倉庫進行功能開發并進行發布

一般情況下,我們通過 git status 看看當前狀態,并通過 git add 和 git commit 等命令完成本地倉庫的提交。 當然這個提交影響的也只是本地倉庫而已,并沒有對中心倉庫產生任何影響,所以我們既不需要關心別人有什么提交,也不用擔心我們當前的提交是否對別人造成了影響。當 A 認為自己所開發的功能已經完成, 那他將執行 git push origin master 這樣的操作,將自己本地倉庫所有不存在于中心倉庫的提交都 push 到遠端的中心倉庫上。

4.程序員 B 在他本地倉庫進行功能開發

B 在 clone 中心倉庫后所做的操作和 A 一樣,在本地倉庫進行項目開發,并在本地倉庫進行提交,他不需要知道中心倉庫發生了什么樣的變化。

5.程序員 B 將自己開發的功能并進行發布

B 在確認自己開發的功能已經完成后,想要將自己的代碼通過 git push origin master 這樣的操作發布至中心倉庫,但是卻被中心倉庫提示他的修改已經和中心倉庫有了分叉, 需要他先執行 git pull 之類的操作, 將中心倉庫上 A 的提交與 B 本地的提交進行合并才允許他并入中心倉庫。所以,他執行了 git pull --rebase origin master 來將中心倉庫的修改并入他的本地倉庫。使用 --rebase 參數的意義在于 fetch 執行完成后,將把 B 的所有提交移至 master 頂端。

當然這里不使用 --rebase 參數也會成功,只不過是會生成一個合并提交,有些情況下使用 --ff 參數也可以避免產生合并提交。在這里使用 --rebase 只是一個建議操作。

如果 A 和 B 修改的文件沒有關聯,一般情況下會直接完成合并,如果發生沖突,Git 將會暫停 rebase 的過程,并列出當前沖突的文件,你可以簡單的使用 git status 和 git add 等命令進行合并,合并后使用 git rebase --continue 繼續 rebase 的過程。或者使用 git rebase --abort 退出 rebase 過程。

在 B 合并完成后,可以執行 git push origin master 將自己開發的功能發布至中心倉庫。

至此,基礎的中心化工作流方式就介紹完了,但是這里也很容易看出來其中的問題,除了前面說到過的以外,還有就是效率低下,如果很多人都在持續進行提交,那很影響新功能的提交(多人持續性進行提交)。 一個比較容易提升效率的方式就是切換到 特性分支工作流 的方式。

特性分支工作流

基于特性的分支工作流,可以為每個特性做隔離,避免對中心倉庫主干代碼造成影響。

工作細節

顧名思義, 就是根據每個特性都會開一個新的分支,每個分支都應該包含著描述性的名稱,無論是一個人開發,還是多人協同,該特性的全部開發工作都在這個分支上進行。待該特性開發完成后, 并入主分支,然后刪除分支,代碼上線。

這種情況下, 最大的優勢在于, 所有的特性開發都可以并行處理。 不必要像中心化工作流方式, 每個人的變動都可能引起其他的人的代碼合并, 并且所有功能都雜糅在一起, 從測試和回滾都會變得很繁瑣。 另外的一個好處就是特性分支可以推送到中心倉庫,這樣也便于單獨測試。

這里需要注意的是,特性分支往主分支合并的時機,應該是該特性開發完成,并測試通過,避免對主干代碼造成污染。

在進行分支隔離后,我們發現,我們當前只處理了開發模式,但并沒有涵蓋一個很完備的產品生命周期, 開發、發布、維護等過程,所以,我們有了 Gitflow 工作流。

Gitflow 工作流

基于Gitflow 的工作流方式, 這種工作流方式, 主要是管理著新功能開發,發布及維護等模式,根據不同類型的工作對分支進行定義, 分為 特性分支修復分支release 分支開發分支主分支

主分支:中心倉庫建立后的默認 master 分支(當然使用其他分支也可以,但要保證該分支是受保護的)。主分支隨時保持代碼是穩定的,并且有明確的版本標簽,后續代碼回滾等操作都將從主分支進行。

開發分支:中心倉庫建立后,從 master 分支切出來,此時與 master 分支保持一致。后續演進中,開發分支隨時保持代碼最新,但卻不一定是線上實際運行的代碼。

git checkout -b develop

特性分支:應該從開發分支切出,開發完成后, 再合并進入開發分支, 如果達到了發布標準, 則從開發分支切出 release 分支, 切出來的這個分支,只做該版本內的代碼修復, 不再加入新功能, 這時此分支處于鎖定的狀態。

修復分支, 用于對線上主分支代碼的及時修復, 待修復完成后, 合并進入主分支, 再并入開發分支。 修復分支只能從主分支切出。

發版分支, 一般命名為 release-xxx 這個分支只能從開發分支切出, 最后并入主分支,打上版本號的標簽,它也應該并入開發分支,如果中間有其他修復的話。

fork 工作流

fork 分支流和上面介紹的所有工作流都不太一樣。它的上游有一個唯一倉庫, 所有人都是 fork 這個倉庫, 在自己的遠端和自己的本地各維護一個倉庫,待開發完成后推入自己的遠端倉庫,并結合 GitHub/GitLab等提交 Pull Request,進入了 review 階段,待通過后,將會被合并入上游唯一的倉庫。這種方式比較適合 GitHub 中的大型開源項目, 對于小團隊的內部項目, 這種方式可能未必合適。

而且 fork 工作流, 會占用更多的資源(畢竟每個人都維護一份遠端倉庫)。 而且每個人都看不到其他人的動態,只有當提交 Pull Request 的時候, 才知道每個人發生了什么。

總結

我個人比較推薦的是 Gitflow 的開發工作流, 這種方式下,一切都是可控的, 每個分支都有各自獨立的功能,目的性很明確, 同時,在做代碼回滾之類的操作也是可以直接剔除。 另外, 在這種工作流方式下, 團隊中的每個人都能很輕易的知道其他人在做什么, 做出了什么樣的改變, 對于團隊協作, 或許更加合適。

當然所有的工作流并不一定能完全套用, 可以吸取一些規范, 合并入自己的日常工作, 將代碼倉庫的合作流程標準化和規范化, 這也是一切自動化的基礎。

 

 

來自:https://segmentfault.com/a/1190000007692929

 

 本文由用戶 zphuang 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!