Mercurial 的 MQ extension

大家都知道 git 有 staging area.
的確是,在台灣玩git的人真的是比較多.

mercurial 則是有MQ extension 來實現同樣的功能.

MQ =  Mercurial Queues ,他的根本意義是,在work copy 跟 repo 之間,實作一個queue 的概念.
有了這個queue 的實作,使用者可以把它當作staging area 來使用,也可以把它當作 patch manage 來使用 , 當然用法不只如此,一旦知道了使用方法後,他的通用性可以讓使用者自由發揮創意.

我很喜歡進行小步進的開發,有可能一個小功能我會再切分更細的工作元素.可是我不希望repo的 log 上滿滿的都是瑣碎的提交,我希望提交的內容是一個完整的功能,或是一個完整的演算法實作,或是一個完美的 bug resolv 方案,因此我的需求就是將一整個串的小修改紀錄變成"一個
"提交.

git 的 local branch 可以很方便的做到這樣.我只要開出一個新分支,改個幾行就commit , 等到功能測試完成,我用Squashed merge 模式 來 merge 到主幹.這樣主幹只會有一個commit 紀錄.

可是其實我還是對mercurial 有愛.如果能在mercurial 下做事,自然是盡量在mercurial 下做.如果我沒有 MQ , 我必須clone 兩份 mercurial repo ,一分作小步進的commit , 等到完成後,用diff 輸出所有的差異,commit 到另一份 repo ,接著 push / pull 到主幹

幹! 真是麻煩.

所以我想到可以用MQ來幫我做.
首先,要啟動 MQ ,請修改 repo 下的.hg/hgrc or ~/mercurial.ini

[extensions]
mq =
這樣就可以了.
有了 MQ 後要怎麼做?

作業概念上是依照以下順序. 新建一個queue --> 修改檔案內容 --> 把變動送進 queue ---> 修改檔案內容 --> 把變動送進 queue ---> 修改檔案內容 --> 把變動送進 queue ---> .......---> 完成,把queue 的內容送進repo 成為一個提交.


新建一個queue 的指令為 qnew . qnew 的語法如下

hg qnew -m "此queue 的大略說明" queue的名字
ex.
hg qnew -m "imprement A logic" a_logic

這樣,你已經有個叫做 a_logic 的queue , 你也可以叫他做a_logic 的staging area , 你也可以叫他做一個 a_logic 的 patch

接著,開始修改內容,修改完後,執行 qrefresh 將變動送上queue 裡面去. qrefresh 指令如下

hg qrefresh

如果你想要更改queue 的說明,可以加上 -m

hg qrefresh -m "想要更改的說明文字"

這著這個流程一直做下去,你就可以一直不停的小步進進行queue 的紀錄.等到整個程式碼都測試完成,現在可以把queue 的內容送上repo 了.指令如下

hg qfinish queue_name
ex.
hg qfinish a_logic

這樣,你就會在repo 的 log 上看到一個commit . 這個commit 的說明就是當初你用qnew / qrefresh -m 所設定的字串.


既然queue 可以設定名字,那麼支援多個queue自然是很合理的(像git 原生支援一個staging area  , 這個staging area 就沒有名字).如果使用跟管理多個queue?

你可以重複執行 qnew 來產生多個queue.然後,你可以用qseries 來看你目前有多少個queue.
ex.
hg qseries

然後,你可以使用qpush / qpop 來切換queue . 首先要先pop掉你目前的queue.
ex.
hg qpop queue_name

然後換上你想要的queue.
ex.
hg qpush queue_name

另外,你還能用qdiff 檢查queue 裡面記錄了什麼東西
ex.
hg qdiff


MQ 的介紹大概就這樣,不過,MQ的功能強大,我這邊沒有講得很詳盡,像MQ 支援patch概念的指令跟操作,以及queue 可以像一般repo 一樣模擬commit 操作 ,這些我都沒有介紹到



留言

這個網誌中的熱門文章

[C語言]宣告陣列的大小是0 ???

利用net-snmp 的mib2c,由一個MIB檔產出一個可執行的AgentX 程式

ubuntu 16.04開機遇到 flip_done timed out 的問題