menu
書いてる野郎
orebike@gmail.com
マージの一種。ブランチの途中(大体根本)を切り取って別ブランチの先にくっつけるという操作。 つまり並走しているリビジョン群の片方をどちらかの頭にくっつけて一直線のリビジョンにする。
複数人開発をしていてpullした時に自分がローカルで操作しているブランチに変更があると Hg が勝手にブランチを分けてしまう。 確かに自分が積み重ねているリビジョンとは違う積み重ねがpullで外部から来るわけだから別ブランチになってしまうのは当然。
ブランチが同一だったとしても変更範囲が被らなければ・・・単に自分の変更をブランチ統合するためだけにマージという行為をしてしまう。 これはソースの状態によるマージではなく単なる変更の順番を解決できないというだけだ。
ということで pull, push をやっているとその度にやる必要のないマージ行為が増えてしまう。 ソース上に問題は無いのに管理上の関係でブランチの分岐と統合がひっきりなしに起きてしまう。
後から見ると、理由があって作っているブランチとこの理由のないブランチがゴチャゴチャになってわけわからなくなるので、一直線にしてわかりやすくしましょうという話。
絶対に rebase 時にぶつからないとわかっているなら、これが一番お手軽。
Hgは標準でrebaseをサポートしていないがrebase拡張が同梱されているので単にONにすれば使えるようになる
[extensions] rebase =
$ hg rebase -s 移動対象のリビジョン -d 移動先のリビジョン
わかりにくいがs
で切り取って先頭に繋げたいリビジョンの塊の根っこのリビジョンを指定する。
d
で指定している方の先にs
で指定したリビジョンの塊が繋がる。
ということになっているが、実際問題として rebase は本線の変更の取り込みにたいして仕掛り中のブランチの追従させることがメインなので
作業中の hoge ブランチを取り込んで伸びた本線の piyo ブランチの先にくっつける場合このようになる
$ hg update hoge $ hg rebase -d piyo --keepbranches
このコマンドでは push 済みの branch はrebase で移動できないので hg push –new-branch
で押し込む前のものを使う
なんかできない。
普通に切り取られてrebaseされる
途中から先のリビジョンが先頭に移動する。
するのだが、その「途中」というやつがそれ以前のリビジョンに依存性があった場合、rebaseが失敗するので手動で解決しなければならなくなる。
rebase拡張の内部処理はよくわかっていないのだが、動きを見ると、 移動先の頭にリビジョンを作ってそこに根本から1個1個マージしているように見える。
なので衝突があったら衝突があったリビジョンを移動する度にマージ処理が入る。 Hg側で解決してくれるのならそのまま続行、駄目なら手動マージということになる。
どうなる?
普通に接木するように含んでいる別ブランチごと丸々rebaseされる。 注意としては含んでいる別ブランチが名前付きブランチだった場合そのブランチ名が統合先のブランチ名と同じになってしまうということ
graftはマージアルゴリズムを使って対象のリビジョンを移植する作業なので、並走するワークに対してrebaseしたいブランチの根本から順番にgraftしていけば移植先のブランチの先頭にrebaseしたいブランチをつなげることができる。
graftは移植なので元のブランチが残ってしまう。全部性格に移植が終わったなら、MQ拡張のstripで元を消してしまうとOK。
rebaseしたブランチ全体をqimportでパッチ化し、パッチとしてMQ側で確保した状態でqpopで履歴改変、リビジョンを削除してしまう。
Hg側で移植先にupdateしてqpushでリビジョンを付与してやる。
2012-04-27 新規