產(chǎn)品快速迭代時(shí)用Git做分支管理的詳細(xì)步驟

一躯舔、前言

本文用實(shí)例來(lái)講解Git的分支管理在產(chǎn)品快速迭代開(kāi)發(fā)過(guò)程中解決實(shí)際問(wèn)題的詳細(xì)方案,面向的是對(duì)Git有一定了解的朋友(多圖預(yù)警)函喉。


二零截、背景

最近接手了一個(gè)代碼質(zhì)量慘不忍睹的項(xiàng)目,立即著手進(jìn)行重構(gòu)昵慌,由于產(chǎn)品已經(jīng)發(fā)布上線假夺,在重構(gòu)新版的過(guò)程中還要一直維護(hù)著老版本,所以如何維護(hù)好兩個(gè)版本的代碼就成了一個(gè)問(wèn)題斋攀。由于我們的團(tuán)隊(duì)一直以來(lái)使用Git時(shí)都忽視了其最大的優(yōu)勢(shì) - 分支管理已卷,所以正好趁此機(jī)會(huì)規(guī)范團(tuán)隊(duì)中Git的使用姿勢(shì)。


三淳蔼、關(guān)鍵字提示

master指的是本地主分支悼尾,也就是我們新建項(xiàng)目首次關(guān)聯(lián)到Git上的本地主分支柿扣;
origin/master指的是遠(yuǎn)程主分支,也就是我們新建項(xiàng)目首次提交到Git上的遠(yuǎn)程主分支闺魏;
HEAD指的是我們當(dāng)前所開(kāi)發(fā)的代碼的版本指針未状,指向的是某個(gè)分支上的節(jié)點(diǎn);
commit指的是在當(dāng)前分支新建一個(gè)節(jié)點(diǎn)析桥,保存當(dāng)前的代碼版本司草;
這四個(gè)是我下面要經(jīng)常提到的關(guān)鍵字,其他的遇到了再另外解釋?zhuān)?/p>


四泡仗、引出問(wèn)題

假設(shè)我們的產(chǎn)品版本A已經(jīng)發(fā)布上線了埋虹,現(xiàn)在我們繼續(xù)開(kāi)發(fā)版本B,今天產(chǎn)品經(jīng)理過(guò)來(lái)告訴你版本A有一個(gè)十萬(wàn)火急的Bug娩怎,這個(gè)時(shí)候我們肯定是想辦法拿到版本A的代碼去修復(fù)Bug搔课,那么問(wèn)題來(lái)了:

1、在拿版本A的代碼時(shí)截亦,如何去保存我們寫(xiě)到一半的版本B的代碼爬泥?

有的朋友肯定會(huì)把寫(xiě)到一半的代碼commit到本地去解決這個(gè)問(wèn)題,這是最簡(jiǎn)單的方式但是也是錯(cuò)誤的方式崩瓤,其僅僅是達(dá)到了目的袍啡,但是這樣會(huì)在版本節(jié)點(diǎn)上留下很多垃圾數(shù)據(jù),經(jīng)常會(huì)誤導(dǎo)團(tuán)隊(duì)的其他成員却桶。

2境输、在修改完版本A的Bug后,如何提交這次的修改呢颖系?

版本A的節(jié)點(diǎn)上直接進(jìn)行commit的話嗅剖,HEAD指針會(huì)游離出去,也就是我們經(jīng)常遇見(jiàn)的問(wèn)題HEAD detached at head或者HEAD detached from master嘁扼,搞不好會(huì)丟失一部分代碼窗悯,如果你已經(jīng)遇到這個(gè)問(wèn)題了,這里只提供方案就是找到HEAD現(xiàn)在所指向的未知分支偷拔,給其命名蒋院,然后合并到master分支上,具體操作自行搜索莲绰。

3欺旧、先不管用什么辦法,假如我在修改完版本A后真的將此次的修改記錄成功提交了蛤签,如何恢復(fù)我寫(xiě)到一半的版本B 的代碼呢辞友?

這里一定有修改完后選擇不提交,直接手動(dòng)合并到版本B的朋友,目的又達(dá)到了称龙,但是這樣會(huì)導(dǎo)致此次對(duì)版本A的修改以未知的方式記錄到版本B上去了留拾,時(shí)間長(zhǎng)了恐怕自己都不知道當(dāng)初是改了哪里了。


五鲫尊、解決方案

帶著以上三個(gè)問(wèn)題痴柔,我們進(jìn)行情景再現(xiàn),用Demo來(lái)演示一個(gè)項(xiàng)目在Git上的正確管理步驟疫向。

  • 初始導(dǎo)入
    現(xiàn)在我們拿到了版本A的代碼咳蔚,將其提交到遠(yuǎn)程Git倉(cāng)庫(kù)上大家應(yīng)該是沒(méi)有問(wèn)題的,從Android Studio的版本節(jié)點(diǎn)樹(shù)可以看到搔驼,可以看到我們有了本地主分支master和遠(yuǎn)程主分支origin/master谈火,HEAD指向的是本地的master分支。

  • 創(chuàng)建開(kāi)發(fā)分支
    現(xiàn)在版本A已經(jīng)發(fā)布舌涨,我們要進(jìn)行版本B的開(kāi)發(fā)了糯耍,這里最關(guān)鍵的是我們不可以在master主支上直接進(jìn)行開(kāi)發(fā),master主支應(yīng)當(dāng)作為生產(chǎn)環(huán)境上的正式版本的發(fā)布分支囊嘉,該分支的每個(gè)版本最好是有效的温技、干凈的,原則上嚴(yán)禁對(duì)發(fā)布版本直接進(jìn)行修改哗伯。所以我們需要一個(gè)開(kāi)發(fā)分支荒揣,稱(chēng)為developer分支篷角,這個(gè)分支用來(lái)專(zhuān)門(mén)開(kāi)發(fā)新版本焊刹。
    現(xiàn)在我們從版本A創(chuàng)建出一個(gè)developer分支,在工作空間根目錄cmd下執(zhí)行:

    git branch developer master
    

    即從master創(chuàng)建developer的意思恳蹲,版本樹(shù)如下:

可以看到我們現(xiàn)在有了本地的developer分支虐块,我們還要把該分支上傳到遠(yuǎn)程倉(cāng)庫(kù),執(zhí)行
git push origin developer:developer
執(zhí)行結(jié)果如下嘉蕾,意思是將本地的developer分支上傳到遠(yuǎn)程origin/developer贺奠,如果遠(yuǎn)程不存在'origin/developer'分支,則新建之


為了便于觀察错忱,我在developer分支上提交了一個(gè)節(jié)點(diǎn)儡率,現(xiàn)在觀察版本樹(shù)

  • 保存正在寫(xiě)的代碼
    現(xiàn)在我們正在developer分支上改動(dòng)代碼,但是master分支出現(xiàn)了一個(gè)緊急的bug以清,我們應(yīng)該執(zhí)行git stash儿普,作用是暫存我們?cè)?code>developer上做的沒(méi)有提交的修改,然后我們執(zhí)行
    git branch bugbranch master
    從master分支檢出一個(gè)新的bug分支bugbranch掷倔,而不是直接切換到master分支上進(jìn)行修改∶己ⅲ現(xiàn)在觀察版本樹(shù),可以看到從master分支分離出了bugbranch分支纹份,現(xiàn)在HEAD指向的就是該分支古掏。

  • 修復(fù)bug
    現(xiàn)在我們?cè)?code>bugbranch分支上修復(fù)了bug盗蟆,并且測(cè)試通過(guò)了掏呼,那么接下來(lái)我們需要把修復(fù)后的代碼commit一次鉴未,做一個(gè)節(jié)點(diǎn)保存記錄一下裙盾,現(xiàn)在觀察版本樹(shù)

  • 合并bug分支
    bugbranch分支上我們已經(jīng)修復(fù)了bug薯鼠,那么我們需要將bugbranch分支上修復(fù)后的代碼合并到master分支上去馋没,做一個(gè)節(jié)點(diǎn)并且發(fā)布新版本殃姓,先切換到master分支git checkout master袁波,然后執(zhí)行
    git merge bugbranch
    bugbranch分支合并到master分支上,現(xiàn)在觀察版本樹(shù)

可以看到現(xiàn)在masterbugbranch分支上的代碼已經(jīng)合并成功一致蜗侈,接下來(lái)還要將最新的代碼push到遠(yuǎn)程分支上去篷牌,執(zhí)行git push origin master:master,觀察下邊的版本樹(shù)可以看到踏幻,現(xiàn)在本地和遠(yuǎn)程分支上的代碼都已經(jīng)更新完成枷颊,我們可以發(fā)布新版本了

  • 合并修復(fù)的bug到開(kāi)發(fā)分支
    到了這里bugbranch分支的任務(wù)就完成了,我個(gè)人認(rèn)為已經(jīng)沒(méi)有保留的必要了该面,因?yàn)楸敬涡薷牡倪^(guò)程已經(jīng)記錄到了master的節(jié)點(diǎn)上夭苗,如果以后出了問(wèn)題,再?gòu)漠?dāng)前節(jié)點(diǎn)重新檢出一個(gè)分支就好隔缀,執(zhí)行
    git branch -d bugbranch

刪除bugbranch分支题造,現(xiàn)在bug已經(jīng)修復(fù)并且發(fā)布,我們需要回到正常的開(kāi)發(fā)分支上去繼續(xù)開(kāi)發(fā)新的功能猾瘸,執(zhí)行git checkout developer先切換到developer分支界赔,然后執(zhí)行
git stash pop
取出我們當(dāng)時(shí)在developer分支上stash的未提交的代碼,至于我們?cè)?code>master分支上修復(fù)的bug怎么更新到developer分支上牵触,分兩種情況處理:

1淮悼、如果該bug影響到新模塊的開(kāi)發(fā),那就手動(dòng)更新修復(fù)部分的代碼揽思,到時(shí)候新模塊開(kāi)發(fā)完成之后我們將developer分支合并回master的時(shí)候就會(huì)產(chǎn)生沖突袜腥,解決掉就好;

2钉汗、如果該bug對(duì)新模塊的開(kāi)發(fā)沒(méi)影響羹令,那就不用做處理,到時(shí)候?qū)?code>developer分支合并回master之后修復(fù)后的代碼自然就更新了损痰。

  • 合并開(kāi)發(fā)分支到master
    現(xiàn)在我們developer分支上的新功能寫(xiě)完并且測(cè)試通過(guò)了福侈,我們需要先將developer分支上的代碼都提交到遠(yuǎn)程'developer'分支上,我們發(fā)布新版本的時(shí)候需要先將developer分支的代碼合并到master分支上去徐钠,執(zhí)行git checkout master切換到master分支癌刽,執(zhí)行get merge developer來(lái)進(jìn)行合并,這個(gè)時(shí)候可能會(huì)產(chǎn)生沖突,對(duì)照解決即可显拜。

下面是developer分支向master合并的時(shí)候產(chǎn)生了沖突衡奥,解決掉合并后的版本樹(shù)


接下來(lái)我們需要先將本地的master分支提交更新到遠(yuǎn)程,可以發(fā)現(xiàn)雖然developer分支雖然成功合并到master上了远荠,但是因?yàn)楫a(chǎn)生了沖突矮固,developer分支比master分支落后兩個(gè)節(jié)點(diǎn)(分別是1.解決merge沖突的節(jié)點(diǎn) 2.當(dāng)初修改的bug節(jié)點(diǎn)),也就意味著代碼有了差別譬淳,如下圖所示:

如果出現(xiàn)這種情況档址,需要再次執(zhí)行get merge developer,再合并一次邻梆,這次沖突已經(jīng)被解決了守伸,直接合并成功,接下來(lái)我們直接將本地的developer分支代碼提交到遠(yuǎn)程origin/developer分支即可浦妄,最終的代碼樹(shù)如下:

六尼摹、后言

在快速迭代開(kāi)發(fā)中,經(jīng)常會(huì)有需要緊急處理生產(chǎn)環(huán)境版本bug的時(shí)候剂娄,按照這樣的分支管理操作蠢涝,可以做到快速的拿到每一個(gè)發(fā)布版的代碼;在開(kāi)發(fā)新模塊阅懦、修復(fù)舊bug和二、恢復(fù)舊版本的時(shí)候不互相污染代碼;干凈耳胎、清楚的記錄每次更新惯吕、修復(fù)、迭代的內(nèi)容场晶。

從業(yè)以來(lái)的兩個(gè)團(tuán)隊(duì)都沒(méi)有一個(gè)成熟的git分支管理使用方案混埠,這些處理方式是我在實(shí)際工作中摸索怠缸、總結(jié)出來(lái)的诗轻,是否跟真正正確的使用方式一致不太清楚,但是確實(shí)是解決掉我項(xiàng)目重構(gòu)中實(shí)際遇到的問(wèn)題了揭北,感覺(jué)比較適合中小型團(tuán)隊(duì)使用扳炬,因?yàn)榇髨F(tuán)隊(duì)我也沒(méi)去過(guò),有什么錯(cuò)誤歡迎指出討論搔体,哈哈恨樟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疚俱,隨后出現(xiàn)的幾起案子劝术,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件养晋,死亡現(xiàn)場(chǎng)離奇詭異衬吆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)绳泉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)逊抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人零酪,你說(shuō)我怎么就攤上這事冒嫡。” “怎么了四苇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵孝凌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我月腋,道長(zhǎng)胎许,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任罗售,我火速辦了婚禮辜窑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寨躁。我一直安慰自己穆碎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布职恳。 她就那樣靜靜地躺著所禀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪放钦。 梳的紋絲不亂的頭發(fā)上色徘,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音操禀,去河邊找鬼褂策。 笑死,一個(gè)胖子當(dāng)著我的面吹牛颓屑,可吹牛的內(nèi)容都是我干的斤寂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼揪惦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼遍搞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起器腋,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溪猿,失蹤者是張志新(化名)和其女友劉穎钩杰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體诊县,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡榜苫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翎冲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垂睬。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抗悍,靈堂內(nèi)的尸體忽然破棺而出驹饺,到底是詐尸還是另有隱情,我是刑警寧澤缴渊,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布赏壹,位于F島的核電站,受9級(jí)特大地震影響衔沼,放射性物質(zhì)發(fā)生泄漏蝌借。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一指蚁、第九天 我趴在偏房一處隱蔽的房頂上張望菩佑。 院中可真熱鬧,春花似錦凝化、人聲如沸稍坯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞧哟。三九已至,卻和暖如春枪向,著一層夾襖步出監(jiān)牢的瞬間勤揩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工秘蛔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陨亡,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓缠犀,卻偏偏與公主長(zhǎng)得像数苫,于是被迫代替她去往敵國(guó)和親聪舒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辨液,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容