Gitlab 和項(xiàng)目管理
產(chǎn)品部
產(chǎn)品經(jīng)理,產(chǎn)品專員
平面設(shè)計(jì),UI/UE
開發(fā)部
軟件項(xiàng)目經(jīng)理
開發(fā)組長(根據(jù)項(xiàng)目并行開發(fā)的產(chǎn)品線而定)
高級(jí)程序員,中級(jí)程序員,初級(jí)程序員
測(cè)試部
軟件測(cè)試經(jīng)理
測(cè)試組長(根據(jù)并行測(cè)試的項(xiàng)目數(shù)量而定)
高級(jí)測(cè)試工程師(自動(dòng)化測(cè)試),中級(jí)測(cè)試工程師(功能測(cè)試),初級(jí)測(cè)試工程師(功能測(cè)試)
運(yùn)維部
運(yùn)維經(jīng)理
運(yùn)維組長(根據(jù)服務(wù)器數(shù)量而定)
高級(jí)運(yùn)維工程師(運(yùn)維工具研發(fā)),中級(jí)運(yùn)維工程師(8小時(shí),處理日常運(yùn)維),初級(jí)運(yùn)維工程師(7*24小計(jì)監(jiān)控)
開發(fā)、測(cè)試和運(yùn)維三個(gè)部門的關(guān)系
開發(fā),測(cè)試,運(yùn)維不是三個(gè)獨(dú)立部門,他們相互緊密聯(lián)系,但又相互制約
開發(fā)只負(fù)責(zé)寫程序,將運(yùn)行無誤的程序提交至版本庫中
開發(fā)不能私自將程序交給運(yùn)維部署,也不能將編譯好的程序給測(cè)試人員
測(cè)試部只能從版本庫提取代碼,然后編譯,打包,運(yùn)行,測(cè)試
不允許測(cè)試部將代碼交給運(yùn)維部部署
避免代碼沒有經(jīng)過版本庫流入生產(chǎn)環(huán)境,造成線下與線上代碼不一致
運(yùn)維部負(fù)責(zé)部署應(yīng)用程序,配置管理,只接受測(cè)試部確認(rèn)無誤的版本,部署代碼只能從版本庫中獲取
權(quán)限角色
文檔角色:產(chǎn)品,設(shè)計(jì)
報(bào)告角色:測(cè)試
開發(fā)角色:開發(fā)
運(yùn)維角色:運(yùn)維
項(xiàng)目計(jì)劃
我常常把項(xiàng)目開發(fā)計(jì)劃比做列車時(shí)刻表,每一個(gè)站對(duì)應(yīng)一個(gè)項(xiàng)目節(jié)點(diǎn)即里程碑。
列車時(shí)刻表的概念來自早年我參與的一個(gè)英國項(xiàng)目,我們使用?TRAC?管理項(xiàng)目,這是一個(gè)古老的項(xiàng)目管理軟件,他是很多現(xiàn)代項(xiàng)目管理軟件的雛形,很多思想沿用至今,甚至無法超越它,由于他是 Python 開發(fā),框架古老,后期無人維護(hù)更新跟不上時(shí)代節(jié)奏。另一個(gè)項(xiàng)目模仿它90%的功能叫 Redmine,Redmine 紅極一時(shí),但是仍然沒有統(tǒng)一江湖。直到 Github/Gitlab 出現(xiàn),一站式解決了軟件項(xiàng)目管理中遇到的各種剛需問題,TRAC,Redmine,Confluence,Bugzilla,Jira, Mantis, BugFree, BugZero…… 慢慢淡出人們視野。
在 TRAC 中,任務(wù)叫做 Ticker 翻譯成中文就是“票”,項(xiàng)目是沿著 Roadmap 走,走過的路叫時(shí)間線 Timeline, 里程碑又形象的比做站點(diǎn),每個(gè) Milestone 里面是一組 Ticker。每次升級(jí)就如同買票上車,火車不等人,同理項(xiàng)目也按照自己的 Roadmap 運(yùn)行,錯(cuò)過只能等下一班。
項(xiàng)目經(jīng)理會(huì)在即時(shí)通信軟件中,通知發(fā)車時(shí)間,需要升級(jí)同事就會(huì)將自己上手的Ticker代碼合并主干,然后等待發(fā)車。
[ Roadmap ]
---------------.
----\ \
Timeline -----o-----o-----o-----o-----o-----o----->
----------/ /
---------------------
火車偶爾也會(huì)出現(xiàn)晚點(diǎn),取消班次,臨時(shí)停車或不停靠直接開往下一站的情況。項(xiàng)目也是如此:
晚點(diǎn)就是項(xiàng)目延期,取表班次就是停止本次里程碑的上線計(jì)劃,臨時(shí)停靠即熱修復(fù)和緊急上線,不停靠就是跳過本次里程碑,下一個(gè)里程碑一次性解決。
我們常常會(huì)在即時(shí)通信軟件中發(fā)布發(fā)車時(shí)間和詢問發(fā)車時(shí)間。
項(xiàng)目計(jì)劃應(yīng)該是像列車時(shí)刻表一樣,一旦你定好,就不能隨意修改,必須按照設(shè)定的里程碑有條不紊的推進(jìn)。
我們發(fā)現(xiàn)很多國內(nèi)項(xiàng)目是被任務(wù)牽著做,即沒有項(xiàng)目路線圖,走到那里算那里,覺得差不多了就上線,相當(dāng)隨意。一旦出現(xiàn)交叉,沖突,就會(huì)手忙腳亂,回撤更是家常便飯。
工作流
項(xiàng)目管理需要設(shè)計(jì)工作流
你會(huì)發(fā)現(xiàn) Gitlab 并沒有提供工作流的功能?為什么?你是否想過?不僅Gitlab 沒有 ,微軟的 Microsoft Project 也沒有,為什么 Microsoft Office 不提供這種功能?
談?wù)勎业囊欢温殬I(yè)生涯,大約在2000年我來到深圳,第一份工就是OA(辦公自動(dòng)化)系統(tǒng)開發(fā),當(dāng)時(shí)有很多公司開發(fā)類似產(chǎn)品,也包括金山軟件,用友等等。20年過去了,OA沒有一個(gè)標(biāo)準(zhǔn),也沒有一個(gè)成功的產(chǎn)品,OA似乎成為企業(yè)數(shù)字化轉(zhuǎn)型不上的工具之一,上了之后又發(fā)現(xiàn)這東西根本沒法使用。
OA 沒有成為主流的原因,死結(jié)就是工作流,每個(gè)公司都有自己的流程,無法統(tǒng)一標(biāo)準(zhǔn),即使是管理學(xué)誕生的西方國家,也沒有統(tǒng)一的流程,流程是隨著市場(chǎng)和環(huán)境不斷變化的,沒有任何流程能始終延續(xù)。經(jīng)歷了德魯克時(shí)代的企業(yè)到目前為止保留下來的流程也只有部分行政審批流程。
這就是微軟不碰這塊,IBM也做,Oracle 也不做的原因。雖然技術(shù)上已經(jīng)又成熟的工作流引擎,圖形化配置,使用過的人都表示巨難用,對(duì)于非技術(shù)的行政人員幾乎都放棄了。
但凡設(shè)計(jì)流程,設(shè)計(jì)者都會(huì)表現(xiàn)自己,最終設(shè)計(jì)的出的流程無比復(fù)雜,看似流程堪稱完美,執(zhí)行起來不是內(nèi)耗就是受阻。幾乎都是做加法思維,能做減法思維的人少之又少。
工作流設(shè)計(jì)原則
遵循減法原則而不是加法原則,參與人越少越好,節(jié)點(diǎn)越少越好。
盡量線性,從一端流向另一段,中間盡量不出現(xiàn)分叉。
盡可能不出現(xiàn)邏輯判斷分叉,例如 A審批決定下一步是流向B還是C
避免循環(huán),依賴關(guān)系避免循環(huán),即流程后退。
目的是讓工作流可操作,易操作,能冗余。
下面這個(gè)流程有問題嗎?
開發(fā)人員提測(cè) -> 開發(fā)組長審批 -> 技術(shù)部門審批 -> 測(cè)試部門審批 -> 測(cè)試組長審批 -> 分配測(cè)試人員
稍具規(guī)模的企業(yè)不都是這樣做的嗎?
開發(fā)人員提測(cè) | 分配測(cè)試人員
--------------------------------------------------
開發(fā)組長審批 | 測(cè)試組長審批
--------------------------------------------------
技術(shù)部門審批 | 測(cè)試部門審批
矩陣轉(zhuǎn)換一下,看的更清晰,工作流從一段流向另一段,經(jīng)歷兩個(gè)部門,六個(gè)節(jié)點(diǎn)。理論上審批超過三層就要控制,超過三層就會(huì)影響進(jìn)度。為什么會(huì)出現(xiàn)這種情況?
我做過分析,國內(nèi)的管理層大可分為兩類,一類是著重考察項(xiàng)目過程本身,一類是主要考察項(xiàng)目的參與者和結(jié)果,前者著重于時(shí)間管理,后者傾向于績效考核。?[1]
第一類管理者,很清楚項(xiàng)目的 Roadmap,所以根本無需做,技術(shù)部門審批到測(cè)試部門審批這個(gè)審批過程,這些工作都是在 Roadmap 會(huì)議定定好的,按時(shí)發(fā)車即可。
第二類管理者,通常是學(xué)管理出身,運(yùn)用管理學(xué)工具管理項(xiàng)目,他無法參與項(xiàng)目過程,只能關(guān)注時(shí)間點(diǎn)和進(jìn)度,不斷催促,他需要知道現(xiàn)在做什么?什么時(shí)候做完?所以需要事事審批。
議題
Issues 議題
Milestones 里程碑
敏捷開發(fā)中可以每周一個(gè)里程碑,或者每個(gè)月一個(gè)里程碑。
修正路線圖(Roadmap)
每間隔一端時(shí)間需要調(diào)整一次 Roadmap 的設(shè)置,因?yàn)橛行╉?xiàng)目會(huì)延期,有些會(huì)提前完成,還有需求變更等因素都會(huì)影響 Roadmap。
工作報(bào)告
由于項(xiàng)目是由上至下層層分解下去的,制定了嚴(yán)格的Roadmap,每個(gè)參與者知道自己該做什么,如何做,什么時(shí)間完成,也就無需再向上匯報(bào)工作。
團(tuán)隊(duì)所要做的就是按照 Roadmap 的時(shí)間和節(jié)點(diǎn)走即可。
5W2H 任務(wù)分配法則
一旦時(shí)間點(diǎn)確定,接下來就是分配任務(wù)倒指定開發(fā)人,任務(wù)的分配十分講究,分配任務(wù)要精確描述,不能使用模糊語言,那樣會(huì)造成誤解。我的分配原則是5W2H方法:
- What:做什么事?
- Why:為什么做這件事?有什么意義?目的是什么?有必要嗎?
- When:什么時(shí)候做,完成的時(shí)間是否適當(dāng)?
- Where:在什么地方做,在什么范圍內(nèi)完成?
- Who:由誰負(fù)責(zé)做?由誰負(fù)責(zé)執(zhí)行?誰更合適?熟練程度低的人能做嗎?
- How:怎樣做
-?How?much:?成本?(不是所有崗位都會(huì)涉及成本)
任務(wù)/議題
議題
運(yùn)維任務(wù)
舉例,運(yùn)維任務(wù)
- What:為api服務(wù)器做負(fù)載均衡,多增加一個(gè)節(jié)點(diǎn),負(fù)載均衡算法采用最小連接數(shù)。
- Why:目前api服務(wù)器只有一臺(tái),如果出現(xiàn)故障將影響到所有業(yè)務(wù)運(yùn)行,顧該服務(wù)器存在單點(diǎn)故障,需要增加節(jié)點(diǎn)。
- When:本周內(nèi)完成,周末上線。(此處可以寫日期)
- Where:在A機(jī)柜,低2機(jī)位處,連接倒交換機(jī)第三個(gè)端口。
- Who:XXX負(fù)責(zé)網(wǎng)絡(luò)配置,XXX負(fù)責(zé)上架,XXX 負(fù)責(zé)驗(yàn)收測(cè)試
- How:增加/etc/hosts設(shè)置如下
??-?api.example.com???127.0.0.1
??-?api1.example.com??192.168.2.5
??-?api2.example.com??192.168.2.6?
開發(fā)任務(wù)
舉例,開發(fā)任務(wù)
- What:增加圖片驗(yàn)證碼。
- Why:目前用戶注冊(cè)登陸以及發(fā)帖無驗(yàn)證嗎,某些用戶通過機(jī)器人軟件批量開戶/發(fā)廣告帖,給管理帶來很大困擾。
- When:2014-06-15 開始開發(fā),2014-06-20 12:00?上線。
- Where:用戶注冊(cè),登陸與發(fā)帖處增加該功能,。
- Who:張三負(fù)責(zé)驗(yàn)證碼生成類的開發(fā),李四負(fù)責(zé)用戶注冊(cè),登陸UI修改,王五負(fù)責(zé)發(fā)帖UI的修改。
- How:具體怎么操作的細(xì)節(jié),此處省略200字...
測(cè)試任務(wù)
舉例,測(cè)試任務(wù)
- What:測(cè)出XXX軟件并發(fā)性能。
- Why:目前XXX軟件在線任務(wù)達(dá)到200后,用戶反映速度慢,經(jīng)常掉線。
- When:故障時(shí)間點(diǎn)10:00AM,需要周二完成測(cè)試,周五完成優(yōu)化,月底上線。(此處可以寫日期)
- Where:在AAA分支檢出代碼,編譯后部署到BBB環(huán)境。
- Who:XXX負(fù)責(zé)網(wǎng)絡(luò)配置,XXX負(fù)責(zé)軟件部署,XXX 負(fù)責(zé)測(cè)試
- How:具體怎么操作的細(xì)節(jié),此處省略200字...
運(yùn)營任務(wù)
舉例,促銷任務(wù)
- What:XXX產(chǎn)品促銷。
- Why:目前XXX產(chǎn)品在 XXX 市場(chǎng)占有率 XXX 用戶反映 XXX。
- When:促銷起始時(shí)間 XXX 結(jié)束時(shí)間 XXX
- Where:AAA 細(xì)分市場(chǎng),BBB區(qū)域。
- Who:XXX負(fù)責(zé) XX,XXX負(fù)責(zé) XX,XXX 負(fù)責(zé) XX
- How:具體怎么操作的細(xì)節(jié),此處省略200字...
-?How?much:?成本XXX
并行開發(fā)
![]() |
多個(gè)功能并行開發(fā)最常遇到的問題就是沖突,例如A,B,C三個(gè)功能同時(shí)開發(fā),共用一個(gè)分支(development)A開發(fā)完成,B功能開發(fā)1/3,C功能有BUG,此時(shí)升級(jí)A功能,B跟C也會(huì)被升級(jí)上去。
實(shí)現(xiàn)并行開發(fā),需要滿足兩個(gè)條件。一是合理的任務(wù)分解,二是配套的環(huán)境,三是分支的應(yīng)用。
任務(wù)分解
任務(wù)分解要盡可能解耦,出現(xiàn)交叉合并為一個(gè)任務(wù)。一個(gè)任務(wù)對(duì)應(yīng)一個(gè)功能,功能與功能之間依賴關(guān)系必須理清,避免出現(xiàn)交叉依賴和循環(huán)依賴。
A -> B -> C
\-> D -> E
\--> F
配套環(huán)境
配套環(huán)境是指開發(fā)和測(cè)試環(huán)境,參考生產(chǎn)環(huán)境,以最小化實(shí)例,最小化節(jié)點(diǎn),滿足運(yùn)行項(xiàng)目的環(huán)境,盡量減少環(huán)境差異,包括硬盤配置差異,網(wǎng)絡(luò)差異,資源配置差異,以及應(yīng)用軟件安裝配置等等差異。
準(zhǔn)備配套環(huán)境
開發(fā)環(huán)境(development),也叫集成開發(fā)環(huán)境,為開發(fā)團(tuán)隊(duì)提供共享資源,因?yàn)槊總€(gè)程序員在自己的電腦上運(yùn)行一整套的分布式系統(tǒng)不太現(xiàn)實(shí),所以需要將公共部分抽離出來,集中提供服務(wù),例如數(shù)據(jù)庫,緩存,搜索引擎,配置中心,注冊(cè)中心等等。
測(cè)試環(huán)境(testing),由于開發(fā)環(huán)境需要頻繁合并新功能,部署,重啟都會(huì)影響正常的測(cè)試,例如測(cè)試一般,開發(fā)環(huán)境上加入了新功能,此時(shí)會(huì)影響測(cè)試。所以我們需要一臺(tái)獨(dú)立,穩(wěn)定的測(cè)試環(huán)境,這個(gè)環(huán)境由測(cè)試人員自己控制,什么時(shí)候部署,測(cè)試自己說了算。
用戶交付測(cè)試環(huán)境(staging)Stage/UAT 環(huán)境,Beta/Preview 演示環(huán)境,定期同步生產(chǎn)環(huán)境數(shù)據(jù)庫。
功能測(cè)試環(huán)境(feature/hotfix) 新功能,BUG修復(fù)等等。
上面三個(gè)環(huán)境,至少一臺(tái)獨(dú)立服務(wù)器,功能測(cè)試環(huán)境(feature/hotfix) 需要若干臺(tái)服務(wù)器。功能測(cè)試環(huán)境的服務(wù)器是共享的,即誰提測(cè)誰用,用過之后釋放出來。
每個(gè)環(huán)境都有一整套,配套的服務(wù),例如數(shù)據(jù)庫,緩存,搜索引擎,消息隊(duì)列等等……
代碼分支
時(shí)間線分支
開發(fā)分支 Development 面向開發(fā)人員
測(cè)試分支 Testing 面向測(cè)試人員
交付驗(yàn)收分支 Staging 交付驗(yàn)收分支,俗稱 UAT 面向測(cè)試和客戶
生產(chǎn)分支 Production,面向用戶
在小公司中通常會(huì)省去 UAT 這個(gè)環(huán)節(jié),從 Testing直接上生產(chǎn)環(huán)境
分支權(quán)限
分支保護(hù)的目的,防止被誤刪除,禁止向該分支提交代碼,代碼只能通過合并方式進(jìn)入該分支。
分支的權(quán)限管理:
master: 保護(hù),不能修改代碼,只能合并,只有管理員有權(quán)限push
staging:保護(hù),不能修改代碼,只能合并,只有管理員有權(quán)限push
testing:保護(hù),不能修改代碼,測(cè)試人員可以合并 merge
development:保護(hù),開發(fā)人員可以修改代碼,合并,push
tag 標(biāo)簽:保護(hù),對(duì)應(yīng) Release 本版
功能分支
功能分支(Feature),任務(wù)分解之后,每個(gè)功能對(duì)應(yīng)一個(gè)分支,功能分支的代碼來自 development 分支,我們會(huì)有很多功能分支,開發(fā)任務(wù)在功能分支上完成開發(fā),開發(fā)完成后將任務(wù)標(biāo)記為“測(cè)試”,測(cè)試部會(huì)安排測(cè)試環(huán)境,部署該分支上的代碼,測(cè)試結(jié)果分為BUG和Pending(測(cè)試通過,掛起,等待發(fā)車)。
買票上車:在功能分支上,我們有很多開發(fā)完成功能,他們處于掛起狀態(tài),然后根據(jù)升級(jí)計(jì)劃,有序的合并到開發(fā)分支,再到測(cè)試分支,最后升級(jí)到生產(chǎn)環(huán)境。
Feature 分支操作步驟:
創(chuàng)建 Issue 議題
從 Development 創(chuàng)建 Feature 分支
獲取 Feature 分支代碼
修改代碼,提交代碼,測(cè)試代碼
合并 Feature 分支到 Development 分支
關(guān)閉 Issue 議題
合并流程
代碼合并流程
Development -> testing -> staging -> master(production)
合并分支
從 development 像 testing 分支合并
git checkout developmentgit pullgit checkout testinggit pullgit merge --no-ff "development"git push
testing 分支向 master 分支合并
獲取 testing 合并請(qǐng)求的分支
git fetch origingit checkout -b "testing" "origin/testing"
如果此前已經(jīng)執(zhí)行過,使用下面命令切換分支即可,切換后 pull 代碼,看看有什么新提交
git checkout "testing"git pull
切換到 master 分支
git fetch origingit checkout "master"git branch --show-currentgit merge --no-ff "testing"
將合并結(jié)果推送到遠(yuǎn)程
git push origin "master" 除了單個(gè)文件
從 development 到 testing
git checkout developmentgit pullcheckout testinggit checkout development public/doc/UserGuide.pdfgit statusgit commit -a -m '手工合并'git push
從 testing 到 staging
git checkout staginggit pullgit checkout testing public/doc/UserGuide.pdfgit commit -a -m '手工合并'git push
從 stage 到 master
git checkout mastergit pullgit checkout staging public/doc/UserGuide.pdfgit commit -a -m '手工合并'git push
合并分支解決沖突
案例,例如我們從 testing 分支向 master 分支合并代碼出現(xiàn)沖突,該如何解決呢?
首先,兩個(gè)分支拉取最新代碼
neo-Pro-Neo ~/workspace/api.netkiller.cn % git checkout testingneo-Pro-Neo ~/workspace/api.netkiller.cn % git pullneo-Pro-Neo ~/workspace/api.netkiller.cn % git checkout masterneo-Pro-Neo ~/workspace/api.netkiller.cn % git pull
然后合并分支,從 testing 分支向 master 合并
neo@MacBook-Pro-Neo ~/workspace/api.netkiller.cn % git merge --no-ff testing自動(dòng)合并 neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.java沖突(內(nèi)容):合并沖突于 neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.java
自動(dòng)合并失敗,修正沖突然后提交修正的結(jié)果。
出現(xiàn)沖突,編輯沖突文件
vim neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.java
保存后重看狀態(tài)
neo@MacBook-Pro-Neo ~/workspace/api.netkiller.cn % git status位于分支 master您的分支與上游分支 'origin/master' 一致。您有尚未合并的路徑。(解決沖突并運(yùn)行 "git commit")(使用 "git merge --abort" 終止合并)要提交的變更:修改:neo-admin/src/main/resources/application-prod.yml修改:neo-admin/src/main/resources/application-test.yml修改:neo-common/src/main/java/com/neo/common/enums/IncarAttachTypeEnum.java修改:neo-incar/src/main/java/com/neo/incar/service/impl/IncarAttachServiceImpl.java未合并的路徑:(使用 "git add <文件>..." 標(biāo)記解決方案)雙方修改:neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.java
將合并的文件添加到 git
neo-Pro-Neo ~/workspace/api.netkiller.cn % git add neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.javaneo-Pro-Neo ~/workspace/api.netkiller.cn % git status位于分支 master您的分支與上游分支 'origin/master' 一致。所有沖突已解決但您仍處于合并中。(使用 "git commit" 結(jié)束合并)要提交的變更:修改:neo-admin/src/main/resources/application-prod.yml修改:neo-admin/src/main/resources/application-test.yml修改:neo-common/src/main/java/com/neo/common/enums/IncarAttachTypeEnum.java修改:neo-incar/src/main/java/com/neo/incar/service/impl/IncarAttachServiceImpl.java修改:neo-incar/src/main/java/com/neo/incar/utils/PaperlessConfig.java
提交代碼
neo@MacBook-Pro-Neo ~/workspace/api.netkiller.cn % git commit -a -m '手工合并分支 testing -> master'[master 3652bf8e] 手工合并分支 testing -> master
推送代碼
neo@MacBook-Pro-Neo ~/workspace/api.netkiller.cn % git push枚舉對(duì)象中: 1, 完成.對(duì)象計(jì)數(shù)中: 100% (1/1), 完成.寫入對(duì)象中: 100% (1/1), 240 字節(jié) | 240.00 KiB/s, 完成.總共 1(差異 0),復(fù)用 0(差異 0),包復(fù)用 0remote:remote: To create a merge request for master, visit:remote: http://192.168.30.5/netkiller.cn/api.netkiller.cn/-/merge_requests/new?merge_request%5Bsource_branch%5D=masterremote:To http://192.168.30.5/netkiller.cn/api.netkiller.cn.gitfcaefaf4..3652bf8e master -> master
Hotfix / BUG 分支
Hotfix / BUG 分支與功能分支類似,都是用于存放 BUG,BUG分支會(huì)對(duì)應(yīng)缺陷管理系統(tǒng)中的BUG ID,做到缺陷與代碼可溯源。
hotfix 分支的使用場(chǎng)景,生產(chǎn)環(huán)境發(fā)現(xiàn) bug 需要臨時(shí)修復(fù),testing 上面有正在進(jìn)行的項(xiàng)目,不能從 testing -> master 合并,這時(shí)可以從 master -> hotfix 創(chuàng)建分支,修復(fù)和測(cè)試完成后合并到 master 分支,部署 production 環(huán)境。最后再將 hotfix 合并到 development 分支
對(duì)于中小公司,團(tuán)隊(duì)人數(shù)少的情況,可以不用建立 BUG 分支,可以在功能分支上完成修復(fù),再合并到 development 分支。
前滾和后滾
突發(fā)情況,臨時(shí)決定撤掉某些功能,這是會(huì)用到前滾和后滾操作
后滾操作
后滾操作舉例
Timeline ----- [ 往期里程碑 ] -----> [ 本次升級(jí)里程碑 ] -----> [ 未來升級(jí)里程碑 ]|Vo----------o-----o----------o---------o-----o------------->^ ^ ^ ^ ^ ^A功能 B功能 C功能 D功能 E功能 N功能
在本次升級(jí)的里程碑中,有五個(gè)功能搭便車,這個(gè)五個(gè)功能是按照順序合并進(jìn)來的,每次合并都可以找到對(duì)應(yīng)的版本ID。
我們模擬一個(gè)場(chǎng)景,這五個(gè)功能是市場(chǎng)部的五個(gè)活動(dòng),現(xiàn)在由于各種原因,活動(dòng)D這個(gè)功能需要撤掉,我們只需要找到 C功能的版本ID,將代碼恢復(fù)到 C功能,然后重新合并一次 E功能
后滾到 C,然后增加 E功能
Timeline ----- [ 往期里程碑 ] -----> [ 本次升級(jí)里程碑 ] -----> [ 未來升級(jí)里程碑 ]|Vo----------o-----o----------o---------o^ ^ ^ ^ ^A功能 B功能 C功能 D作廢 E功能
前滾操作
當(dāng)撤掉的功能需要恢復(fù)時(shí)就是前滾操作
Timeline ----- [ 往期里程碑 ] -----> [ 本次升級(jí)里程碑 ] -----> [ 未來升級(jí)里程碑 ]|Vo----------o-----o----------o---------o^ ^ ^ ^ ^A功能 B功能 C功能 D功能 E功能
前滾到任意提交版本
Timeline ----- [ 往期里程碑 ] -----> [ 本次升級(jí)里程碑 ] -----> [ 未來升級(jí)里程碑 ]|Vo----------o-----o----------o---------o-----o------------->^ ^ ^ ^ ^ ^A功能 B功能 C功能 D作廢 E功能 N功能
前滾后后滾常見操作
導(dǎo)出最后一次修改過的文件
有時(shí)我們希望把剛剛修改的文件復(fù)制出來,同時(shí)維持原有的目錄結(jié)構(gòu),這樣可能交給運(yùn)維直接覆蓋服務(wù)器上的代碼。我們可以使用下面的命令完成這樣的操作,而不用一個(gè)一個(gè)文件的復(fù)制。
git archive -o update.zip HEAD $(git diff --name-only HEAD^)導(dǎo)出指定版本區(qū)間修改過的文件
首先使用git log查看日志,找到指定的 commit ID號(hào)。
$ git logcommit ee808bb4b3ed6b7c0e7b24eeec39d299b6054dd0Author: 168126. com>Date: Thu Oct 22 13:12:11 2015 +0800統(tǒng)計(jì)代碼commit 3e68ddef50eec39acea1b0e20fe68ff2217cf62bAuthor: netkillerDate: Fri Oct 16 14:39:10 2015 +0800頁面修改commit b111c253321fb4b9c5858302a0707ba0adc3cd07Author: netkillerDate: Wed Oct 14 17:51:55 2015 +0800數(shù)據(jù)庫連接commit 4a21667a576b2f18a7db8bdcddbd3ba305554ccbAuthor: netkillerDate: Wed Oct 14 17:27:15 2015 +0800init repo導(dǎo)入 b111c253321fb4b9c5858302a0707ba0adc3cd07 至 ee808bb4b3ed6b7c0e7b24eeec39d299b6054dd0 間修改過的文件。$ git archive -o update2.zip HEAD $(git diff --name-only b111c253321fb4b9c5858302a0707ba0adc3cd07)
回撤提交
首先 reset 到指定的版本,根據(jù)實(shí)際情況選擇 --mixed 還是 --hard
git reset --mixed 096392721f105686fc3cdafcb4159439a66b0e5b --orgit reset --hard 33ba6503b4fa8eed35182262770e4eab646396cd --git push origin --force --allorgit push --force --progress "origin" master:master
撤回單個(gè)文件提交
例如撤回 project/src/main/java/cn/netkiller/controller/DemoSceneController.java 到上一個(gè)版本
api.netkiller.cn git:(testing) git log project/src/main/java/cn/netkiller/controller/DemoSceneController.javacommit b4609646ee60927fe4c1c563d07e78f63ab106ea (HEAD -> testing, origin/testing)Author: Neo ChenDate: Wed Nov 17 18:49:27 2021 +0800手工合并,臨時(shí)提交commit bc96eb68ad73d5248c8135609191c51e258edf10Author: TomDate: Thu Oct 21 16:29:20 2021 +0800獲取激活場(chǎng)景commit d564ea25bd556324f1f576357563a8ee77b3bdd9Author: TomDate: Thu Oct 21 15:15:26 2021 +0800獲取激活場(chǎng)景commit d5a40165ad24a3a021fe58c6d78e0b7d97ab3cc5Author: TomDate: Thu Oct 21 14:43:16 2021 +0800新增場(chǎng)景角色增加commit aa98662cb9e781e328ee3d5cec23af29c81050d9Author: TomDate: Thu Oct 21 09:55:29 2021 +0800新增場(chǎng)景角色增加commit 140d22a8d4ea7fcc775d4372e8beb6d854831512Author: JerryDate: Sat Oct 16 15:27:30 2021 +0800場(chǎng)景接口修改commit 2ddbb1ff933de663305db2396d99030c938c267aAuthor: TomDate: Fri Oct 15 10:55:30 2021 +0800
只顯示最后五條記錄
? api.netkiller.cn git:(testing) git log -5 project/src/main/java/cn/netkiller/controller/DemoSceneController.java? api.netkiller.cn git:(testing) git reset bc96eb68ad73d5248c8135609191c51e258edf10 project/src/main/java/cn/netkiller/controller/DemoSceneController.javaUnstaged changes after reset:M project/src/main/java/cn/netkiller/controller/DemoSceneController.java? api.netkiller.cn git:(testing) ? git statusOn branch testingYour branch is up to date with 'origin/testing'.Changes to be committed:(use "git restore --staged..." to unstage)modified: project/src/main/java/cn/netkiller/controller/DemoSceneController.javaChanges not staged for commit:(use "git add..." to update what will be committed)(use "git restore..." to discard changes in working directory)modified: project/src/main/java/cn/netkiller/controller/DemoSceneController.java? api.netkiller.cn git:(testing) ? git add project/src/main/java/cn/netkiller/controller/DemoSceneController.java? api.netkiller.cn git:(testing) ? git commit -m '恢復(fù)到上一個(gè)版本'[testing 9959acd4] 恢復(fù)到上一個(gè)版本1 file changed, 6 insertions(+), 8 deletions(-)
提交代碼怎樣寫注釋信息
將任務(wù)ID寫在代碼提交注釋信息當(dāng)中,可以實(shí)現(xiàn)代碼與任務(wù)的綁定,我們?cè)陧?xiàng)目平臺(tái)上查看代碼的時(shí)候,可以直接點(diǎn)擊編號(hào)跳到對(duì)應(yīng)的任務(wù)。這樣便清晰的直到本次提交對(duì)應(yīng)的任何和需求文檔,便于代碼溯源。
Fixed Bug
svn ci -m "- Fixed bug #53412 (your comment)"Implementedsvn ci -m "- Implemented FR #53271, FR #52410 (Building multiple XXXX binary)"Addsvn ci -m "- Add Feature #534 (your message)"
升級(jí)與發(fā)布相關(guān)
分支與版本的關(guān)系
各種版本來自與那個(gè)分支,它們的對(duì)應(yīng)關(guān)系是什么?
分支與版本的關(guān)系:
Alpha 內(nèi)部測(cè)試環(huán)境,面向測(cè)試人員,不穩(wěn)定版本。來自 testing 分支
Beta / Preview / Unstable 新特性,預(yù)覽版,面向用戶體驗(yàn)。來自 staging 分支
Stable = Release 穩(wěn)定版,發(fā)行版來自 master/main 以及 tag 標(biāo)簽
分支與標(biāo)簽的區(qū)別
分支與標(biāo)簽的區(qū)別是,分支中的代碼可以修改,標(biāo)簽可以視為只讀分支。
Release Notes
Release Notes 撰寫說明
當(dāng)一個(gè)項(xiàng)目升級(jí)時(shí),需要寫一個(gè)文檔紀(jì)錄這次變動(dòng)
內(nèi)容包括
新增了什么
更改了什么
修復(fù)了什么
未解決得問題
改善了什么
忽略了什么
常用信息類型
New
Changed
Fixed
Unresolved
Improved
Ignore
例?1.3.?Example - Release Notes
NEW - xxxxxxxxxxxxx
CHANGED - xxxxxxxxxxxxx
FIXED - xxxxxxxxxxx
UNRESOLVED - xxxxxxxxx
IMPROVED - xxxxxxxxx
你也同樣可以參考很多開源組織編寫的Release Notes,例如apache, mysql, php 等等
License
使用開源軟件需要知道各種 License 區(qū)別,以免出現(xiàn)法律糾紛。
GPL 你可以免費(fèi)使用,但修改后必須開源。
GPLv3 你可以免費(fèi)使用,但修改后必須開源,不允許加入閉源商業(yè)代碼。
BSD 你可以免費(fèi)使用,修改后可不開源,基本上你可以我所欲為。
Linux 中有許多BSD代碼,但BSD卻不能移植Linux 代碼到BSD中,這是因?yàn)镚PL License。
http://www.apache.org/licenses/

