また炊飯器の予約ボタンを押すのを忘れて寝ちまったー。つい 5 分ほど前に炊飯ボタンを押したが、果して家を出る時間までに炊きあがるのか。
追記: 間に合った。
例外的なケースで例外が送出されないのは本当に困るよ。しかも同じ API の他の部分では、例外的なケースは例外が送出されるってのに、一番大事なところで抜けてるんだから。こういう設計の API ってのは他にもおかしな部分が確実にあるので、結局はラッパーみたいなのをかぶせないといけなくなる (ていうか今作ってる)。ああ面倒臭い。
どうせ俺は料理が下手だよ。
criss-cross merge の何が面倒なのか、自分の理解を深めるために書き出してみる。べ、別にあんたのために書いてるんじゃないからね!
まずは最初の状態を A とし、そこに X と Y というオブジェクトを配置する (これはファイルでもいいしファイル内のある部分でも良い。問題は変わらない)。
A: X Y
ここから B, C の二つに流れは分岐する。前者は X を、後者は Y を変更する。
B: *X Y
C: X *Y
次の操作は少しややこしい。 B に C をマージした状態 D と C に B をマージした状態である E へそれぞれの状態を進め、 D は X を、 E は Y をさらに変更する。
D: &X *Y
E: *X &Y
さあここからが大変だ。この二つをマージする場合、 3-way merge のアルゴリズムでは衝突が避けられない (3-way merge の簡単な説明としては、基本は差分の適用を二回なんだけど同じ場所に適用されそうになったら衝突って感じ)。この場合は共通の親リビジョンは A, B, C の三種類。じゃあそれらを比較してみよう。
A: X Y
D: &X *Y
E: *X &Y
^ ^
B: *X Y
D: &X *Y
E: *X &Y
^
C: X *Y
D: &X *Y
E: *X &Y
^
うはー、全部衝突してるじゃん。泣けてくる。こんなの調べるんじゃなかった。マージ機能なんて止めようか、どうせ一人で使うように作ってるんだし。でもなあ、マージ機能がないってそれバージョン管理の意味半減だしなあ (俺はよく適当にブランチ切って実験的なコードを書くので)。どうしようこれ。
一つ思い浮かんだのは、各ブランチごとにマージしたブランチとそのリビジョンを覚えさせておいて、それをもとに依存関係を算出するという物。途中で次のような状態になれば、問題は解決するんじゃないかな。
T: *X *Y
D: &X *Y
E: *X &Y
つまり、テンポラリブランチみたいなのを作ればいいんじゃないかという発想。でもこれで済むのか、本当に? 罠にはまっている可能性がめちゃくちゃ高いので、もう少し考察を進める必要があるな。
ビフィズスヨーグルトの賞味期限が今日であることに気が付き、まだ 200g 以上残っているよなあと思いつつもブルーベリージャムを混ぜて無理矢理食す。無理に食わなくてもいいだろうと思われるかもしれないが、それじゃもったいないお化けが出るだろ!