Source Control 碰到的難題 2

  • [Problem 2] The issue branch stays open for too long

一般而言,要修正一個 bug 的標準程序如下:

  1. Creating a issue branch from the main trunk
  2. Download the issue branch to your local working copy
  3. Fix the bug in your local working copy
  4. Test your issue branch, go to step 3 again if not fixed
  5. Commit the fix to your issue branch
  6. Download the main trunk to your local working copy
  7. Merge the main trunk in your local working copy with your issue branch (Rebase)
  8. Test the main truck, make sure the bug is fixed
  9. Commit the change to the main trunk

前面5個步驟稱為resolve issue,通常是一個連續的動作,意思就是你會一股作氣完成,中間不會去做別的事情,除非有其他的特殊情況。而後面4個步驟稱為 integrate issue,就是把你的修正加入到正式的程式碼中,到此為止這個 bug 算是暫時告一段落,之後等下一個 RC(release candidate) 出來,測試人員確認問題解決後,這個 bug 就可以正式關閉(各家公司細部流程不大相同,不過大致上是這樣)。以上步驟可以用下面這張圖來簡單表示:

這個流程的好處是你可以在你自己的 branch 裡面做任何你想做的實驗,一切都和主要的程式沒有關係,只要最後你把程式碼放 進main truck 時注意不要有問題就好了。顯然,如果事情這麼單純的話,軟體工程師也未免太好當了,我也不用花時間寫這篇文章了。事情豬羊變色的關鍵就在於步驟 7 和 8,如果 merge 後的程式不能用怎麼辦?通常一般正常的情況下,這種事情應該是不會發生的,可是根據我個人的經驗,在工程師的世界裡,一件事情如果你不能百分之百保證不會發生,那它就一定會發生,就算它發生的機率極小,一百個人只有一個會遇到,相信我,你絕對剛好就會是那一個遇到的人。防止豬羊變色的辦法就是儘量縮小你 merge 的幅度,什麼意思?就是說當你要 Rebase 的時候,main trunk 最好和你一開始 branch 的時候沒有太大的差別,換句話就是不要讓太多人有機會把他們的修正放進 main trunk 裡面。因為如果只有一兩個人更改了 main trunk,那你碰到問題的機會相對比較小,而且就算碰到了問題,你要找出到底是誰的修正和你的相衝也會比較容易。反過來說,如果你遲遲解決不了問題,或是說解決了問題你卻不趕快把東西放回 main trunk 的話,那你要遇到相衝的機會就相對高上許多。就像下面這個圖裡面的第2個 branch一樣,等到你之後要rebase的時候,不出問題還好,如果出了問題,那通常就不是幾個小時可以解決的了。而且就算你自己測試沒有問題,我相信你也很難保證整個merge是完全可靠的,因為如果修改的幅度太大,改變的東西已經超出你的理解範圍,坦白講你真的沒有辦法光靠頭腦去判斷到底有沒有衝突。在沒辦法做大規模測試的情況下,這時你能做的大概只有求老天保佑,東西之後不要出什麼大問題了。

(一般我們用 source control 的習慣是先搶先贏,如果兩個修正沒有任何衝突,基本上誰先誰後都沒什麼差別,但是如果兩個修正之間有衝突,解決問題的責任會落在比較晚 commit 的那個人身上。所以通常除非是你手上的問題還沒辦法解決,否則一旦問題解決了,我們都是儘量趕快放進 main trunk 裡面,免得夜長夢多。當然有時修正範圍太大的時候,難免會要花很多時間,這時就只能夠常常進行 rebase,儘量看看最近別人放進的修正是不是有可能影響你正在進行的工作。)

如果你的 issue branch 一直沒辦法關閉的原因是由於問題沒解決,或是你自己偷懶不做事,那也就認了,可是我在我們公司卻遇到了第三種情況,而這也是為什麼我最近快被這個 rebase 給搞死。(我不知道這是我們公司獨有的政策還是怎樣,不過我大致可以猜得出來這和我們是 OEM 廠有很大的關係。)這第三種情況是這樣的,有人發現了一個 bug,而這一個 bug 也已經獲得解決,但是公司不想(或是不能)在這一次的版本升級中加入這個 bug 的修正,而必須要等到下一次版本升級或是更久之後才會加入(或是永遠不會?)。這個想法乍聽之下有點不可思議,問題被解決了卻不想要發布?我和比較資深的同事請教之後,才知道原來這個做法的理論根據有個好聽的名字叫做「風險管理(Rick Management)」。它的想法是這樣的,因為我們無法百分之百確認你新加入的這個修正是不是不會衍生出別的問題,所以如果這個問題不是非常嚴重,那在客人沒有發現之前,我們是不會主動提供這個修正的。這個想法某種程度上我可以理解,因為基本上我們做出來的東西是賣給客人用的,而如果客人自己在認證測試的過程中沒有看到問題,那就表示我們的產品符合規範,換句話說就是我們內部發現的問題對於客人來講不是問題,於是我們就沒有理由為了這不是問題的問題去修改系統,因為這很可能反而會造成其他的問題。(不知道誰講過這句話:哪個系統沒有bug?沒有被發現的 bug 就不算 bug。)

這個作法對於已經獲得認證,或是即將獲得認證的產品有相當的合理性,因為我們這個產業的認證有時長達一年,實在沒有必要為了幾個沒人在意的 bug 危害到產品的可靠性。但坦白講,我覺得我現在在做的這個產品,距離認證通過恐怕還有相當長的一段時間,在這麼早期就採用這麼保守的做法,實在有點極端。你現在不讓我 merge 進main trunk,如果萬一我現在修正的這個問題在幾個月後的測試中被發現,那請問我是要 rebase 到什麼時候去?還是我乾脆重來一次比較快?如果重來比較快的話,那我現在花這些時間去做這些事情是怎樣?For fun 嗎?而且有時同時好幾家客戶在認證,每一家的測試進度都不一樣,你要怎麼控制什麼修正要提供給什麼客人?最簡單有效的方法就是用不同的 branch,但如同前一篇所講的,這注定會是個災難,但除此之外我實在想不出其他更好的辦法了。嚴格來講,客戶認證的程序應該都是在產品開發的中後期才會開始,理論上不會有太多的問題,所以上面講的情況應該不太會出現,但為什麼我們公司的產品明明就不是很穩定,就有客戶要開始認證(甚至已經下單!),這我就真的搞不懂了。

廣告

About Weicheng Chu

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

發表迴響

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

WordPress.com Logo

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

Twitter picture

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

Facebook照片

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

Google+ photo

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

連結到 %s