吉米與 Eric 相約在咖啡廳會面後,閒聊一會後,吉米直接將自己遇到的情況詳細說明給 Eric 知道。並詢問是否有其他建議的作法。
Eric
: 吉米,你目前的原始碼,是使用什麼方式來進行管控?
吉米
: 大多都是在交付軟體時,才會將程式碼所在的資料夾壓縮成 zip 檔,用這種方式來管理程式碼的版本。
Eric
: 嗯,聽起來你是使用本地版本管控 的概念,來管理你的程式碼。不過這種備份方式,萬一需要比對程式碼差異時,需要額外花費一番功夫。
吉米
: 確實,之前有幾次要確認某個功能,是從那一個版本之後才新增的,花了不少時間去進行程式碼的比對。
Eric
: 你交付軟體的間隔時間大約多久?
吉米
: 一般來說,大約一個月到兩個月左右,就會交付軟體給客戶。
Eric
: 除了在交付程式時的備份外,其他時間也會進行備份嗎?針對這些程式碼壓縮檔,有異地備份嗎?
吉米
: 都是在完成某一項功能後,如果有想到備份,才會備份,但大部份都會忘記。至於備份下來的壓縮檔,都會同步到網路硬碟。
Eric
: 嗯,大致了解你的情況。吉米,你的程式碼版本管控的方式,風險相當高。例如開發環境突然掛掉、軟體開發到一半,突然發現方向錯誤……,雖然都可以解決,但都需要花費額外的時間去處理。
吉米
: 嗯嗯,換個角度來說,這就是隱性(時間)成本的耗損吧。
Eric
: 沒錯!看起來你現在需要的是版本管控系統來協助你管理原始碼,如果沒有使用其他的版控軟體,建議你可以去用許多開發人員使用的版控軟體 Git。
在版本控制系統中,最重要的,莫過於「倉庫(Repository)」[^註1],在 Repository 中,會記錄所有的版本資訊、分支(Branch)、合併(Merge) 等等資料。而版控所有的指令,都是建立於系統對 Repository 的操作行為。
此外,版本控制系統,也一定存在同步、追溯與檔案備份,這三種特性。
目前主流的版本控制系統的架構,大致上,都可以歸屬於集中式與分散式這兩種類型。在下面的圖中,Subversion 就是集中式版本控制系統,Git 則是分散式版本控制系統。
(圖片出處: Scriptcrunch)
集中式的版本控制系統,就是基於……同個團隊之間合作的方式,是共用同一個 Repository。系統必須確保每位使用者都需與 Respository 保持一致。為要維持使用者之間保持同步的狀態,分為 鎖定模式 與 合併模式 兩種作法。
鎖定模式
當使用者想要修改某檔案、簽出該檔案後,該檔案便會進入鎖定狀態,其他使用成員便無法加以修改,直到簽出者將該檔簽回為止。
對於維持同步來說,這當然是一個十分保險的作法,因為永遠不會有兩個或以上的使用者同時修改同一個檔案。
只是,這種方法造成了使用者對於檔案修改的互斥效應,使得使用效率受到影響。
合併模式
允許多位使用者同時針對同一檔案進行修改,當他們分別將檔案提交回集中的檔案庫時,若發生衝突的情況,便會自動進行合併,而若自動合併失敗,再要求人工進行衝突的調解。
集中式版本控制不足處
無法離線工作
因為所有使用者共用同一個 Respository ,因此 Respository 幾乎存放在網路可連結的主機。使用者想要對 Respository 進行任何動作,都必須在能夠連網的環境下進行。
動一鬆而牽全身
如果某一個使用者,在檔案修改的過程中,就提交到 Respository ,那麼,便有可能影響到 Respository 內的檔案,處於不穩定或異常的狀態。
若強制使用者必需修成完成後,才能提交檔案至 Respository。但是,在修改的過程中,使用者無法得到版本控制系統的支援,有效控制各階段的修改內容。
分散式的版本控制系統允許 Respository 存在一份或多份。每個使用者,都可以在自己電腦中,建立 Respository。
對於分散式版本控制系統而言,讓每個使用者都可以修改各自的 Respository,享受版本控制系統的支援,而不受其他因素的限制。
同時,運用 Push、Pull 的動作,使用者之間可分享自己的變更內容,達到同步的結果。因此,為了更有效的同步版本內容,分散式版本控制系統就更重視 Branch、Merge 的支援與功能。
適時的 提交(Commit) 變動
每次的 Commit ,盡可能的確實變動內容的單純性與獨主性。例如,這次 Commit 的 Fix Bug 的變動,那在變動的內容,應盡可能避免與 Fix Bug 無關的內容。
每次的 Commit,都應確保變更後內容,是可以順利 Build 的。
良好的 Commit 訊息
每次的 Commit ,確認描述此次變動的原因與修改內容。利用有效的訊息,提高軟體的維護性。
[^註1]: Repository 具有倉庫、貯藏室、存放處的意思,但在版本控制中,也有人稱為版本庫或檔案庫。