Source Control 碰到的難題 1

我之前公司用的程式碼管理工具 (source control tool) 是 SourceGear 出的 Vault。為什麼選要付費的 Vault 而不是用免錢的 SVN(Subversion)? 說來也蠻好笑的,在我加入之前公司只有一個韌體工程師,用的是 CVS (Concurrent Versions System),因為只有一個人,所以也有一搭沒一搭的用著,不是太在意這個東西。而在我加入之後,寫程式的人變成了兩個,這時source control 變成了一個相當重要的工具,可是不知道是我太笨還是 CVS 太難用,我那時真的搞不太懂 source control 的原理是什麼,於是我就上網查了一下,看有沒有 tutorial 之類的文章。看了半天我找到 Eric Sink 的 blog,他是 Source Gear 的創辦人,他在 blog 裡面介紹了 source control 的基本原理, 而且分析了各家的好處。想當然爾,字理行間他當然是覺得他們家的東西是最好的 (否則他幹嘛要去寫一個新的 source control 軟體),當然其他的軟體有些也不錯,但是!#%^#$^@$%,總而言之都有缺點。最後我就好像被他唬了一樣,建議我們老闆買他的軟體來用,印象中前後買了9個的 license,應該有5千美金左右。(Eric Sink 的 blog 應該算是典型創業家使用的技巧,我想在當時(2005)應該還算是蠻先進的一個觀念,我甚至還有買他的書來看,Joel Spolsky 的書上也有提到他的文章。)對我來講,當時 Vault 的一個優點是全 Windows 介面,後端資料庫用的是 SQL Server,這對我這種不太搞 Linux 的人有很大的吸引力。而事實上 Vault 的確是蠻容易上手的,只要你有基本的 source control 觀念、熟悉 Windows 介面,應該都沒有使用上的問題。所以在這六年之中,我一直覺得買這軟體是很值得的一項投資。(我甚至在家裡也弄了一套Vault,因為單人版是免費的。)

不過這個想法等我換到了現在的公司卻有了轉變。我發現幾乎大部分的同事之前都是使用 SVN,只有極少數的人有用過其他的軟體,然後根本沒有人用過,甚至聽過 Source Gear 。我想其中的原因除了 SVN 是免費的之外,應該主要還是因為它的功能非常強大的關係。說來好笑,一開始我用 SVN 的時候,因為不熟悉它的功能,對於 TortoiseSVN 的介面也不是很適應,居然還抱怨它比不上以前的 Vault 好用,搞不懂為什麼這麼多人要用這爛東西。不過時間一久,各種功能慢慢上手之後,覺得 SVN 還真的很厲害,要什麼有什麼,diff, merge, branch, log, blame 各種基本功能都非常好用,才明白為什麼會有這麼多人要用它。

最近我開始在私底下學用 git,因為想要參考一下 MiniKeePass 這個App是怎麼寫的,想說來當個寫作練習。因為它的原始碼是在 github,所以逼得我非用 git 不可。根據基本的描述,git 和 SVN 最大的差別是分散式與集中式,不用和中央伺服器連線是 git 最大的優點。不過它到底好不好用,恐怕要等實際用了之後才知道。

話題有點扯遠了,回歸主題。我在我們公司看到一些程式碼版本維護上的問題,每一個都替工程師帶來不少麻煩,而且很妙的是,幾乎每個問題在我之前那個小公司也都曾經出現過。這似乎表示這類型的問題是一個通病,不過我覺得很奇怪的是,既然是通病,為什麼沒有人有一個系統性的解決方法?還是說辦法有,只是我們都不知道而已?不管怎麼樣,我想在這裡先講幾個我碰到的問題,也許以後會想出解法也不一定。

  • [Problem 1] Developing several release branches at the same time

我相信每個軟體工程師應該都有這樣的經驗,就是你必須要同時維護、開發一個以上的project,有可能是類似功能的不同產品,有可能是針對標準產品進行的客製化,也有可能是同一個產品但是屬於不同的世代 (generation)。而由於projects之間都有極高的重覆性,通常而言我們會在 source control system 裡面從原始的 project(main trunk) 用 branch 的方式去產生一個新的 project,然後同時從 main truck 和 branch 去做出兩種最後生產用的軟體。就像下面這個圖一樣,你本來只有 project 1 ,後來衍生出 project2,再後來衍生出 project3。

這會有什麼問題?剛才說這幾個 project 之間有大約80%的重覆性,因此當你在某一個project 碰到某個 bug 時,你幾乎無法避免的會在其他的 project 碰到一樣的問題,換句話說就是你必須要去每一個 project 裡面修正這個問題。也許你會說「不過就是把程式碼移過去而已,有這麼難嗎?」(是啊,當你這個動作要重覆做1,000次的時候,我看你會不會抱怨。)這還只是很煩而已,有些時候同樣的錯誤在不同的project裡面修正的方式不盡相同,這時就考驗程式員對於不同 project 的熟悉度有多高了(一般正常情況是不會很高)。另一方面,通常 bug tracking system 和 source control system 之間是對應的,也就是說,在 source control 裡面的一次修改,一定會對應到 bug tracking system 上的一個 bug。所以當你要套用一個 bug fix 到不同的 project 時,你該怎麼做?理論上是要新開另一個 bug 給你要套用的 project,然後才能進行修正。換句話說當你在 project 1 修正好一個 bug 時,你必須要做以下這些動作才能把全部的 projects 都給同時修正好:

  1. 新增一個同樣的 bug 給project 2
  2. 修正 project 2 中的 bug
  3. 把修正好的程式碼放回 source control
  4. 新增一個同樣的 bug 給 project 3
  5. 修正 project 3 中的 bug
  6. 把修正好的程式碼放回 source control

而當你有10個 bug 要修正時,以上這些動作就要重覆10次。於是有些天才就發明了一次性修正的作法:

我先在 project1 裡面把10個 bug 改好,然後分別開一個 bug 給 project2 和 project3,之後便一次把這10個修正加入到 project2 和 project3 裡面。這個方式是省了行政程序沒錯,但帶來的後果是相當嚴重的。當你發現系統無法正常運作的時候,你幾乎沒辦法區別到底是哪一次修正把系統弄爛了,這個問題在當負責 project2 或 project3 的工程師沒有同時負責 project1時尤其嚴重。通常你只能祈禱它不要發生,因為一旦出了問題,就不是簡單的複製貼上可以解決的了。

總的來講,由於開發衍生的 project 是不可避免的事,因此我們只能用最有效的方式儘量把傷害降到最低。我大概可以想到幾種作法:

  • 儘量把不同的 project 整合在同一套程式碼裡面,用 compiler option 或是 runtime configuration 來控制程式該有的行為

這個方式應該是最有效的,不過也是最難的,因為稍微一不小心程式碼就會被搞得不可收拾。要達到這種境界必須在 project 的初期就做好設計上的準備,可以為以後的變動留下擴充的彈性,問題這幾乎是不太可能的,因為你永遠都不會知道到底之後會發生什麼事,更何況要留下準備?另外有的時候不同的 project 的差別是來自於硬體上的,除非你系統的分層設計的很好,否則很難有辦法整併程式。總而言之,我個人覺得使用這種方式需要很深厚的經驗,或者是同一個 project 整個打掉重練才有辦法達到,一般初次設計的系統不太可能有辦法到達這個程度。

  • 儘量在系統開發的後期才衍生出別的 project,確保重大的 bug 都能在原 project 內解決

如果因為某個 bug 你必須要修正系統結構,那你最好保佑你手上只有一個 project,否則要同時維修兩個以上的 project,你絕對百分之兩百會帶來你不想要的後果。當然什麼時候要開新的 project 也許不是你能控制的,如果是系統的前期就要分支,那儘量考慮第一種作法。

  • 對已經存在的 project 分別進行小規模的重構(refactoring),慢慢的把重覆的函式整併到獨立的函式庫內

這個應該算是比較實際的做法,不過通常公司管理層不會希望你浪費時間去做這些沒有實際貢獻的事情,他們對於你修正 bug 的數量也許還比較重視。他們可能知道也可能不知道你修正的那些 bug 中其實有三分之二都是重覆的東西,不過那些都不重要,因為他們只在乎可以「量化」的東西,其他什麼 maintainability, scalability, refactoring, design pattern 都不在考慮範圍內。

廣告

About Weicheng Chu

創業中,微碧愛普科技 (www.weibyapp.com) 已婚, 有一對雙胞胎兒子, 現居住在美國加州、台灣台中
本篇發表於 軟體工程, Source Control 並標籤為 , , , , , , , , , 。將永久鏈結加入書籤。

4 Responses to Source Control 碰到的難題 1

  1. ray521 說道:

    Hi 我目前也遇到標準版&客製版的問題,在google看其他人的心得中。
    想請問一下,關於這方面,你目前仍然是用svn的branch方式處理嗎?

  2. Jenny Mckinney 說道:

    I can tell that you must have lots of free time on hand. Incredible analysis in a very structured fashion.

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s