|
原始出處見:http://www./scmforum/topic.asp?topic_id=547&forum_id=33&cat_id=8 持續(xù)集成
英文原文版權(quán)由Martin Fowler擁有 Martin Fowler
譯者語:2002年1月23日,我們很榮幸的在UMLCHINA組織的網(wǎng)上交流中聆聽了Martin Fowler先生的教誨。在
交流中,Martin Fowler向所有中國軟件開發(fā)者推薦了這篇文章:Continuous Integration(《持續(xù)集成》)。 由于這是Fowler先生送給全體中國軟件開發(fā)者的禮物,所以我絕對不敢獨(dú)占。任何人都可以在任何地方隨意 轉(zhuǎn)載本文,但是在轉(zhuǎn)載時(shí)請保持本文完整性——包括標(biāo)題、版權(quán)聲明、原文鏈接、譯者語……總之,請不要在轉(zhuǎn) 載的時(shí)候做任何改動或增刪。另外,如果能在轉(zhuǎn)載的時(shí)候順手給我一個(gè)mail,我會更加高興。 下面,請開始欣賞這篇精彩的文章。
在任何軟件開發(fā)過程中都有一個(gè)重要的部分:得到可靠的軟件創(chuàng)建(build)版本。盡管知道創(chuàng)建的重要 性,但是我們?nèi)匀粫?jīng)常因?yàn)閯?chuàng)建失敗而驚訝不已。在這篇文章里,我們將討論Matt(Matthew Foemmel)在 ThoughtWorks的一個(gè)重要項(xiàng)目中實(shí)施的過程,這個(gè)過程在我們的公司里日益受到重視。它強(qiáng)調(diào)完全自動化的、可 重復(fù)的創(chuàng)建過程,其中包括每天運(yùn)行多次的自動化測試。它讓開發(fā)者可以每天進(jìn)行系統(tǒng)集成,從而減少了集成中 的問題。 ThoughtWorks公司已經(jīng)開放了CruiseControl軟件的源代碼,這是一個(gè)自動化持續(xù)集成的工具。此外,我們還 提供CruiseControl、Ant和持續(xù)集成方面的顧問服務(wù)。如果需要更多的信息,請與Josh Mackenzie 本文有以下主要內(nèi)容: 持續(xù)集成的優(yōu)點(diǎn) 在這里,我們使用了“持續(xù)集成(Continuous Integration)”這個(gè)術(shù)語,這個(gè)術(shù)語來自于XP(極限編程) 的一個(gè)實(shí)踐。但是我們認(rèn)為:這個(gè)實(shí)踐早就存在,并且很多并沒有考慮XP的人也在使用著它。只不過我們一直用 XP作為軟件開發(fā)過程的標(biāo)準(zhǔn),XP也對我們的術(shù)語和實(shí)踐產(chǎn)生了深遠(yuǎn)的影響。盡管如此,你還是可以只使用持續(xù)集 成,而不必使用XP的任何其他部分——實(shí)際上,我們認(rèn)為:對于任何切實(shí)可行的軟件開發(fā)活動,持續(xù)集成都是很 基本的組成部分。 實(shí)現(xiàn)自動化日創(chuàng)建需要做以下幾部分的工作: 將
所有的源代碼保存在單一的地點(diǎn),讓所有人都能從這里獲取最新的源代碼(以及以前的版本)。
使創(chuàng)建過程完全自動化,讓任何人都可以只輸入一條命令就完成系統(tǒng)的創(chuàng)建。 使測試完全自動化,讓任何人都可以只輸入一條命令就運(yùn)行一套完整的系統(tǒng)測試。
確保所有人都可以得到最新、最好的可執(zhí)行文件。 持續(xù)集成的優(yōu)點(diǎn) 持續(xù)集成最基本的 優(yōu)點(diǎn)就是:它完全避免了開發(fā)者們的“除蟲會議”——以前開發(fā)者們經(jīng)常需要開這樣的 會,因?yàn)槟硞€(gè)人在工作的時(shí)候踩進(jìn)了別人的領(lǐng)域、影響了別人的代碼,而被影響的人還不知道發(fā)生了什么,于是 bug就出現(xiàn)了。這種bug是最難查的,因?yàn)閱栴}不是出在某一個(gè)人的領(lǐng)域里,而是出在兩個(gè)人的交流上面。隨著時(shí) 間的推移,問題會逐漸惡化。通常,在集成階段出現(xiàn)的bug早在幾周甚至幾個(gè)月之前就已經(jīng)存在了。結(jié)果,開發(fā) 者需要在集成階段耗費(fèi)大量的時(shí)間和精力來尋找這些bug的根源。 如果使用持續(xù)集成,這樣的bug絕大多數(shù)都可以在引入的同一天就被發(fā)現(xiàn)。而且,由于一天之中發(fā)生變動的 部分并不多,所以可以很快找到出錯(cuò)的位置。如果找不到bug究竟在哪里,你也可以不把這些討厭的代碼集成到 產(chǎn)品中去。所以,即使在最壞的情況下,你也只是不添加引起bug的特性而已。(當(dāng)然,可能你對新特性的要求 勝過了對bug的憎恨,不過至少你可以多一種選擇。) 到現(xiàn)在為止,持續(xù)集成還不能保證你抓到所有集成時(shí)出現(xiàn)的bug。持續(xù)集成的排錯(cuò)能力取決于測試技術(shù),眾 所周知,測試無法證明已經(jīng)找到了所有的錯(cuò)誤。關(guān)鍵是在于:持續(xù)集成可以及時(shí)抓到足夠多的bug,這就已經(jīng)值 回它的開銷了。 所以,持續(xù)集成可以減少集成階段“捉蟲”消耗的時(shí)間,從而最終提高生產(chǎn)力。盡管現(xiàn)在還不知道是否有人 對這種方法進(jìn)行過科學(xué)研究,但是作為一種實(shí)踐性的方法,很明顯它是相當(dāng)有效的。持續(xù)集成可以大幅減少耗費(fèi) 在“集成地獄”中的時(shí)間,實(shí)際上,它可以把地獄變成小菜一碟。 集成越頻繁,效果越好 如果你的集成不是經(jīng)常進(jìn)行的(少于每天一次),那么集成就是一件痛苦的事情,會耗費(fèi)你大量的時(shí)間與精 力。我們經(jīng)常聽見有人說:“在一個(gè)大型的項(xiàng)目中,不能應(yīng)用日創(chuàng)建”,實(shí)際上這是一種十分愚蠢的觀點(diǎn)。 不過,還是有很多項(xiàng)目實(shí)踐著持續(xù)集成。在一個(gè)五十人的團(tuán)隊(duì)、二十萬行代碼的項(xiàng)目中,我們每天要集成二 十多次。微軟在上千萬行代碼的項(xiàng)目中仍然堅(jiān)持日創(chuàng)建。 持續(xù)集成之所以可行,原因在于集成的工作量是與兩次集成間隔時(shí)間的平方成正比的。盡管我們還沒有具體 的衡量數(shù)據(jù),但是可以大概估計(jì)出來:每周集成一次所需的工作量絕對不是每天集成的5倍,而是大約25倍。所 以,如果集成讓你感到痛苦,也許就說明你應(yīng)該更頻繁地進(jìn)行集成。如果方法正確,更頻繁的集成應(yīng)該能減少你的痛苦,讓你節(jié)約大量時(shí)間。
持續(xù)集成的關(guān)鍵是自動化。絕大多數(shù)的集成都可以而且應(yīng)該自動完成。讀取源代碼、編譯、連接、測試,這
些都可以自動完成。最后,你應(yīng)該得到一條簡單的信息,告訴你這次創(chuàng)建是否成功:“yes”或“no”。 如果成
功,本次集成到此為止;如果失敗,你應(yīng)該可以很簡單地撤消最后一次的修改,回到前一次成功的創(chuàng)建。在整個(gè) 如果有了這樣一套自動化過程,你隨便想多頻繁進(jìn)行創(chuàng)建都可以。唯一的局限性就是創(chuàng)建過程本身也會消耗 一定的時(shí)間。(譯注:不過與捉蟲所需的時(shí)間比起來,這點(diǎn)時(shí)間是微不足道的。) 一次成功的創(chuàng)建是什么樣的? 對于下列“成功創(chuàng)建”的標(biāo)準(zhǔn),我們還是相當(dāng)自信的: 所有最新的源代碼都被配置管理系統(tǒng)驗(yàn)證合格 單一代碼源 辦法很簡單。任何人都應(yīng)該可以帶一臺干凈的機(jī)器過來,連上局域網(wǎng),然后用一條命令就得到所有的源文 件,馬上開始系統(tǒng)的創(chuàng)建。 最簡單的解決方案就是:用一套配置管理(源代碼控制)系統(tǒng)作為所有代碼的來源。配置管理系統(tǒng)通常都設(shè) 計(jì)有網(wǎng)絡(luò)功能,并且?guī)в凶岄_發(fā)者輕松獲取源代碼的工具。而且,它們還提供版本管理工具,這樣你可以很輕松 地找到文件以前的版本。成本就更不成問題了,CVS就是一套出色的開放源代碼的配置管理工具。 所有的源文件都應(yīng)該保存在配置管理系統(tǒng)中。我說的這個(gè)“所有”常常比人們想到的還要多,它還包括創(chuàng)建 腳本、屬性文件、數(shù)據(jù)庫調(diào)度DLL、安裝腳本、以及在一臺干凈的機(jī)器上開始創(chuàng)建所需的其他一切東西。經(jīng)常都 能看到這樣的情況:代碼得到了控制,但是其他一些重要的文件卻找不到了。 盡量確保所有的東西都保存在配置管理系統(tǒng)的同一棵代碼源樹中。有時(shí)候?yàn)榱说玫讲煌慕M件,人們會使用 配置管理系統(tǒng)中不同的項(xiàng)目。這帶來的麻煩就是:人們不得不記住哪個(gè)組件的哪個(gè)版本使用了其他組件的哪些版 本。在某些情況下,你必須將代碼源分開,但是這種情況出現(xiàn)的幾率比你想象的要小得多。你可以在從一棵代碼 源樹創(chuàng)建多個(gè)組件,上面那些問題可以通過創(chuàng)建腳本來解決,而不必改變存儲結(jié)構(gòu)。 自動化創(chuàng)建腳本
大規(guī)模的創(chuàng)建經(jīng)常會耗費(fèi)一些時(shí)間,如果只做了一點(diǎn)小小的改動,當(dāng)然你不會希望重新做所有這些步驟。所
以好的創(chuàng)建工具會自動分析需要改變的部分,常見的方法就是檢查源文件和目標(biāo)文件的修改日期,只有當(dāng)源文件
的修改日期遲于目標(biāo)文件時(shí),才會重新編譯。于是,文件之間的依賴就需要一點(diǎn)技巧了:如果一個(gè)目標(biāo)文件發(fā)生 取決于自己的需要,你可以選擇不同的創(chuàng)建類型:你創(chuàng)建的系統(tǒng)可以有測試代碼,也可以沒有,甚至還可以 選擇不同的測試集;一些組件可以單獨(dú)創(chuàng)建。創(chuàng)建腳本應(yīng)該讓你可以根據(jù)不同的情況選擇不同的創(chuàng)建目標(biāo)。 你輸入一行簡單的命令之后,幫你挑起這副重?fù)?dān)常常是腳本。你使用的可能是shell腳本,也可能是更復(fù)雜 的腳本語言(例如Perl或Python)。但是很快你就會發(fā)現(xiàn)一個(gè)專門設(shè)計(jì)的創(chuàng)建環(huán)境是很有用的,例如Unix下的make工具。 在我們的Java開發(fā)中,我們很快就發(fā)現(xiàn)需要一個(gè)更復(fù)雜的解決方案。Matt用了相當(dāng)多的時(shí)間開發(fā)了一個(gè)用于 企業(yè)級Java開發(fā)的創(chuàng)建工具,叫做Jinx。但是,最近我們已經(jīng)轉(zhuǎn)而使用開放源代碼的創(chuàng)建工具Ant (http://jakarta./ant/index.html)。Ant的設(shè)計(jì)與Jinx非常相似,也支持Java文件編譯和Jar封 裝。同時(shí),編寫Ant的擴(kuò)展也很容易,這讓我們可以在創(chuàng)建過程中完成更多的任務(wù)。 許多人都使用IDE,絕大多數(shù)的IDE中都包含了創(chuàng)建管理的功能。但是,這些文件都依賴于特定的IDE,而且 經(jīng)常比較脆弱,而且還需要在IDE中才能工作。IDE的用戶可以建立自己的項(xiàng)目文件,并且在自己的單獨(dú)開發(fā)中使 用它們。但是我們的主創(chuàng)建過程用Ant建立,并且在一臺使用Ant的服務(wù)器上運(yùn)行。 自測試的代碼 XP 將測試分為兩類:單元測試和容納測試(也叫功能測試)。單元測試是由開發(fā)者自己編寫的,通常只測試 一個(gè)類或一小組類。容納測試通常是由客戶或外部的測試組在開發(fā)者的幫助下編寫的,對整個(gè)系統(tǒng)進(jìn)行端到端的 測試。這兩種測試我們都會用到,并且盡量提高測試的自動化程度。 作為創(chuàng)建的一部分,我們需要運(yùn)行一組被稱為“BVT”(Build Verification Tests,創(chuàng)建確認(rèn)測試)的測 試。BVT中所有的測試都必須通過,然后我們才能宣布得到了一個(gè)成功的創(chuàng)建。所有XP風(fēng)格的單元測試都屬于 BVT。由于本文是關(guān)于創(chuàng)建過程的,所以我們所說的“測試”基本上都是指BVT。請記住,除了BVT之外,還有一 條測試線存在(譯注:指功能測試),所以不要把BVT和整體測試、QA等混為一談。實(shí)際上,我們的QA小組根本不會看到?jīng)]有通過BVT的代碼,因?yàn)樗麄冎? 對成功的創(chuàng)建進(jìn)行測試。 有一條基本的原則:在編寫代碼的同時(shí),開 發(fā)者也應(yīng)該編寫相應(yīng)的測試。完成任務(wù)之后,他們不但要?dú)w還 (check in)產(chǎn)品代碼,而且還要?dú)w還這些代碼的測試。這也跟XP的“測試第一”的編程風(fēng)格很相似:在編寫完 相應(yīng)的測試、并看到測試失敗之前,你不應(yīng)該編寫任何代碼。所以,如果想給系統(tǒng)添加新特性,你首先應(yīng)該編寫一個(gè)測試。只有當(dāng)新的特性已經(jīng)實(shí)現(xiàn)了以后,這個(gè)測 試才可能通過。然后,你的工作就是讓這個(gè)測試能夠通過。 我們用Java編寫這些測試,與開發(fā)使用同樣的語言,所以編寫測試與編寫代碼沒有太大的區(qū)別。我們使用JUnit(http://www./)來作為組織、編寫測試的框架。JUnit是一個(gè)簡單的框架,讓我們可以快速編 寫測試、將測試組織為套件、并以交互或批處理的模式來運(yùn)行測試套件。(JUnit是xUnit家族的Java版本 ——xUnit包括了幾乎所有語言的測試框架。) 在編寫軟件的過程中,在每一次的編譯之后,開發(fā)者通常都會運(yùn)行一部分單元測試。這實(shí)際上提高了開發(fā)者的工作效率,因?yàn)檫@些單元測試可以幫助你發(fā)現(xiàn)代碼中的 邏輯錯(cuò)誤。然后,你就沒必要去調(diào)試查錯(cuò),只需要注意 最后一次運(yùn)行測試之后修改的代碼就行了。這個(gè)修改的范圍應(yīng)該很小,所以尋找bug也就容易多了。 并非所有的人都嚴(yán)格遵循XP“測試第一”的風(fēng)格,但是在第一時(shí)間編寫測試的好處是顯而易見的。它們不但 讓每個(gè)人的工作效率更高,而且由這些測試構(gòu)成的BVT更能捕捉到系統(tǒng)中的錯(cuò)誤。因?yàn)锽VT每天要運(yùn)行好幾次,所 以BVT檢查出的任何問題都是比較容易改正的,原因很簡單:我們只做了相當(dāng)小范圍的修改,所以我們可以在這 個(gè)范圍內(nèi)尋找bug。在修改過的一小塊代碼中排錯(cuò)當(dāng)然比跟蹤整個(gè)系統(tǒng)來排錯(cuò)要有效多了。 當(dāng)然,你不能指望測試幫你找到所有的問題。就象人們常說的:測試不能證明系統(tǒng)中不存在錯(cuò)誤。但是,盡 善盡美不是我們唯一的要求。不夠完美的測試只要經(jīng)常運(yùn)行,也比永遠(yuǎn)寫不出來的“完美測試”要好得多。 另一個(gè)相關(guān)的問題就是:開發(fā)者們?yōu)樽约旱拇a編寫測試。我們經(jīng)常聽人說:開發(fā)者不應(yīng)該測試自己的代 碼,因?yàn)樗麄兒苋菀缀鲆曌约汗ぷ髦械腻e(cuò)誤。盡管這也是事實(shí),但是自測試過程需要快速將測試轉(zhuǎn)入代碼基礎(chǔ) 中。這種快速轉(zhuǎn)換的價(jià)值超過獨(dú)立測試者的價(jià)值。所以,我們還是用開發(fā)者自己編寫的測試來構(gòu)造BVT,但是仍 然有獨(dú)立編寫的容納測試。 自測試另一個(gè)很重要的部分就是它通過反饋——XP的一項(xiàng)核心價(jià)值——來提高測試的質(zhì)量。這里的反饋來自 于從BVT中逃脫的bug。自測試的規(guī)則是:除非你在BVT中加入了相應(yīng)的測試,否則就不能修正任何錯(cuò)誤。這樣, 每當(dāng)要修正某個(gè)錯(cuò)誤的時(shí)候,你都必須添加相應(yīng)的測試,以確保BVT不會再把錯(cuò)誤放過去。而且,這個(gè)測試應(yīng)該 引導(dǎo)你去考慮更多的測試、編寫更多的測試來加強(qiáng)BVT。 主創(chuàng)建 第一步是要選擇運(yùn)行主創(chuàng)建的機(jī)器。我們選擇了一臺叫做“投石車”的計(jì)算機(jī)(我們經(jīng)常玩“帝國時(shí)代” J),這是一臺裝有四個(gè)CPU的服務(wù)器,非常適合專門用來做創(chuàng)建。(由于完整的創(chuàng)建需要相當(dāng)長的時(shí)間,所以這 種馬力是必須的。) 創(chuàng)建進(jìn)程是在一個(gè)隨時(shí)保持運(yùn)行的Java類中進(jìn)行的。如果沒有創(chuàng)建任務(wù),創(chuàng)建進(jìn)程就一直循環(huán)等待,每過幾 分鐘去檢查一下代碼倉庫。如果在最后的創(chuàng)建之后沒有人歸還任何代碼,進(jìn)程就繼續(xù)等待。如果代碼倉庫中有了 新的代碼,就開始創(chuàng)建。 創(chuàng)建的第一階段是完全提取倉庫中的代碼。Starteam已經(jīng)為我們提供了相當(dāng)好的Java API,所以切入代碼倉 庫也很容易。守護(hù)進(jìn)程(daemon)會觀察五分鐘以前的倉庫,看最近五分鐘里面有沒有人歸還了代碼。如果有, 守護(hù)進(jìn)程就會考慮等五分鐘再提取代碼(以免在別人歸還代碼的過程中提?。?。 守護(hù)進(jìn)程將全部代碼提取到投石機(jī)的一個(gè)目錄中。提取完成之后,守護(hù)進(jìn)程就會在這個(gè)目錄里調(diào)用Ant腳 本。然后,Ant會接管整個(gè)創(chuàng)建過程,對所有源代碼做一次完整的創(chuàng)建。Ant腳本會負(fù)責(zé)整個(gè)編譯過程,并把得到 的class文件放進(jìn)六個(gè)jar包里,發(fā)布到EJB服務(wù)器上。 當(dāng) Ant完成了編譯和發(fā)布的工作之后,創(chuàng)建守護(hù)進(jìn)程就會在EJB服務(wù)器上開始運(yùn)行新的jar,同時(shí)開始運(yùn)行BVT 測試套件。如果所有的測試都能正常運(yùn)行通過,我們就得到了一個(gè)成功的創(chuàng)建。然后創(chuàng)建守護(hù)進(jìn)程就會回到 Starteam,將所有提取出的源代碼標(biāo)記上創(chuàng)建號。然后,守護(hù)進(jìn)程會觀察創(chuàng)建過程中是否還有人歸還了代碼。如 果有,就再開始一次創(chuàng)建;如果沒有,守護(hù)進(jìn)程就回到它的循環(huán)中,等待下一次的歸還。 創(chuàng)建結(jié)束之后,創(chuàng)建守護(hù)進(jìn)程會給所有向最新一次創(chuàng)建歸還了代碼的開發(fā)者發(fā)一個(gè)e-mail,匯報(bào)創(chuàng)建的情 況。如果把創(chuàng)建留在代碼歸還之后去做,而又不用e-mail向開發(fā)者通報(bào)創(chuàng)建的情況,我們通常認(rèn)為這是不好的組 織形式。 守護(hù)進(jìn)程將所有的步驟都寫在XML格式的日志文件里面。投石車上會運(yùn)行一個(gè)servlet,允許任何人通過它檢 查日志,以觀察創(chuàng)建的狀態(tài)。(見圖1) 屏幕上會顯示出創(chuàng)建是否正在運(yùn)行、開始運(yùn)行的時(shí)間。在左邊有所有創(chuàng)建的歷史記錄,成功的、失敗的都記 錄在案。點(diǎn)擊其中的某一條記錄,就會顯示出這次創(chuàng)建的詳細(xì)信息:編譯是否通過、測試的結(jié)果、發(fā)生了哪些變 化…… 我們發(fā)現(xiàn)很多開發(fā)者都經(jīng)??纯催@個(gè)頁面,因?yàn)樗屗麄兛吹巾?xiàng)目發(fā)展的方向,看到隨著人們不斷歸還代碼 而發(fā)生的變化。有時(shí)我們也會在這個(gè)頁面上放一些其他的項(xiàng)目新聞,但是需要把握好尺度。 要讓開發(fā)者能在自己的本地機(jī)器上模擬主創(chuàng)建過程,這是很重要的。這樣,如果集成錯(cuò)誤出現(xiàn)了,開發(fā)者可 以在自己的機(jī)器上研究、調(diào)試,而不必真的執(zhí)行主創(chuàng)建過程。而且,開發(fā)者也可以在歸還代碼之前先在本地執(zhí)行 創(chuàng)建,從而降低了主創(chuàng)建失敗的可能性。 這里有一個(gè)比較重要的問題:主創(chuàng)建應(yīng)該是干凈的創(chuàng)建(完全從源代碼開始)還是增量創(chuàng)建?增量創(chuàng)建會快 得多,但是也增大了引入錯(cuò)誤的風(fēng)險(xiǎn),因?yàn)橛行┎糠质菦]有編譯的。而且我們還有無法重新創(chuàng)建的風(fēng)險(xiǎn)。我們的 創(chuàng)建速度相當(dāng)快(20萬行代碼約15分鐘),所以我們樂于每次都做干凈的創(chuàng)建。但是,有些團(tuán)隊(duì)喜歡在大多數(shù)時(shí)候做增量創(chuàng)建,但是當(dāng)那些奇怪的問題突然出現(xiàn) 時(shí),也經(jīng)常性地做干凈的創(chuàng)建(至少每天一次)。 圖1:運(yùn)行在投石車上的servlet 代碼歸還(Check in) 在開始新的任務(wù)之前,開發(fā)者應(yīng)該首先與配置管理系統(tǒng)同步。也就是說,他們應(yīng)該首先更新本地機(jī)器上的源 代碼。在舊的代碼基礎(chǔ)上編寫代碼,這只會帶來麻煩和混亂。 然后,開發(fā)者要隨時(shí)保持文件的更新。開發(fā)者可以在一段任務(wù)完成之后將代碼集成到整個(gè)系統(tǒng)中,也可以在 任務(wù)的中途集成,但是在集成的時(shí)候必須保證所有的測試都能通過。 集成的第一步是要再次使開發(fā)者的本地文件與代碼倉庫同步。代碼倉庫中所有新近有改動的文件都要拷貝到 開發(fā)者的工作目錄中來,當(dāng)文件發(fā)生沖突時(shí),配置管理系統(tǒng)會向開發(fā)者提出警告。然后,開發(fā)者需要對同步后的 工作集進(jìn)行創(chuàng)建,對這些文件運(yùn)行BVT,并得到正確的結(jié)果。 現(xiàn) 在,開發(fā)者可以把新的文件提交到代碼倉庫中。提交完成之后,開發(fā)者就需要等待主創(chuàng)建。如果主創(chuàng)建成功,那么這次歸還也是成功的。如果主創(chuàng)建失敗了,開發(fā)者 可以在本地修改。如果修改很簡單,就可以直接提 交;如果修改比較復(fù)雜,開發(fā)者就需要放棄這次修改,重新同步自己的工作目錄,然后繼續(xù)在本地開發(fā)、調(diào)試,然后再次提交。 某些系統(tǒng)強(qiáng)制要求歸還進(jìn)程逐個(gè)進(jìn)行。在這種情況下,系統(tǒng)中會有一個(gè)創(chuàng)建令牌,同一時(shí)間只有一個(gè)開發(fā)者 能拿到令牌。開發(fā)者獲取創(chuàng)建令牌,再次同步文件,提交修改,然后釋放令牌。這就確保創(chuàng)建過程中,最多只能 有一個(gè)開發(fā)者在更新代碼倉庫。不過我們發(fā)現(xiàn),即使沒有創(chuàng)建令牌,我們也很少遇到麻煩,所以我們也不用這種方法。經(jīng)常會有多個(gè)人同時(shí)向同一個(gè)主創(chuàng)建提交代碼 的情況,但是這很少造成創(chuàng)建失敗,而且這樣的錯(cuò)誤也很容 易修復(fù)。 同時(shí),我們還讓開發(fā)者自己來決定歸還過程中的小心程度。這反映出開發(fā)者對集成錯(cuò)誤出現(xiàn)幾率的評估。如 果她覺得很有可能出現(xiàn)集成錯(cuò)誤,那么她就會在歸還之前先做一次本地創(chuàng)建;如果她覺得根本不可能出現(xiàn)集成錯(cuò)誤,那么她可以直接歸還。如果犯了錯(cuò)誤,在主創(chuàng)建 運(yùn)行時(shí)她立刻就會發(fā)現(xiàn),然后她就必須放棄自己的修改,找到出錯(cuò)的地方。如果錯(cuò)誤很容易發(fā)現(xiàn)、很容易修補(bǔ),那么這種錯(cuò)誤也是可以接受的。 總結(jié) 關(guān)鍵是要讓所有的事情都完全自動化,并且要經(jīng)常進(jìn)行集成,這樣才能盡快發(fā)現(xiàn)錯(cuò)誤。然后,人們可以隨時(shí) 修改需要修改的東西,因?yàn)樗麄冎溃喝绻麄冏龅男薷囊鹆思慑e(cuò)誤,那也是很容易發(fā)現(xiàn)和修補(bǔ)的。一旦獲得了這些利益,你會發(fā)現(xiàn)自己再也無法放下它們 |
|
|