Ask, Do, Commit

受到姿勢跑法(Pose Method)將跑步簡化為 Fall,Pose,Pull 三個動作的啓發,我在想,寫程式是否也能有這樣的簡化?

回想了一下,自己寫程式的過程,似乎也可簡單分成幾個:

1. Ask
先問自己一個問題,或是從 issue tracker 裡挑一個問題。

2. Do
在問題的驅使下,開始去作一些事,如寫程式、調整設定,或是研究資料之類的。

3. Commit
作到某個階段就作個 commit ,可能是版本控制的 commit ,或是筆記的儲存。有點像是玩 RPG 遊戲時”遊戲進度存檔”的功能。

備註:
其中,我覺得第一步是最困難的,很多時候不知那根筋不對,腦筋就是無法進入專注。我發現到,我自己似乎比較常在被問問題,(尤其是有趣的問題),而腦袋開始想東西時,那瞬間好像有什麼開關被打開了一樣。

git 分支運作模式之我見

tag: merge / patch / 上游 / 下游 / 順流 / 逆流

特性: merge strategy

git 的 merge 有多種不同的 strategy 模式,可透過


git merge [-s ] [-X ]

比較常用的有


git merge -s ours # 以我方 branch 為主


git merge -s recursive -X ours # 如遇衝突以我方 branch 為主
git merge -s recursive -X theirs # 如遇衝突以對方 branch 為主

其中, 最重要的是預設模式為


git merge -s recursive

特性: merge base

git 在作 merge 時,除了參考兩方 branch 的 HEAD ,還會參考兩個 branch 的共同 ancestor 。

View post on imgur.com

以上圖為例,R 是 A,B 分支共同的 ancestor ,也是 A3, B2 的 merge base。

要如何找出 merge base 呢? 除了手算外,也可以下指令找出 merge base:


git merge-base [branch A] [branch B]

特性: git 下不會影響 merge base 的 merge 方式
git 還有其他不會影響 merge base 的 merge 方式,如下:

* git cherry-pick
* git merge –squash
* 以 patches 形式匯入

特性: merge 的累積性

當我們持續跟隨 merge 某個分支時,會發現新一次的 merge 會參考前一次 merge 的資訊,而只處理前一次 merge 完之後的新變更。也就是說,之前已經處理的 merge conflict ,不會再重複出現,也不需要重複處理。這個聰明特性讓 git merge 變得很好用。其示意圖大致如下:

View post on imgur.com

上圖中,黃色記號的點,是兩個 branch 在 merge 時,所納入計算的 merge base。我們可以注意到,merge base 會依新的 merge 成果,往前累積紀錄點。

另一個值得注意的地方是,雖然是 B 分支 merge A 分支,但 merge base 是在 A 分支上,而上圖的 merge 過程,merge base 都是保持在 A 分支上。

特性: 交叉 merge 的變化

當 git merge 的方向改變時, merge base 也會隨之變化。示例圖如下:

View post on imgur.com

上圖中,黃色記號所註記的 merge base 點,隨著 B merge A 切換成 A merge B 時,merge base 也跟著從 A 分支切換到 B 分支上。而這個變化,正是藏在細節裡的魔鬼,因為這個切換,使先前累積一致的紀錄點中斷了。在中斷之後,再一次回到 B merge A 時,會發現先前已經處理過的舊 conflict 又再一次重複出現。

也就是說,交叉 merge 會破壞掉原先 merge 的累積紀錄,不管是 A 分支或是 B 分支,都會失去 merge 的累積性。

在交叉 merge 的特性下,只會有兩個結果,一個是兩分支漸趨一致,最後合而為一,或是保持獨立分支,但一直不斷的處理先前舊的 merge conflict。

特性: merge base 俱有傳遞性
舉例
當 B merge A ,而 C 又 merge B 時,C 的 merge base 會分別紀錄在 A, B 分支上。接著,當 A merge C 時,merge base 切換紀錄在 C 分支上。則當下一次 C 再次 merge B 之時,會發現之前累積在 A, B 分支上的 merge base 紀錄中斷了,而切換到 C 分支上。

觀察: 順流發佈與逆流整合
在分支的使用過程中,我觀察到兩種類型的使用情境。

其一,順流發佈。
以 Linux Kernel 為例,主要的版本會在最上游的 kernel mainline 發佈,然後各個 Linux distribution 主分支再 merge mainline 新發佈的程式碼。而再更下游的 distribution 分支,會再 merge 上述的主分支的程式。

這個過程主要是從功能開發的上游往下游遞延,跟產品製造從生產、經銷、商店的發佈流程類似。

這個模式在 git branch 模式中,很容易實現,只要以 fork 的方式從上游衍生下游分支,並持續單向 merge 即可。

其二,逆流整合
商品出現問題時,回饋的方向則跟上述的流程是相反的。舉例來說,消費者可能先反應給商店,商店反應給經銷,經銷再回饋給製造的上游廠商,或是消費者也有管道可直接反應給經銷商、製造商。不論經過幾層,這個方向跟順流發佈是相反的。

程式也是一樣,可能有 bug 或是新功能,是散佈在下游的分支們之間。為了讓這些成果能夠發佈到更多地方使用,我們會嘗試將這些成果整合到上游的分支,以利下一波發佈時能一併分佈到其他更多下游分支。

一般來說,我們在 git 下實行的方式,大概是從主要版本中成立一個獨立開發分支,然後用這個分支去一一 merge 那些想要整合的下游分支。

順流發佈與逆流整合的衝突
我在嘗試建立分支之間的發佈與整合流程時,遭遇了大挫敗。情況大概是,我在處理完近幾個 merge conflict ,建立順流發佈的分支架構後,卻在一次逆流整合的小小 merge 之後,先前已經處理過的舊 conflict 又重新冒了出來。

為什麼?

這問題我卡了很久,後來研究發現,其實原因就是上述提及的兩個:
* 交叉 merge 的變化
* merge base 俱有傳遞性

也就是說,我在順流發佈與逆流整合的分支流程中,構成了迴路,使得整個 merge base 的累積性紀錄被破壞了。

重構 git 分支結構的兩個原則
要解決上述的問題,唯一的方法就是避免產生 merge base 的迴路。根據上述的種種特性與觀察,我想出了兩個原則來克服這個問題:

1. 在 git 分支結構中,區別出上游與下游的順序關係
2. 逆流方向必須使用不影響 merge base 的 merge 方式(ex: patches/cherry-pick/merge –squash/…)

重新審視 git workflow

以最常被引用的 nvie 的經典文章 A successful Git branching model 為例:

View post on imgur.com

從上圖的開發流程中,大略可分類為 develop + feature branches => release branches => master + hotfixes,可劃分為 upstream , midstream, downstream。其中,標上星號的是我認為是逆流方向的 merge的部份。

以 tag=1.0 這個節點為例,在 merge 產生 tag=1.0 時,參與 merge 計算的有,tag=0.2 節點跟綠色的 release branch 節點,還有作為 merge base 參考點的 hotfixed 紅色節點。但如果 hotfixes 往 develop 分支的 merge 是斷開的話,那麼 merge base 參考點,就會是 tag=0.1 節點了。也就是說圖中的 hotfixes 分支往 develop 分支的 merge ,破壞了原先累積性的 workflow 設計。雖然此示例圖比較簡單,看起來影響不是很明顯,但在更複雜的案例中,很可能就因某次的逆流 merge 而導致整體 workflow 衝突中斷。

這也是為什麼,這麼多人依這一篇文章建立 git workflow 運作一段時間之後,卻遇到一些難纏的 merge conflict 的問題的原因了。會出現奇怪的 conflict 其實不是你的錯,而這個 git workflow 本身就漏了這個細節中的魔鬼。

延伸思考

仔細觀察 Linux Kernel 的 workflow,你會發現 upstream 沒有在收 Pull Request 的,而是以 patch / squash merge 的方式在整合的。

為什麼 upstream 不收 Pull Request 呢? 又 Pull Request 適用在那些 workflow ,又不適合那些 workflow呢? 這些問題,從上述提出的觀點下,都有了解釋與答案了。

Bash 上的 Error Handling 實作策略

大綱:

1. 實際上遇到的問題, 與 bash 預設的模式

2. Error Handling 議題: keepgoing(風雨無阻) v.s. longtake(一鏡到底)

3. Error Handling 議題: return v.s. exception(bubble) v.s. signal

4. Bash 現有的的機制 trap / kill / set -o errtrace

5. 自行設計 Bash Error Handling 機制 ( Backtrace / Handler stack / Error policy )

没大没小不是壞事

其實有些東西是由外而內的,語言和動作,都在不知不覺中由外而內的影響著自己。

若常常將,”大大”、”小小” 掛在嘴邊,久了心中就難免有”大大”、”小小”的分別。而人的心中一旦有了”大大”、”小小”的分別,也跟著就有了差別心、定見、偏見。心中惦記著地位高低,疏於正視其本質,繼而疏於在本質上繼續精益求精。

我最早是剛開始參加社群活動時,聽到”大大”、”小小”一詞覺得不大習慣。後來習慣了也跟著用,直到某天想通了,就決定改掉了。

請試著去掉”大大”、”小小”的字詞吧。有時候,没大没小不是壞事。

在 ./configure 時檢查 Header 的 Dependency

換電腦製作套件檔時,常常會發現漏掉的 dependency 在 make 時產生讓使用者不知所措的 error。

g++ -DHAVE_CONFIG_H -I. -I/usr/local/include -fno-exceptions -fno-rtti `pkg-config –cflags freetype2` -g -O2 -MT fbterm_ucimf-font.o -MD -MP -MF .deps/fbterm_ucimf-font.Tpo -c -o fbterm_ucimf-font.o `test -f ‘font.cpp’ || echo ‘./’`font.cpp

font.cpp:22:35: error: fontconfig/fontconfig.h: 沒有此一檔案或目錄

font.cpp: In static member function ‘static Font* Font::createInstance()’:

可以在 configure.ac 加上

AC_CHECK_HEADERS ([fontconfig/fontconfig.h], [echo “有 fontconfig, pass~”], [echo “沒有 fontconfig, 請裝 fontconfig”], []

這樣子使用者在 ./configure 時,就可以收到關於這個 headers 的檢查訊息了。你可以在這裡加上一些親切簡短的文字,幫助使用者先定下心嘗試回報、解決問題。

聽別人,沒聽自己。

車師姊說,我很敏銳,可以聽到對方許多細微的勁。
可是卻很少去聽自己身體的地方。

是啊,我太習慣去注意別人的缺漏的地方,卻很少注意自己的部分。

真是一語道醒夢中人。

25+1

變革許多,一路回來一直聽到不好的消息,不好的爭吵聲。
我試著把持心定,不受其他事物的影響。
默默認住未來的道路,專注的踏出每一步。

現在的我,一無所有,只有一顆追求自由而熱愛創作的心。

p.s. 謝謝月亮貓帶我去超有品味的茶店,幫我過一個特別的 25+1。

OLPC Hacking Meet-up心得

View post on imgur.com

經過十天的等待,於於完成了這次「OLPC Hack Meet-Up Day」 的活動。活動期間,感謝jollen、jserv、PingYeh、 Andrew、…等人提供不少對活動的經驗和建議。這段期間也感謝BV1AL、KC、olv、 FourDollars、linanne、aguai、wesley、thinker、yungyuc、gaso、yuren…等人的幫忙,才能順利 將活動完成。

活動開始,先是由Mat簡單介紹一下如何用QEMU模擬OLPC和測試程式。之後則是共同開發和交流討論。21:10-22:00 則是展示時間,首先是jserv展示了QEMU用於模擬系統開發的各個應用,也現場展示了他最新的成果「親手打造Tablet / WebPad」。接著,FourDollars也跟著和大家分享影音串流程式最新的發展,分析未來的驅勢。並同時展示了一個他參考pcman的程式而改出來的影音外掛程式。可以非常方便的點選網路廣播並收聽,並發想也能整合進OLPC,提高OLPC的娛樂性。

而在PCMan on OLPC這個主題上,由國內開發LiveCD(USB)系列的BV1AL將gcinOLPC上的成果作成LiveCD的映像檔,並設定好網路等相關部分。而PCMan X開發團隊的字型好手olv ,則是解決OLPCPCMan X中文字型顯示的問題。在經過一段時間修改,順利將兩方的成果結合起來,如下:

View post on imgur.com

雖然還是有許多小缺點,但這張快照也象徵了我們用行動來實踐我們的信念,也呼應了活動發起的訴求。

在活動期間,wesley、aguai、annelin… 也嘗試利用QEMU建立多個OLPC來模擬mesh network的測試環境。而Andrew、PingYeh、BV1AL、…在Tick偶然拿到OLPC實機的root console後,也著手研究了OLPC的系統更新、開機流程,相信不久之後也能見到相關的經驗分享。

最後希望能持續將這些成果整理出來,以開放的方式回饋給upstream和社群。