剛剛看到這篇《Upcoming Subversion 1.5 Feature: Changelists》,介紹了 Subversion 1.5 新增加的功能:changelist。簡單講,就是可以替 working copy 裡尚未 commit 的 changes,標上 tag (label),以區分出不同的 groups。

文章的前半段講的我心有戚戚焉,這正是開發生活的寫照啊。為了能夠同時解多個不同的 issues (bugs),而不會把事情混在一起搞得一團亂,開發者通常可以有兩種作法:

  • 使用多個不同的 working copies,每個 working copy 負責一個 issue,也許都對應到同一個 branch,也許對應到不同的 branch。
  • 使用一個 working copy,但在要解不同的 issue 時,利用 svn switch 切換到不同的 branch。

我通常的作法,是兩者混和,準備個兩、三個 working copies,輪流使用。因為專案太大,光是 checkout 就要好久,再加上執行時會需要一些 intermediate files,因為不會放在 repository 裡,重新產生耗時更久,所以必須得事先備好多個 working copies 使用[1]。可惜因為專案架構還不夠好的關係,runtime 目錄不能共用[2],所以無法進 repository 的 runtime 目錄下的 intermediate files 的同步問題,就有些麻煩。

可惜的是,這樣的 changelist 還不完全,要扣兩分。

要扣的第一分是,只能以路徑為單位標註 tag (label),所以在同一個檔案裡,分屬不同 issue 的變動,就不能靠 changelist 區分,必須要自己另外處理。這真的是很大的遺憾,因為依據我的經驗,這種需要臨時以 changelist 區分的不同 issue 的改變,在同一個檔案的機會,非常的大。因為,如果是比較大的 issue,通常就會直接在另外一個 working copy 解,或是另外一個 branch 然後用 svn switch 切過去解,以便保持環境的乾淨[3]。反倒是很小的改變,如修正註解裡的錯字、或臨時看到的小錯誤等,反倒都是因為,為了解前一個 issue 而修改程式,「順便」發現的。所以這種很小的改變,非常容易發生在同一個檔案裡。

要扣的第二分,文章裡沒有提到,不過我估計多半如此。那就是,不同的 changelist 沒辦法直接 commit 到不同的 branch。舉例來說,我正在某個 branch 解某個 bug,順便看到了一個註解裡的錯字,這個修正,理應不屬於這個 branch,所以應該 commit 到如 trunk 去。若不同的 changelist 沒有辦法直接 commit 到不同的 branch,那我就必須在要 commit 之前,先把 working copy 給 switch 到 trunk,然後再 commit 這個小修正,最後再 switch 回來。如果 Subversion 1.5 新的 merge auditing 機制夠強大的話,還可以順便把剛剛 commit 進 trunk 的改變,一併 merge 回現在的 branch[4]。事實上,如果 changelist 有支援直接 commit 到不同的 branch,內部的作法也差不多是如此,整個程序自動化,除非有 conflict 時才跳出來讓使用者手動處理。

Subversion 1.5 一些新的功能,實在是讓人非常的心動啊。


  1. 還好 working copy 的根目錄可以自由 rename,不會影響到 subversion 運作,所以輪流使用的這些 working copies,可以依據使用目的,將根目錄更名成符合使用目的的名字。為甚麼 OS 提供的 filesystem,不能對檔案、目錄,有方便瀏覽,容易編輯的 meta info 呢?
  2. 如使用 soft link 指到同一個目錄,或是將 PREFIX 設到同一個目錄。
  3. 如前一個 issue 解到一半,程式根本沒辦法 build,此時直接在同一個 working copy 跟前一個 issue 的改變混在一起解,就沒辦法測試了。
  4. 依靠 merge auditing,當這個 branch 要 merge 回 trunk 時,這個從 trunk merge 到 branch 的小改變,就不會重複 merge 回 trunk。