歡迎您光臨本站 註冊首頁

讓開發自動化: 針對廣大開發人員的并行開發

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
雖然很多開發團隊都使用版本控制系統管理代碼變更,但當多個開發人員并行地使用不同的代碼庫進行編碼時,還是會出現問題的。在本期的 讓開發自動化 中,自動化專家 Paul Duvall 展示了如何運用開源的、免費的 Subversion 版本控制系統來有效地進行標記、分支和合併。

說到源代碼分支,可以將大多數的軟體開發團隊大致劃分為兩大陣營:有些是根本不分支;或存在大量的分支(甚至儲存庫),以致開發人員不知道從哪裡簽入變更 — 或者覺得合併變更很痛苦,於是就冒險將這項工作推遲到軟體快要發布時才做。

術語

主幹(trunk)(有時稱 head)用於幹線開發(mainline development)。分支(branch)是指一個代碼支線副本,用於進行與幹線開發不同的變更。標記(tag)(有時稱 標籤)是一個使用時間戳的代碼支線副本,用於標識代碼支線,以在開發周期中返回到標記的地方。

永遠只需要操作主幹是最理想的情況。這使合併兩個或多個代碼支線間的變更沒有那麼複雜。然而,在現實的軟體開發中,您正在開發的可能是未來版本,或者有時您可能需要為一個已經交付使用的版本準備一條後路。你需要有許可權訪問已發布版本的源代碼副本 — 但又不能擾亂正在開發的新代碼。

但當開發團隊試圖使用分開的代碼支線時,問題就會出現了。有些時候,開發團隊可能會選擇不創建分支,免得會延誤發布或導致開發人員瓶頸。而有些時候,開發人員合併的頻率太低,結果導致了合併衝突、瓶頸以及發布延誤。而增加分支則會使導航項目儲存庫很困難,從而導致開發人員無意中更改了不應該更改的代碼。

團隊進行并行開發時,一定要以最高的頻率將代碼合併回幹線(即主幹)。如果無法經常將代碼合併到主幹的話,可以運行測試,這樣就能夠確定是否會發生合併衝突,從而使實施 合併沒有那麼困難。要有效地進行并行開發,您可以使用 Subversion(SVN)中的標記和分支,Subversion 是一個開源的、免費的源代碼管理系統。通過標記,團隊可以安全地返回到源代碼的前一版本中。

我將通過介紹以下內容來示範如何在 SVN 中進行并行開發:

  • 如何從主幹創建一個 SVN 版本標記
  • 根據版本標記來創建一個 SVN 分支
  • 將變更合併回幹線(即主幹)的技巧
  • 如何在開發中的主幹運行持續集成(Continuous Integration,CI),以定期測試分支與主幹的合併
  • 演示如何將源於分支的變更應用到主幹
  • 舉例說明如何標記分支的源代碼

 

圖 1 顯示了幾個并行代碼支線的基本流程:


圖 1. 并行開發

在圖 1 中,有效的開發發生在 SVN 主幹的版本 1.0.0 和版本 1.1.0 之間。可以是一組開發人員在版本 1.0.1 分支上進行開發,而其他人員在幹線上開發。

如果想要多個開發人員負責不同的代碼支線的話,可以使用很多策略和技巧。在本文中,我將展示一個很常用的方法,我曾在使用 SVN 的項目上用過它。

為并行開發配置 Subversion

安裝和配置 SVN 伺服器並不在本文的討論範圍之內。如果您有許可權訪問一個有效的 SVN 伺服器,就可以執行以下的步驟了:

  1. 將 SVN 客戶機軟體下載到您的工作站。
  2. 在工作站中創建一個標準本地目錄。
  3. 將目錄添加到 SVN 儲存庫。
  4. 將目錄提交到 SVN 儲存庫。

從 Tigris.org Web 站點(參見 參考資料)為您的操作系統下載 SVN 客戶機軟體,並將其安裝到您的工作站。確保 SVN 可執行文件在您的工作站的系統目錄中。用 svn co URL 執行儲存庫的 SVN 簽出。

接下來,創建三個本地目錄:

  • 分支:用於維護幹線開發之外的軟體。
  • 標記:在發布軟體時用於標識變更集,以備使用。
  • 主幹:用於幹線開發。

清單 1 展示了在 Windows®、Macintosh 以及基於 *nix 的系統上如何從命令行創建這些目錄:


清單 1. 創建本地目錄,將其添加到 Subversion
$ mkdir branches  $ mkdir tags  $ mkdir trunk  

在操作系統中創建了目錄之後,您可以分別使用 SVN add 和 commit 命令將它們添加並提交到 SVN。在我創建清單 1 的目錄的目錄中,我輸入了如清單 2 所示的命令(在適當的時候替代用戶憑證):


清單 2. 將本地目錄添加並提交到遠程 SVN 儲存庫
$ svn add *.*  $ svn commit -m "Setting up standard SVN branches, tags and trunk directories" \    --username tjefferson --password Mont!cello   

執行了清單 1 和清單 2 中的操作之後,SVN 儲存庫應該類似於圖 2:


圖 2. 在儲存庫中創建的標準 SVN 目錄

基本的 SVN 儲存庫就緒以後,就可以創建版本標記了。





根據主幹創建一個版本標記

標記的用途是在某個特定點及時標識代碼支線副本,以便以後返回到該版本。圖 3 展示了一個名為 brewery-1.0.0 的標記,它是針對 1.0.0 版本創建的。(標記能夠隨時在任何點創建,但通常都是在發布軟體時創建)。


圖 3. 為 SVN 主幹創建一個惟一的標記

假設主幹包含已發布的軟體的源代碼的話,第一個任務就是要依據主幹創建一個 SVN 標記。清單 3 就是一個關於如何創建這個標記的例子:


清單 3. 根據主幹創建一個版本標記
<path id="svn.classpath">    <fileset dir="${lib.dir}">      <include name="**/*.jar" />    </fileset>  </path>	  <taskdef name="svn" classpathref="svn.classpath"     classname="org.tigris.subversion.svnant.SvnTask"/>    <target name="create-tag-from-trunk">    <svn username="jhancock" password="S!gnhere">      <copy srcUrl="https://brewery-ci.googlecode.com/svn/trunk"        destUrl="https://brewery-ci.googlecode.com/svn/tags/brewery-1.0.0"  	  message="Tag created by jhancock on ${TODAY}" />    </svn>  </target>  

安全驗證失敗

第一次運行使用 Hypertext Transfer Protocol 而不是 Secure Socket Layer 的 SVN 伺服器時,一定要接受安全認證。如果您是第一次這樣從 Ant 腳本連接到安全 SVN 伺服器,連接會失敗,並且不提供診斷信息。因此,第一次時,必須從命令行運行 SVN 命令連接到伺服器。以後,您就可以從您的工作站運行任何 SVN Ant 腳本,以連接到該伺服器。

清單 3 使用了由 Subclipse 開源項目提供的 SVN Ant 任務(下載地址請參見 參考資料)。運行該 Ant 腳本時,一定要將隨 SVN Ant 任務一起提供的 JARs —svnant.jar、svnClientAdapter.jar 和 svnjavahl.jar— 包含在您的類路徑中。清單 3 的前半部分定義了這個類路徑。中間部分使用 taskdef 定義了 SVN Ant 任務。最後,我向主幹和標記目錄執行了 SVN copy 命令,從而為這個版本提供一個惟一的名稱:brewery-1.0.0.

運行清單 3 中的腳本並創建了一個新標記之後,您的 SVN 儲存庫應該如圖 4 所示。儲存庫的根級下面是標記目錄(在 清單 2 中創建)。而標記目錄的下面是在清單 3 中創建的新標記(目錄):brewery-1.0.0。它含有主幹的副本。


圖 4. 根據主幹創建標記

雖然標記的內容在 Subversion 中是可以更改的,但千萬 不要這樣做。





根據版本標記創建一個分支

在技術上,根據版本標記創建分支與根據主幹創建標記是相似的。兩者都要使用到 SVN 的 copy 命令。通常都會依照標記而創建分支,因為標記的是已發布 的代碼的代碼副本 — 而不是正在開發的代碼(可能已經更改)。圖 5 展示了如何根據 1.0.0 版本標記創建 1.0.1 分支:

版本命名

人們一直都想找到一個簡單的版本命名的模式。但是,只要一個版本和下一個版本或不同項目之間所使用的版本命名模式稍有不同的話,麻煩就大了。版本模式可能有很多種。一定要選擇一個既簡單又能夠靈活處理將來的版本的模式。我所使用的模式是 major-version.minor-version.patch,它很簡單。Version 1.1.2 就是以這個命名模式命名的。也有些團隊選擇向版本追加一個構建號。


圖 5. 根據 1.0.0 版本標記創建分支 1.0.1

清單 4 通過 SVN Ant 任務調用了 SVN copy 命令,以將 brewery-1.0.0 標記中的所有文件拷貝到分支位置:


清單 4. 從版本標記創建分支的 Ant 腳本
<target name="create-branch-from-tag">    <svn username="sadams" password="b0stonM@ss">      <copy srcUrl="https://brewery-ci.googlecode.com/svn/tags/brewery-1.0.0"        destUrl="https://brewery-ci.googlecode.com/svn/branches/brewery-1.0.1"  	  message="Branch created by sadams on ${TODAY}" />    </svn>  </target>  

運行清單 4 中的腳本之後,SVN 儲存庫應該如圖 6 所示:


圖 6. 從版本標記創建分支

記住主幹

有些團隊處理分支開發時很極端,他們所有的開發工作都從分支開始。要記住,根據主幹進行開發會更輕鬆、更易於管理。分支就是為了并行地進行分開的開發。盡量不要濫用分支,動不動就創建分支。

在創建分支和使用 SVN Ant 任務時,一定要記得使用標記,這樣您才能夠提供一個可重複的過程,該過程方便源代碼的維護,使您可以輕鬆返回到上一版本的源代碼。

根據分支運行 CI

通常 CI 過程都是根據儲存庫的幹線(即主幹)而運行的。但如果想集成開發人員在分支上的變更並檢查支線與幹線的合併,這個原理也適用於分支。

圖 7 展示了 SVN 的位置。在這個 Hudson 配置頁面上,您還能夠定義要調用的 Ant 目標。


圖 7. Hudson CI 伺服器根據主幹構建分支並測試合併

運行 Hudson 等 CI 伺服器來測試合併可以提供一個預警系統,警告可能會在開發周期中發生潛在的合併衝突。





將分支的變更合併到主幹

創建分支的主要原因之一就是防止中斷幹線開發。但是,一定要將分支上的更改合併到主幹。圖 8 展示了將版本 1.0.1 合併到幹線,這個幹線是軟體正在開發的版本 1.1.0:


圖 8. SVN 時間線

在清單 5 中,我使用了 Subversion 的 merge 命令。我先輸入 svn merge,接著是合併到的目標 URL,然後是合併源的 URL,最後是本地目錄位置:


清單 5. 使用 SVN 的 merge 命令將分支開發合併到主幹
$ svn merge https://brewery-ci.googlecode.com/svn/trunk \   https://brewery-ci.googlecode.com/svn/branches/brewery-1.0.1 \   /dev/brewery --username pduvall --password password!  

SVN Ant 任務沒有提供合併命令,因此需要從命令行運行 merge 命令。或者使用 Ant 的 exec 任務來運行它。

運行清單 5 中的命令會得到類似於圖 9 的結果:


圖 9. 將分支合併到主幹的結果

如果合併成功,則需要提交 Subversion 中的變更,如清單 6 所示。在命令行上輸入 svn commit,然後輸入消息描述和主幹的 SVN URL :


清單 6. 將合併后的變更提交到主幹
<target name="commit-branch-to-trunk">    <svn username="gwbush" password="IL0veTHEG00g!e">      <commit dir="${basedir}"        message="Committing changes from brewery-1.0.1">      </commit>    </svn>  </target>  

要經常將變更從分支合併到主幹以避免合併衝突,從而使代碼支線始終保持一致。





根據分支創建標記

為了根據特定的分支準備一個版本,我創建了一個 SVN 標記。這裡使用方法與前面一些清單提供的方法類似。圖 10 展示了根據 brewery-1.0.1 分支創建名為 brewery-1.0.1 的標記的方法:


圖 10. 根據分支創建標記

在特定的分支上完成開發后,就需要在 Subversion 中標記它。清單 7 展示了一個根據分支創建標記的例子:


清單 7. 根據分支創建 SVN 標記
<svn username="jbartlett" password="newHampsh!re">    <copy srcUrl="https://brewery-ci.googlecode.com/svn/branches/brewery-1.0.1"      destUrl="https://brewery-ci.googlecode.com/svn/tags/brewery-1.0.1"      message="Branch created by jbartlett on ${TODAY}" />  </svn>  

根據具體分支創建標記之後,您就可以在以後的開發周期中返回到該版本了。





結束語

并行開發並不是什麼難事,但如果不按照項目需求進行規劃並不斷改進,它的管理將非常困難。如果必須記住一點的話,那就是一切最終都要回到主幹。您可以將分支看作是一個容納可能中斷幹線開發的源代碼的臨時居所。最後要考慮的是要儘早地、經常地測試合併。當然可能有比 Subversion 更好的支持并行開發的版本控制系統,但根據我的經驗,開發團隊在開發時堅持原則比使用工具解決問題重要得多。(責任編輯:A6)



[火星人 ] 讓開發自動化: 針對廣大開發人員的并行開發已經有636次圍觀

http://coctec.com/docs/linux/show-post-69080.html