2009年5月28日

與嘉濠討論 Mercurial 筆記

嘉濠比我年輕一屆,從高中同在在工研社開始,我們就常討論程式語言、軟體開發生產力與軟體工程等問題。這禮拜我們討論了一下使用與推廣 revision control、wiki與bug tracking system 的心得:

1. Nested repositories (mercurial forests 、 git submodules、svn externals)
fcamel: 『我最近要把公司小組內用的 VCS 換用 Mercurial, 有幾個問題和你請教一下
我們目前程式不多, 我打算用一個 repository 含蓋全部,
但有可能會和別人合作, 到時會抽出其中一個 sub-project 和別人共用,
SVN 只要讓對方 checkout 子目錄就好,
但查了一下 mercurial 似乎沒內建類似功能,
只有看到這篇提到有 extension 有提供, 不知道效果如何
http://www.selenic.com/mercurial/wiki/NestedRepositories
不知道你有相關的經驗嗎? 你的建議是?』

Scottt:『 從單一 repository 中拆出子 project 在mercurial與git中都不方便。
建議:專案還小時,讓第二個 project 也checkout 第一個的全部 source code 。
中長期,尤其考慮到API修改、release 時程不同對等問題還是把 library 獨立成為自己的 repository較佳。
當有一個 library 有的三個使用者,或是 API穩定時就可以做了。

我之前一個專案有多個 repository 時,寫一小段 Makefile來協助 clone、tag、release等動作,相當順利。』

2. Work flow
fcamel:『我目前想的 work flow 如下 (兼顧自己暫時階段性工作和乾淨的官方 repository):
hg clone http://... main # http://... 表示組內 canonical repository 位置
hg clone main my_dev
cd my_dev
# update, commit, update, commit, ...
hg diff -r BASE_REVISION > update.diff
# code review
cd ../main
hg patch ../my_dev/update.diff # write a clean and formal log
hg push
cd ..
rm -rf my_dev # drop unused clone and its messy logs.
另外 code review 時, 則是請對方 hg pull my_dev 取得更新,
我也會把 update.diff 上傳到 ReviewBoard, 這雙方方便寫評論,
之前我和同事試用過幾次 ReviewBoard,
雖然功能很陽春, 但單就 review 這件事來說滿好用的』
Scott:『『一般』
developer對版本管理沒有多大興趣,用一個 local repository即可。
我需要改寫歷史的時候用 mercurial queues:
http://hgbook.red-bean.com/read/managing-change-with-mercurial-queues.html
我前一個開發超過兩年、
四個國家約50個developer參與的專案中,會用mercurial queue的developer不到5個.
當時多數修改只有事後 code review,少數關鍵模組、或在release關頭有事前code review。』

3. Source Code Layout
fcamel:『我們主要用 Java, 雜事用 Python, 我目前規劃是
# 假設根目錄是 hg
hg/python # 各個 module 開不同目錄, 另有 hg/python/lib 放 third-party modules
hg/java # 相當於 Eclipse 的 workspace 吧, 我們都用 Eclipse 寫 Java
有其它建議嗎?』
Scott:『強烈建議不要在最上層用程式語言分類。
不用IDE開發Python時,目錄很深很麻煩。
我常用:
libfoobar/org.itrs/FoobarServer.java
libfoobar/client.py
等,把Python工具放到跟它有關的Java碼附近。 flat instead of nested.』

4. Mercurial server setup
fcamel:『暫定用 Apache + CGI 吧, 我想把 server 帳號密碼和 VCS 分開, 或是一般來說, 都是綁在一起, 比較省事?』
Scott:『我們可 commit 的 repository用 ssh public key authentication。
這樣developer來來去去,只要在 .ssh/authorized_keys 中加減一行即可。』

5. Merge tool
fcamel:『你慣用的 diff 軟體是?http://hgbook.red-bean.com/read/ 的作者是用 kdiff3』
Scott:『我也是看了 mercurial book之後用 kdiff3。 使用前要花一個小時讀他的 online help手冊,但之後進行複雜的 3-way merge分常有效率。 我之前跟晶片供應商、還有外國同事 merge code 時,非常喜歡kdiff3 可以 split diff hunk、『剩下差異全部選我的版本』 等功能。』

6. 其他建議
fcamel:『有其它用 Mercurial 的相關經驗可以分享嗎?』
Scott:『6-0. 兩個我用過的GUI:
http://bitbucket.org/tortoisehg/stable/wiki/Home
http://bitbucket.org/mercurialeclipse/main/wiki/Home
6-1. Commit notification email 與 hgweb 介面早點設起來。
6-2. Release 流程,事前先跑過,不要凌晨有人打電話問你 "hg push"為何失敗、"hg tag"怎麼用。
6-3. 推新系統,永遠是訓練人最麻煩,可用『種子培訓』
方式散播mercurial知識。』

7. 嘉濠的筆記

今天我們還見面討論了一下:
0. 嘉濠示範了他用 Eclipse 進行 Java Test-Driven-Development 的流程給我看。此流程 iterate 於寫 test case、實作、refactor之間,很依賴 statically typed language 與 IDE 配合: 1. 產生未實作的 method stub 2. 跳到 method definition 3. 改 method signature 時可很方便修改 definition 及標出全部參數不符的使用地點.
1. hgrc 重要:建議統一。mercurial類似 VIM 需要設定檔寫好才能用得順,這是個缺點。
2. kdifff3用法: 選擇 1.共同祖先2.我的版本3.別人的版本. 好用功能:split hunk、剩下全部選B版
3. mq: qinit my.patch、改code、qrefresh、qpop、qpush、qfinish
4. code review 是訓練新人學習的好方法,強制新手第一個月全部的收改都需要在 commit 前通過 review.
5. wiki: fcamel 在 ITRI 的 team 有6 個人在用
6. redmine: Ajax UI 寫的比 Trac 好,支援多個project,但一個專案多個 repository仍未解: http://www.redmine.org/issues/779
7. 用 Python 寫 test code 比用Java省時
8. 用Python也可以寫跟硬體溝通的程式:Scott在研究硬體規格階段喜歡用 Python寫硬體實驗碼。我用 Java 寫 Test Case 時常咒罵為什麼沒有更方便表示輸入資料的 liternal syntax。如要實作某種『簡陋的 domain specific language』 來表達輸入與輸出也是用 dynamic language比較容易。既有的 Python library也有助於快速寫出 test。
9. C 佔優勢的應用領域(fcamel:『為什麼不全部程式都用支援 garbage collection 的語言實作?』): 3D Game Engine、Driver(因為要跟 kernel 配合)、codec(Scott 認為未來可能被opencl或別的可利用 x86 SSE3 與 ARM neon指令的 library 取代)
10. 工作經驗分享: ClearCase 是Motorola的『企業標準版本管理系統』,我從來沒想過一套號稱成熟、貴得要死得軟體可以這麼難用!
11. The Myth of the Genius Programmer: "we discuss how to avoid this trap and gracefully exchange personal ego for personal growth and super-charged collaboration." 但 SVN 在數年之內就被 git 取代。
12. Scott 的個人設定檔集合:包括用 VIM 當 pager(search for MANPAGER、PAGER)