git 協同開發流程
-
前言
-
倉庫(Repository)
- 源倉庫
- 開發者倉庫
-
分支(Branch)
- 永久性分支
- 暫時性分支
-
工作流(workflow)
-
總結
前言
(本文假設各位已經對基本git的基本概念、操作有一定的理解,如無相關git知識,可以參考
很多專案開發都會採用git這一優秀的分散式版本管理工具進行專案版本管理,使用github開源平臺作為程式碼倉庫託管平臺。由於git的使用非常靈活,在實踐當中衍生了很多種不同的工作流程,不同的專案、不同的團隊會有不同的協作方式。
本文將介紹一種前人已經在各種大小專案中經過千錘百煉總結出來的一種比較成功的git工作流,這種工作流已經被成功用於許多團隊開發當中。掌握git,掌握這種工作流,對大家以後的學習、開發工作大有好處。
先上一張圖:
上面一張圖展示了一種使用git進行專案協同開發的模式,接下來會進行詳細介紹。
倉庫(Repository)
在專案的開始到結束,我們會有兩種倉庫。一種是源倉庫(origin)
開發者倉庫
。上圖中的每個矩形都表示一個倉庫,正中間的是我們的源倉庫,而其他圍繞著源倉庫的則是開發者倉庫。
源倉庫
在專案的開始,專案的發起者構建起一個專案的最原始的倉庫,我們把它稱為origin
,例如我們的Go2Cloud網站,origin
就是這個Devops/go2cloud了。源倉庫的有兩個作用:
- 彙總參與該專案的各個開發者的程式碼
- 存放趨於穩定和可釋出的程式碼
源倉庫(master)應該是受保護的,開發者不應該直接對其進行開發工作。只有專案管理者(通常是專案發起人)能對其進行較高許可權的操作。
開發者倉庫
上面說過,任何開發者都不會對源倉庫進行直接的操作,源倉庫建立以後,每個開發者需要做的事情就是把源倉庫的複製
fork
。
每個開發者所fork的倉庫是完全獨立的,互不干擾,甚至與源倉庫都無關。每個開發者倉庫相當於一個源倉庫實體的影像,開發者在這個影像中進行編碼,提交到自己的倉庫中,這樣就可以輕易地實現團隊成員之間的並行開發工作。而開發工作完成以後,開發者可以向源倉庫傳送pull request
,請求管理員把自己的程式碼合併到源倉庫中,這樣就實現了分散式開發工作,和最後的集中式的管理。
分支(Branch)
分支是git中非常重要的一個概念,也是git這一個工具中的大殺器,必殺技。利用git的分支,可以非常方便地進行開發和測試 .
在文章開頭的那張圖中,每一個矩形內部紛繁的枝蔓便是git的分支模型。可以看出,每個開發者的倉庫都有自己的分支路線,而這些分支路線會通過程式碼彙總對映到源倉庫中去。
我們為git定下一種分支模型,在這種模型中,分支有兩類,五種
- 永久性分支
master branch
:主分支develop branch
:開發分支
- 臨時性分支
feature branch
:功能分支release branch
:預釋出分支hotfix branch
:bug修復分支
永久性分支
永久性分支是壽命無限的分支,存在於整個專案的開始、開發、迭代、終止過程中。永久性分支只有兩個master
和develop
。
master:主分支從專案一開始便存在,它用於存放經過測試
,已經完全穩定程式碼
;在專案開發以後的任何時刻當中,master
存放的程式碼應該是可作為產品供使用者使用的程式碼。所以,應該隨時保持master
倉庫程式碼的清潔和穩定,確保入庫之前是通過完全測試和程式碼reivew的。master
分支是所有分支中最不活躍的,大概每個月或每兩個月更新一次,每一次master
更新的時候都應該用git打上tag
,說明你的產品有新版本釋出了。
develop:開發分支,一開始從master分支中分離出來,用於開發者存放基本穩定程式碼。之前說過,每個開發者的倉庫相當於源倉庫的一個映象,每個開發者自己的倉庫上也有master
和develop
。開發者把功能做好以後,是存放到自己的develop
中,當測試完以後,可以向管理者發起一個pull request
,請求把自己倉庫的develop
分支合併到源倉庫的develop
中。
所有開發者開發好的功能會在源倉庫的develop
分支中進行彙總,當develop
中的程式碼經過不斷的測試,已經逐漸趨於穩定了,接近產品目標了。這時候,我們就可以把develop
分支合併到master
分支中,釋出一個新版本。所以,一個產品不斷完善和釋出過程就正如下圖:
注意,任何人不應該向master
直接進行無意義的合併、提交操作。正常情況下,master
只應該接受develop
的合併,也就是說,master
所有程式碼更新應該源於合併develop
的程式碼。
暫時性分支
暫時性分支和永久性分支不同,暫時性分支在開發過程中是一定會被刪除的。所有暫時性分支,一般源於develop
,最終也一定會迴歸合併到develop
。
feature:功能性分支,是用於開發專案的功能的分支,是開發者主要戰鬥陣地。開發者在本地倉庫從develop
分支分出功能分支,在該分支上進行功能的開發,開發完成以後再合併到develop
分支上,這時候功能性分支已經完成任務,可以刪除。功能性分支的命名一般為feature-*
,*為需要開發的功能的名稱。
舉一個例子,假設我是一名go2cloud網站的開發者,已經把源倉庫fork了,並且clone到了本地。現在要開發 資料盤遷移
功能。我在本地倉庫中可以這樣做:
step 1: 切換到develop
分支
>>> git checkout develop
step 2: 分出一個功能性分支
>>> git checkout -b feature-datadisk_transfer
step 3: 在功能性分支上進行開發工作,多次commit,測試以後...
step 4: 把做好的功能合併到develop
中
# 回到develop分支
>>> git checkout develop
# 把做好的功能合併到develop中
>>> git merge --no-ff feature-datadisk_transfer
# 刪除功能性分支(這是臨時的分支)
>>> git branch -d feature-datadisk_transfer
# 由管理員把develop提交到自己的遠端倉庫中
>>> git push origin develop
這樣,就完成一次功能的開發和提交。
release:預釋出分支,當產品即將釋出的時候,要進行最後的調整和測試,這時候就可以分出一個預釋出分支,進行最後的bug fix。測試完全以後,釋出新版本,就可以把預釋出分支刪除。預釋出分支一般命名為release-*
。
hotfix:修復bug分支,當產品已經發布了,突然出現了重大的bug。這時候就要新建一個hotfix
分支,繼續緊急的bug修復工作,當bug修復完以後,把該分支合併到master
和develop
以後,就可以把該分支刪除。修復bug分支命名一般為hotfix-*
release
和hotfix
分支離我們還比較遙遠。。最好永遠不會遇到這種分支
工作流(Workflow)
傻瓜教程,接下來,我們就一步一步來操作上面所說的工作流程,大家感受一下:
Step 1:源倉庫的構建
這一步通常由專案發起人來操作,我們這裡把管理員設為admin,假設a已經為我們建立起了一個源倉庫Devops/go2cloud,並且已經初始化了兩個永久性分支master
和develop
,如圖:
Step 2:開發者fork源倉庫
源倉庫建立以後,每個開發就可以去複製一份源倉庫到自己的github賬號中,然後作為自己開發所用的倉庫。假設我是一個專案中的開發者,我就到Devops/go2cloud專案主頁上去fork
:
fork
完以後,我就可以在我自己的倉庫列表中看到一個和源倉庫一模一樣的複製品。這時就應該感嘆,你以後要和它相依為命了:
Step 3:把自己開發者倉庫clone到本地
這一步應該不用教,git clone
Step 4:構建功能分支進行開發
進入倉庫中,按照前面說所的構建功能分支的步驟,構建功能分支進行開發、合併,假設我現在要開發一個“討論”功能:暫時把windows_002當作我們的develop
# 切換到`develop`分支
>>> git checkout windows_002
# 分出一個功能性分支
>>> git checkout -b feature-datadisk_transfer
# 假裝READforDataTransfer.Md就是我們要開發的功能說明
>> touch READforDataTransfer.Md
# 把新增的新功能新增到本地分支
>> git add .
# 提交更改
>> git commit -m 'finish datatransfer feature'
# 回到develop分支
>>> git checkout windows_002
# 把做好的功能合併到develop中(檢查差異)
>>> git merge --no-ff feature-datadisk_transfer
# 刪除功能性分支(本地)
>>> git branch -d feature-datadisk_transfer
# 把develop提交到自己的遠端倉庫中
>>> git push origin windows_002
這時候,你上自己github的專案主頁中develop
分支中看看,已經有READforDataTransfer.Md
這個檔案了:
Step 5:向管理員提交pull request
假設我完成了“”功能(當然,你還可能對自己的develop
進行了多次合併,完成了多個功能),經過測試以後,覺得沒問題,就可以請求管理員把自己倉庫的develop分支合併到源倉庫的develop分支中,這就是傳說中的pull request
。
Step 6: 管理員測試、合併
接下來就是管理員的操作了,作為管理員的PingHackers登陸github,便看到了我對源倉庫發起的pull request
。
這時候Admin需要做的事情就是:
-
對我的程式碼進行review。github提供非常強大的程式碼review功能:
-
在他的本地測試新建一個測試分支,測試我的程式碼:
# 進入他本地的develop分支
>> git checkout windows_002
# 從develop分支中分出一個叫livoras-develop的測試分支測試我的程式碼
>> git checkout -b livoras-develop
# 把我的程式碼pull到測試分支中,進行測試
>> git pull https://github.com/livoras/git-demo.git develop
- 判斷是否同意合併到源倉庫的develop中,如果經過測試沒問題,可以把我的程式碼合併到源倉庫的
develop
中:
>> git checkout develop
>> git merge --no-ff livoras-develop
>> git push origin develop
注意,admin一直在操作的倉庫是源倉庫。所以我們經過上面一系列操作以後, master 分支中會看到 READforDataTransfer.Md
檔案
總結
git這一個工具博大精深,使用如此噁心而又如此靈活和優雅的工具;希望能幫助您處理各種專案團隊協同工作的問題,成為一個高效的開發者、優秀的專案的管理者。送一張神圖,好好領悟:
author: failymao