Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks

          關(guān)于分支模式

          并行軟件開發(fā)是企業(yè)級環(huán)境下軟件開發(fā)的一種不可避免的模式,這種開發(fā)模式可以說是任何大中型軟件產(chǎn)品和項目所必需的。然而,并行開發(fā)在為我們的開發(fā)效率提高保證的同時,也會給我們的開發(fā)管理帶來諸多問題:

          * 什么時候進(jìn)行分支?
          * 什么時候進(jìn)行合并?
          * 如何選擇有效的分支策略?
          * 如何保證不同分支上的代碼同步問題?
          * 如果建立對分支訪問控制的授權(quán)機(jī)制?
          * 如何避免頻繁的合并沖突?
          * 如何處理被復(fù)用的代碼?
          * ……

          可以說并行開發(fā)中的分支與合并是一個涉及到環(huán)境、方法和技術(shù)平臺等諸多因素的綜合性難題,在這種場合下,“模式(Pattern)”可能是解決上述 問題的一個很好的工具。所謂模式,其實就是解決某一類問題的方法論。你把解決某類問題的方法總結(jié)歸納到理論高度,那就是模式。Alexander給出的經(jīng) 典定義是:每個模式都描述了一個在我們的環(huán)境中不斷出現(xiàn)的問題,然后描述了該問題的解決方案的核心。通過這種方式,你可以無數(shù)次地使用那些已有的解決方 案,無需在重復(fù)相同的工作。

          在不同的領(lǐng)域有不同的模式,具體到并行開發(fā)領(lǐng)域,“分支模式”是專門針對并行開發(fā)環(huán)境下分支及合并作業(yè)中的各種不同的操作方法抽象出來的一套方法論。其主要由以下幾部分組成:

          結(jié)構(gòu)模式——通過約束和指導(dǎo)分支/代碼線的整體結(jié)構(gòu),實現(xiàn)并行開發(fā)的組織結(jié)構(gòu)、開發(fā)模式及開發(fā)過程的約束和指導(dǎo)。

          規(guī)則模式——通過對特定分支/代碼線實施的約束,實現(xiàn)對該分支/代碼線相關(guān)的操作進(jìn)行約束,如訪問控制及合并等操作的約束。

          創(chuàng)建模式——提供對分支/代碼線創(chuàng)建的約束

          反模式——以反例的方式展示并行開發(fā)中常見的行為誤區(qū)和陷阱,并提供有效的解決方案。

          分支模式在并行開發(fā)中的應(yīng)用難點有兩個:一是如何根據(jù)企業(yè)的實際情況選擇適合的分支模式,二是如何構(gòu)建一個技術(shù)平臺來將這些分支模式的理論和方法有 效的應(yīng)用于實踐。為此,我們專門在此開辟專欄和大家分享并行開發(fā)中分支模式相關(guān)的理論、方法以及如何將這些理論和方法付諸實現(xiàn)的相關(guān)實踐。

          主線(結(jié)構(gòu)模式)

          一、分支模式的相關(guān)定義

          模式 主線

          別名 主干、主錨線、本線、地線(Main Trunk, Main Anchor Line, Home Line, Ground Line )

          場景

          在開發(fā)和維護(hù)周期中,因為各種原因需要創(chuàng)建多條代碼線,典型的代碼線是發(fā)布線、維護(hù)線和集成線。這在采用每發(fā)布代碼線、并行維護(hù)/開發(fā)線和重疊發(fā)布線 (或者其任何變形模式)的情況下尤為如此。隨著項目的進(jìn)行,會創(chuàng)建出越來越多的代碼線,從而導(dǎo)致項目的版本樹越來越寬。

          連續(xù)的瀑布式分支(應(yīng)該避免的情況)

          問題

          怎樣確保當(dāng)前活動代碼線的數(shù)量在可控范圍內(nèi),以及避免項目的版本樹過寬過深?

          動機(jī)

          • 通常,每條代碼線在某個時間點需要將變更集合并至其父分支。所以越多的代碼線就意味著更多的合并,而越多的合并意味著越多的同步工作。
          • 當(dāng)后續(xù)的版本發(fā)布時,看起來只有在當(dāng)前版本的代碼線上開創(chuàng)一個新的分支才算是合理的。

          解決方案

          在每一個分支樹中保持一個“主”分支或代碼線作為主干,而不是持續(xù)的瀑布式從分支創(chuàng)建分支從而使分支樹變得寬廣而笨重(在每一對父子分支之間需要大量的同步工作)

          擁有主線的瀑布式分支

          當(dāng)為主發(fā)布創(chuàng)建代碼線的時刻來到時,我們不會從前一個發(fā)布線創(chuàng)建新的發(fā)布線,而是將先前的發(fā)布線合并回主線,然后再從主線創(chuàng)建新的發(fā)布線。
          為特定代碼線或分支合并回來的過程被稱為“主線化”、“主干化”、“歸位”、“錨定”或“接地”("mainlining," "trunking," "homing," "anchoring," or "grounding.")。

          變種 穩(wěn)定接收線(也稱為穩(wěn)定主線、主集成線和基礎(chǔ)集成線(Stable Mainline, Main Integration Line, Base Integration Line))

          保持一個穩(wěn)定的,可靠的主要開發(fā)主干可以用來從其他代碼線導(dǎo)入(接收)穩(wěn)定基礎(chǔ)。在代碼線上不會直接發(fā)生開發(fā)工作,所有集成工作必須來自其他代碼線(不是一個單獨的離散的活動分支)。這個規(guī)則唯一的例外是為了保證代碼線構(gòu)建和功能一致性的集成變更。

          (用以接收穩(wěn)定基線的穩(wěn)定主線——實際上就是通常所說的基線)

          LAG開發(fā)線(也稱為主開發(fā)線、中央線和主流)

          把主干作為最新的最好的(LAG)會一直進(jìn)展的開發(fā)線,所有前面的發(fā)布的代碼線都會在其退休后被合并入其中。主干作為下一步/最后的開發(fā)發(fā)布(不是 維護(hù),而是開發(fā),包括顯著的改進(jìn)和新特性)的開發(fā)線使用,因此當(dāng)B2發(fā)布的工作已經(jīng)準(zhǔn)備好開始,而A1發(fā)布已經(jīng)完成或逐漸停止,則建立一個新的分支來結(jié)束 A1的工作(見延遲分支),而LAG線則用來針對B2(最新的和最好的開發(fā)工作)發(fā)布的工作。

          (LAG開發(fā)主線)

          對于特定代碼線或分支合并到滯后(LAG)開發(fā)線的過程也可以稱為"LAGging," "mainlining," "LAG-lining," or "mainstreaming."。

          盡管作為一個主線使用,LAG線也可以作為主線與穩(wěn)定接收線結(jié)合:

          (有一條穩(wěn)定主線用于接收發(fā)布版本的LAG開發(fā)主線)

          二、模式的分析

          主線模式及其變種主要試圖從分支的結(jié)構(gòu)上約束其不合理的擴(kuò)展和延伸,而盡量使主線成為其他代碼線創(chuàng)建的來源及合并的目標(biāo)。穩(wěn)定接收線(也就是通常所 說的基線)用于接受并保存相對穩(wěn)定的版本,通常情況下其只接受版本(通常情況下為直接保存版本的鏡像而非合并操作)而不進(jìn)行其他任何操作。

          三、主線模式在Subversion環(huán)境下的實現(xiàn)

          如上圖所示實際上就是有一條基線伴隨的LAG開發(fā)線模式,實現(xiàn)該模式相關(guān)的約束包括:

          1、所有的代碼線(不包括分支)都從主線創(chuàng)建

          2、主線以外的代碼線的合并操作都以主線為目標(biāo)

          3、基線只接受版本(直接保存版本的鏡像而非合并操作)而不進(jìn)行其他任何操作。

          寬松訪問線(規(guī)則模式)

          一、分支模式的相關(guān)定義

          模式 寬松訪問線(Relaxed-Access Line)

          問題 如何確定代碼線訪問控制規(guī)則的限制或排他程度?

          動機(jī)

          • 如果許多開發(fā)者在代碼線上工作,或某一些人缺乏經(jīng)驗,那嚴(yán)格的治理是必要的。
          • 如果代碼線上發(fā)生的工作具有顯著的風(fēng)險級別或難度,則檢入和合并需要更緊密的監(jiān)控和/或驗證。
          • 保證代碼線一直處于完整的狀態(tài)非常重要,這樣就不會影響其它工作在代碼線上的人們。
          • 如果代碼線對應(yīng)了特定提升級別(見階段集成線)或生命周期階段,這也許指明了對特定代碼線驗證一致性的必要性級別。

          解決方案

          如果代碼線是用來開發(fā)或維護(hù)(而不是排它或集成),并且工作在代碼線上的團(tuán)隊規(guī)模相對較小,人員富于經(jīng)驗并可靠,那么給開發(fā)者有相對寬松自由的區(qū) 域,讓他們做他們已經(jīng)知道如何去做的事情:在一起以及時的方式工作。使用最小檢查和控制,但是要確保代碼線所有者可以認(rèn)真對待他的工作,并可以一直知道代 碼線的狀態(tài)以及確認(rèn)完整性是否被特定風(fēng)險/復(fù)雜開發(fā)任務(wù)危害。

          相關(guān)模式

          MYOC(合并你自己的代碼)及其變種PYOC(傳遞你自己的代碼)是使用寬松訪問線最常見的副產(chǎn)品(或原因),如果在你的環(huán)境中,風(fēng)險較小,而且開發(fā)者合并自己的變更到代碼線的交流通暢,那么我們有充足的理由使用寬松訪問。

          二、對模式的分析

          這種訪問模式通常適用于沖突不嚴(yán)重(如開發(fā)初期或彼此按模塊獨立開發(fā))的情況,要求相關(guān)人員具備一定的水準(zhǔn)以保證開發(fā)的質(zhì)量,而在開發(fā)的后期通常不適用這種模式。

          三、寬松訪問線(Relaxed-Access Line)在Subversion環(huán)境下的實現(xiàn)

          如上圖所示(相關(guān)內(nèi)容只是相關(guān)模式實現(xiàn)的一個實例,實際使用時可根據(jù)實際需求對角色及授權(quán)進(jìn)行調(diào)整):

          1、代碼線的所有者對代碼線擁有完全的操作權(quán)限

          2、主管及EPG成員僅對代碼線擁有有限的操作權(quán)限(讀)

          3、除測試人員以外的項目成員都對代碼線擁有完全的讀寫權(quán)限

          4、代碼線的所有者以及項目經(jīng)理和配置經(jīng)理擁有對代碼線鎖的權(quán)限

          大爆炸式集成(反模式)

          一、分支模式的相關(guān)定義

          陷入的誤區(qū) 大爆炸集成

          別名 大怪獸集成

          癥狀

          由于某種原因,一直不選擇集成,直到(軟件)要發(fā)布的時候 ,才把所有的分支一下子全部交給倒霉的集成者進(jìn)行集成。經(jīng)常性的增量集成看起來是流行的常識性規(guī)則(亦稱為:盡早且經(jīng)常合并),大爆炸(的方式)顯然在隔 離和避免風(fēng)險方面達(dá)到了極致,這是大怪物地結(jié)束合并,結(jié)果不是一個“大爆炸”,而是以“哭泣”告終。

          大爆炸式的集成(需要避免的反模式)

          原因

          一個原因是我們未能成功找到盡早集成和經(jīng)常集成的地正確“節(jié)奏”和“脈搏”。有時‘大怪獸式集成’是“整合恐懼癥”帶來的附加品,在盡力縮小合并數(shù) 量的時候,結(jié)果會是一個延期而至的可怕的復(fù)雜合并的結(jié)尾。因而,在這種情況下,“集成是魔鬼” 變成了自我實現(xiàn)的一種預(yù)言,并且在失敗的惡性循環(huán)中不斷加強(qiáng)。

          影響

          太多人都很熟悉所造成的后果,直到一切已經(jīng)太晚,如系統(tǒng)不能正確的構(gòu)建,無法通過測試,或部分代碼與其它代碼工作不能協(xié)同工作,我們才能發(fā)現(xiàn)這問 題。直到項目生命周期的下一個階段,這些信息才得到交流,相關(guān)的風(fēng)險和返工將會非常巨大,會導(dǎo)致“合并是魔鬼”或“合并恐懼”的心理。

          修復(fù)和預(yù)防

          使用盡早經(jīng)常性的集成或使用一個或更多的變種來確保以一定頻率和間隔執(zhí)行集成,以在時間充裕,額外工作較少時盡早分解風(fēng)險和盡快交流問題區(qū)域。你可 以現(xiàn)在或者將來,或者由你自己決定何時付出,有規(guī)律的經(jīng)常的集成可以迫使你在每次迭代和集成計劃中只需要付出很少的努力,通過分解減少隨時間積累的合并負(fù) 擔(dān),從而定義了健康項目的“脈搏”。

          二、模式的分析

          這種大爆炸式的集成在缺乏有效管理的團(tuán)隊中是經(jīng)常發(fā)生的,我們經(jīng)常可以看到這樣的場景:明天就要發(fā)版本了(尤其是非計劃的發(fā)布),今天所有的相關(guān)人員都一起合版本,于是大家驚訝的發(fā)現(xiàn)系統(tǒng)出現(xiàn)無數(shù)的合并沖突和缺陷,而在這種情況下,延遲發(fā)布幾乎是唯一的選項了。
          要避免這種最好的方式就是通過某種機(jī)制約束分支的周期和合并。

          三、大爆炸式集成在Subversion環(huán)境下的規(guī)避方式

          如上圖所示,在創(chuàng)建分支時添加如下約束:

          1、創(chuàng)建分支時定義分支的周期(通常任務(wù)分支都是需要及時終結(jié)的),并強(qiáng)制終結(jié)


          2、創(chuàng)建分支時定義分支的合并周期和約束方式(包括提醒和強(qiáng)制合并兩種可選方式)

          通過上述的約束,可以使分支/代碼線及時的合并和終結(jié),從而避免大爆炸式集成的發(fā)生

          代碼所有權(quán)(規(guī)則模式)

          一、分支模式的相關(guān)定義

          模式 代碼線所有權(quán)(Codeline Ownership)

          別名 分支所有權(quán)(Branch Ownership )

          場景

          作為一名程序員,在一組多代碼線的環(huán)境下,并至少在一條代碼線上開發(fā)。代碼線規(guī)則已經(jīng)為該代碼線定義好檢入/檢出的規(guī)則。有些人要在代碼線上進(jìn)行某些工作,但是該規(guī)則并沒有允許這樣的操作,或者就是規(guī)則對一些特定事務(wù)的描述含糊不清。

          問題

          能影響代碼線的動作能否執(zhí)行?在保證代碼線的完整性和連續(xù)性的同時,怎樣做上面的決策?

          動機(jī)

          • “理論上,實踐和理論是一致的;但在實踐中,其兩者卻有極大的不同。”沒有一個規(guī)則能夠涵蓋所有的情況。 代碼線規(guī)則從理論上滿足了需求,但是在實踐中,則還有必要其他一些東西補充理論和實踐之間的缺失。
          • 如果代碼線規(guī)則不是很清楚,則開發(fā)人員需要將其定義清楚。
          • 代碼線規(guī)則是會被違背的,不管是有意還是無意。
          • 代碼線必須保持正確且連續(xù)的狀態(tài),以避免與正在進(jìn)行的開發(fā)任務(wù)起相反的作用。.

          解決方案

          為每個代碼線分配一名所有者(owner),其相應(yīng)的職責(zé)如下

          • 如果代碼線的規(guī)則定義不清晰,則定義清楚;
          • 如果檢入的配置項與代碼線的規(guī)則相抵觸,則決定讓其保留在代碼線中,還是回退到上一個版本
          • 制定相應(yīng)的規(guī)則,防止代碼線處于含糊不清狀態(tài)或不適用實際情況
          • 在該代碼線上,輔助或執(zhí)行變更的集成
          • 決定何時對代碼線進(jìn)行凍結(jié),解凍;何時代碼線必須結(jié)束生命周期并且合并到主線(Mainline)中

          所有權(quán)(Ownership)并不一定意味著排他式的訪問,但卻表示用戶認(rèn)證訪問控制。也許只有代碼線的所有者才能檢入文件(受限訪問線);或者, 其他人只要在檢入前獲得代碼線所有者的同意,即可檢入代碼線,又或者在檢入后立刻通知代碼線所有者(寬松訪問線)。代碼線規(guī)則必須清楚地定義訪問控制類型 相對應(yīng)的所有權(quán)類型。通常來講,在代碼線上工作的開發(fā)人員越多,相應(yīng)的所有權(quán)策略也越嚴(yán)格。同樣地,限制程度與代碼線包含活動的風(fēng)險性或是復(fù)雜性,或是對 穩(wěn)定性的要求成正比。在較小的項目和團(tuán)隊中的代碼線中所包含較少的關(guān)鍵任務(wù),在保證代碼線完整性和連續(xù)性的前提下,提供比較隨意,限制較少的訪問控制策 略。

          變種 代碼線專屬(Codeline Dictatorship )

          代碼線的所有權(quán)中極其嚴(yán)格的一種形式,其配置項的檢出和分支都是嚴(yán)格受限的,當(dāng)然更包括檢入。專屬者可能是一個人,或是一個小組。一個常見的例子就 是“遠(yuǎn)程開發(fā)線”。遠(yuǎn)程開發(fā)人員可能被禁止從非遠(yuǎn)程分支中創(chuàng)建新的版本或是分支,因此,本地分支僅僅是“主人(master)”開發(fā)的地方。這實質(zhì)上就是 ClearCase Multisite定義的“分支主人身份(branch mastership)”的概念。

          導(dǎo)致的場景

          • 只有一個人對代碼線的連續(xù)性和完整性負(fù)責(zé)。這樣,代碼線比較可能處于一種穩(wěn)定的狀態(tài)。
          • 保持所有者對代碼線的狀態(tài)負(fù)責(zé),降低了代碼線規(guī)則被踐踏或代碼線被用于錯誤目的的可能。
          • 代碼線的概念完整性由一個頭腦,也就是所有者維護(hù),作為解決代碼線問題的單一權(quán)威。

          二、模式的分析

          代碼線所有權(quán)/代碼線專屬模式強(qiáng)調(diào)的是代碼線所有者對代碼線的控制權(quán),適用于由專人(或角色)對代碼線內(nèi)容進(jìn)行全權(quán)負(fù)責(zé)的情況下使用

          三、代碼線專屬(Codeline Dictatorship )在Subversion環(huán)境下的實現(xiàn)

          如上圖所示(相關(guān)內(nèi)容只是相關(guān)模式實現(xiàn)的一個實例,實際使用時可根據(jù)實際需求對角色及授權(quán)進(jìn)行調(diào)整):

          1、代碼線的所有者對代碼線擁有完全的操作權(quán)限

          2、主管、項目經(jīng)理及配置經(jīng)理僅對代碼線擁有有限的操作權(quán)限(讀)

          3、代碼線的所有者擁有再授權(quán)的權(quán)限

          代碼線規(guī)則(規(guī)則模式)

          一、分支模式的相關(guān)定義

          模式名稱 代碼線規(guī)則

          別名 每代碼線規(guī)則

          適用環(huán)境 使用多條代碼線開發(fā)軟件的情況下。

          問題 開發(fā)人員如何知道需要將他們的代碼存入哪條代碼線中,并且何時保存?

          動機(jī)

          • 每條代碼線都有不同的目的 ;
          • 代碼線的名稱通常能暗示其目的;
          • 代碼線的名稱通常不能全部表達(dá)代碼線的使用要點;
          • 如果代碼寫入到錯誤的代碼線,而這錯誤的變更必須要回退,導(dǎo)致生產(chǎn)率的降低;
          • 使用正規(guī)文檔描述代碼線的用法會很有幫助,但是需要額外的記錄和維護(hù);
          • 這個文檔太過拘謹(jǐn)就會有一點過度規(guī)劃和專橫了;

          解決方案

          除了給分支/代碼線起一個有意義的名稱之外,要給每條代碼線明確目的,并使用簡捷明了的策略描述其目的。其中應(yīng)該包括以下一些要點:

          • 代碼線包含何種工作,例如:開發(fā)、維護(hù)、一種特定的版本、功能或是子系統(tǒng);
          • 配置項在怎樣的條件下才能被檢入,檢出,分支,合并;
          • 對于不同的個人,角色,組,代碼線該設(shè)置怎樣的讀寫權(quán)限的限制;
          • 導(dǎo)入/導(dǎo)出關(guān)系:代碼應(yīng)該從其它哪些代碼線中接受變更,同時應(yīng)該將變更應(yīng)用于其它哪些代碼線;
          • 代碼線的生命周期或結(jié)束條件;
          • 預(yù)期的工作負(fù)載以及集成頻率。

          讓規(guī)則簡短扼要:一個簡單的經(jīng)驗方法是1-3段(各自25行25個字符,一頁絕對是上限)。



          請切記不是所有的代碼線策略都需要上面所有的信息,只需要制定自己所需要的。一些版本控制工具允許在每個分 支、代碼線的名稱上附加詳細(xì)的注解,這是存放合適簡短代碼線規(guī)則描述的理想地方。開發(fā)者可以通過包含代碼線名稱的命令來查看代碼線規(guī)則,而無需在別的地方 找文檔。否則,將代碼線規(guī)則放在大家都知道的隨手可得的地方(或許提供簡單的命令或宏,對于給定代碼線名稱可以快速顯示規(guī)則)。

          二、對模式的分析

          代碼線規(guī)則這種模式實際上就是一種最基本的分支/代碼線使用規(guī)范,它強(qiáng)調(diào)每條分支/代碼線都應(yīng)該以快捷而有效的方式記錄其相關(guān)的信息,并且這些信息可以隨時被方便的訪問。

          作為更進(jìn)一步的要求,除了將相關(guān)信息記錄在案,在某些情況下對其中部分內(nèi)容(如分支的周期及合并的頻率等)進(jìn)行提醒甚至約束也是有其必要性的。

          三、寬松訪問線(Relaxed-Access Line)在Subversion環(huán)境下的實現(xiàn)

          如上圖所示:

          1、每條分支/代碼線代碼線創(chuàng)建時都有效的記錄相關(guān)信息

          2、對分支的生命周期和合并周期提供約束控制

          注:上述功能的實現(xiàn)是基于在系統(tǒng)底層屏蔽了所有不受控的分支創(chuàng)建操作,而只能在特定應(yīng)用系統(tǒng)內(nèi)進(jìn)行分支/代碼線的創(chuàng)建,從而使所有分支/代碼線相關(guān)操作都處于受控狀態(tài)


          posted on 2009-09-02 09:46 seal 閱讀(1204) 評論(0)  編輯  收藏 所屬分類: 版本控制
          主站蜘蛛池模板: 台湾省| 德令哈市| 碌曲县| 铜山县| 吉安市| 冀州市| 巴塘县| 横峰县| 吴川市| 花莲市| 伊春市| 苍山县| 北海市| 龙山县| 广州市| 鄱阳县| 绥中县| 富锦市| 景泰县| 从江县| 腾冲县| 遂平县| 蒙阴县| 库尔勒市| 五家渠市| 秭归县| 吉木萨尔县| 台中市| 莱阳市| 石阡县| 庆云县| 绥江县| 搜索| 鄂州市| 贞丰县| 三江| 普宁市| 渭源县| 嘉义市| 比如县| 吴堡县|