【閱讀筆記】軟體構築美學(02)棕地專案的版本控制

為應用程式導入版本控制。了解簽入程序。發揮版本控制的功用。

書名:軟體構築美學

作者:Kyle Baley,Donald Belcham

譯者:蔡煥麟,張簡才祿

發行公司:悅知文化,精誠資訊股份有限公司

解決專案開發環境的問題,從版本控管(version control)開始。

問題描述

參考錯誤

第一次從版本控管系統的程式碼,編譯時通常都會出現參考錯誤

簽出時檔案即被鎖定

檔案已被其他成員取出,無法編輯

維護已經上線的程式碼

同一個 Bug 卻要修正兩份不同版本的程式碼。

 

版本控管系統裡面有什麼?

必備功能

保留修訂紀錄:保存檔案的不同版本。

連結性:讓每個成員都能輕鬆取得程式碼。

不可分割的交易:檔案的異動要麼全部成功,否則就全部失敗。

減少阻礙

好的版本控管系統,在你簽入時,會讓你能夠回答以下問題

1. 誰做了這次的修改?

2. 改了哪些檔案?

3. 為什麼要改?

比較檔案版本

差異比對可能是找出程式碼為何被改壞的唯一辦法。

容易使用

不論是方便結合IDE的版本控管系統,或是擁有彈性的命令列工具,只要符合團隊就可以了。

檔案管理

主要的兩種模型:檔案鎖定 版本合併

檔案鎖定模型(鎖定-編輯-送交)

優點:操作起來直覺,簽入程式碼的動作簡單,而且發生衝突的機會也很低。

缺點:開發人會經常搶檔案的擁有權,阻礙程式開發。

檔案被鎖定,無法繼續前進時,你有兩條路可選

1. 停止這項工作,等到檔案解除鎖定再來處理。

2. 想辦法把程式碼寫到別的地方。

版本合併模型(編輯-合併-送交)

你只要開始編輯檔案的內容,檔案就會自動被簽出。

如果你要簽入的檔案已經先被別人修改且簽入了新版本,你所做的修改就必須和目前的版本進行合併。

採用單一責任原則以及養成經常簽入的習慣,你會發現合併衝突的機率非常低,就算碰到了也很容易解決。

誰是對的? 看團隊而定,但建議使用版本合併模型。

分支

分支指的是讓程式碼分成兩條或兩條以上的路徑

使用情境

正式上線的版本出現 Bug,但與目前手邊修正的版本差異太多,可以在上線版本拉出一條分支修正,朝自己的方向前進。

實驗性質的程式碼(spike),為了評估特定解決方案所撰寫的程式碼,例如UI測試,或是測試新框架。

寫這類程式要有時間限制,避免方法行不通,卻花費了太多時間。

這些實驗性質的程式碼應該是可以用完即丟

記住,我們是要從這些實驗中學習,而不是要寫成正式的程式碼。

分支合併

分支並合併為主線:修正Bug完畢,或實驗解決方案成功,並合併回主線。

分支不再合併回主線:新版本的 .net framwork,專案必須更新為新版本,舊的版本維護一段時間就退下來(原主線),新的版本(新版本分支變為主線)。

頻繁的分支

一般會頻繁建立分支,通常是為了應付多變的需求。

為每項功能建立一個分支,每個分支都只有一個開發人員,達成隔離效果,缺點是將眾多分支合併為主線比較麻煩。

為每一個Bug建立分支,而不是將Bug全部集中到同一條分支線,一旦Bug修正完畢,就合併回主要開發或維護分支。

不要害怕分支,把它當作一個能夠隔離變動的工作來使用就好了。

 

導入版本控制

在開始將專案加入Repository之前,還有一些問題需要考慮

1. 你的專案是否有用到任何外部元件?

2. 專案的目錄結構是否穩定了?

3. 專案中是否有不需要納入版本控管的檔案或資料夾?

處理外來元件的相依性

1. 從版控系統取出最新版本。

2. 開始VS專案。

3. 編譯並執行

新建成員應該只要執行這幾個點簡單步驟就開始撰寫程式,若手續太複雜,就會形成阻礙,並且降低生產力。

通常最後一步會失敗,參考元件失效

1. 開發人員的機器上缺少必要的元件或函式庫。

2. 必要的元件或函式庫安裝在不正確的地方。

3. 安裝了不正確的版本。

解決之道是不要依賴開發人員自行安裝這些元件或函式庫,而是將它們直接放到應用程式的目錄結構中

放在一個集中的地方,讓開發人員都能輕易取得。

只要你的版控系統有保存你應用程式需要的版本,就能避免元件新舊版本不相容的問題。

目錄結構

資料夾名稱 說明
Build 包含自動建置的相關檔案。
Docs 用來存放任何與程式碼直接相關的文件。其他文件應該以內容管理系統的形式儲存(不放入版控內)。
Lib 包含應用程式需要用到的外來元件。
Src

app - 包含應用程式的原始檔。

test - 包含測試專案的原始檔。

Tools 用來儲存任何工具或公用程式。這些工具並非應用程式運行的要件,但建置程序可能需要他們。例如:單元測試框架、自動建置工具、用來分析程式碼涵蓋範圍或其他度量的工具。

關於 tools 資料夾的注意事項

如果會更著應用程式一起部署,就是屬於 lib,否則就是 tools 。

適合放在 tools 資料夾的檔案 適合放在 lib 資料夾的檔案

自動建置工具(例如:NAnt)

單元測試框架(例如:NUnit、MbUnit、XUnit)

原型(mocking)框架(例如:Rhino Mocks、TypeMock、Moq、Autofac)

程式碼涵蓋範圍 / 度量分析工具(例如:NCover、NDepend)

UI元件(例如:DevExpress、Infragistics、Telerik)

控制反轉容器(例如:Castle Windsor、StructureMap、Spring.NET)

記錄(logging)框架(例如:log4net)

物件關聯對應元件(例如:NHibernate、LLBLGen Pro)

自行開發的共用函式庫

哪些檔案不需要加入Repository

在 Visual Studio 編譯專案時,binobj 都不應該加入版控。

因為它們都自動編譯應用程式時自行產生的

因為每次編譯時,裡面的檔案都會被更動,會頻繁的簽入簽出

其他可以考慮排除的檔案包括

與程式開發有關的使用者設定檔(*.suo、*.csproj.user、*.vbproj.user)

Visual Studio 附加元件所衍生的檔案(例如:CodeRush與ReSharper產生的檔案)

最後可能有一項例外,你想要讓所有專案成員共享某些生產力工具的設定檔,你可以把這些檔案加入版控

第一次簽入與簽出

不要草率簽入程式碼,以為可以將來出問題時再修補就好。

應該要仔細看簽入時的對話視窗,至少第一次簽入時要特別注意。

 

簽入程序

Step1. 簽出你要修改的檔案。
Step2. 修改檔案內容。
Step3. 確定程式可以編譯和執行。
Step4. 取出應用程式的最新版本,並與你修改的部分合併。
Step5. 再次確定程式能否編譯和執行。
Step6. 將這次修改的檔案簽入Repository。

步驟4跟5,為了解決當你和其他人同時都在修改程式時可能產生的問題。

確保版控中的程式碼都處於穩定的狀態。

造成衝突的人,要自己負責解決。

 

版本控制的運用技巧

兩個技巧:經常簽入   使用標籤/標記(labeling,tagging)策略

經常簽入

每當程式碼已經有一點進展,完成一小部分的時候就盡快簽入。這樣就能減少需要處理合併的情形

使用標籤/標記(labeling,tagging)策略

每次部署應用程式到新環境時就要加個標籤。萬一出現嚴重的Bug,就可以馬上回到上一個可正常運行的版本

使用標籤的時機

1. 每次簽入時(這種作法有點矯枉過正了)。

2. 每天晚上(要搭配每晚自動建置發行才有用)。

3. 每當完成一項功能時。

4. 當你要大幅度重構程式碼時。

 

總結

要能有效率地比對檔案差異

了解各種操作版控的方式。

了解你的版控如何處理簽出檔案,並考慮採用版本合併式的版控,不要用檔案鎖定模式。

應用程式開發與運行所需之相關檔案都要加入版本控制

重新組織你的專案目錄結構,把非程式碼的檔案也納入考慮。

每次簽入程式碼的時候,依本章建議的簽入步驟進行。

將程式撰寫的工作分成較小的單元,以便經常簽入

為團隊制定一個適當的標籤策略