ストーリーとヒストリー

あるいは考古学者は新しい仕事を見つけるであろうこと

Ichi Kanaya
Pineapple Blog
6 min readJan 12, 2016

--

人は失敗する.

悪いことに,失敗は失敗してみて初めて失敗だと気づくものだ.

バージョン管理システムのGitと Mercurial (Hg) は,失敗に対して正反対のアプローチをしているように思える.どちらが優れているのかはわからない.

SourceTree という優れたユーザインタフェースのお陰でGitもMercurialも見かけの使い勝手はほぼ同じである.しかし,その背後にある設計というか,人間という存在への考え方は異なるようだ.

Gitは新しい試みを行うときに,新たなブランチを作成することを勧める.勧めるとは,そのための機能が豊富にあり,それ以外の迂回路は積極的にサポートされないということだ.もう一度言うと,新しい試みは新しいブランチで行うのがGitの流儀だ.もしその試みが成功したら,オリジナルのブランチから fast forward すればよいし,オリジナルのブランチが進んでいたらrebaseすることだって出来る.どちらの場合もmergeを行うことが僕の好みだが,Gitは fast forward もrebaseもサポートしているし,Git文化はその両者の使用をエンカレッジしている.もしその試みが失敗ならば,単純に放置すれば良い.

Gitでは間違ったコミットを柔軟に取り消せる.もちろんこれは危険なことだが,リポジトリのコピーは文字通り分散しているので,最悪のケースでも本当に必要なコードはどこかで生き残っているだろうという発想かもしれない.

一方でMercurialは厳格だ.まず,取り消せるコミットは一つ前のものに限られる.これとて大幅な譲渡に思える.間違えたのも歴史なら,それを修正するコミットもまた歴史だ.コミットを一つだけ取り消すrollbackコマンドの存在意義は,コメントやタグの付け間違いなど,メタデータに関する取り消しにあるのだろう.(コミットグラフを Git 並に操作できるプラグインが存在するのだが,ここでは文化的背景について述べている.)

そしてMercurialがGitと決定的に異なるのはブランチの考え方だ.Gitではブランチ名はただのポインタだ.コミットグラフ上のある一点を指し示す変数,それがGitのブランチだ.一方Mercurialではブランチ名は各々のコミットがたかだか一つだけ持つことを許された名前だ.デフォルトで子供コミットは親コミットのブランチ名を引き継ぐため見かけ上はブランチに名前をつけているように見えるが,実際にはコミットごとにブランチ名を持っているため,コミットのフォルダと呼んだほうが正確であろう.

Mercurialでは一度作ったブランチ名は消せないし,変更もできない.それが歴史だからだ.ただし,ブランチ名をcloseすることで隠すことは出来る.(プラグインを駆使すれば Mercurial でもブランチの名前を変更することが出来る.ただし,Git だろうが Mercurial だろうが他のリポジトリに push したブランチの名前は — たとえ変えられるにしても — 変えないほうが安全だ.)

よくご存じの方はMercurialにはbookmarkがあるだろうと言われるだろう.その通り.MercurialのbookmarkはGitにおけるブランチ(つまりはポインタ)と同じだ.ただしMercurialは原則として歴史の修正を認めないから,Gitのようにコミットグラフを動き回るポインタというのはあまり便利なものではないし,どうしても必要になる場面もほとんどない.

もうひとつ,GitでもMercurialでも名無しブランチを作ることは出来る.それはコミットログの中には存在するが,Gitならコミット自身かその子孫をどのブランチもポイントしていない状態,Mercurialならば唯一のブランチ名もbookmarkも与えられていない状態だ.このような名無しブランチは,Gitリポジトリからは静かに消される一方,Mercurialリポジトリの中では永久に生き残る.

人は失敗するものだ.

そのヒストリーを,ストーリーとして読みやすくするためには修正を辞さないGitと,ヒストリーとはそんなもんでしょとありのまま残すMercurial.

バージョン管理システムの平均的な寿命を考えると,GitもMercurialもこのまま行くと考えるのは楽観的にすぎる気がするだろう.次のバージョン管理システムはどちらの思想をベースにするだろうか.

僕は,これは本当に僕の直感なのだけれど,Gitのやり方は破綻すると思っている.分散されたリポジトリで,細々と歴史を修正していても,大きな流れに見通しをたてることは難しい.ではMercurialか.もちろん,答えはノーだ.Mercurialのやり方はもっと早く破綻するだろう.人はストーリーしか理解できないのだ.

そう,僕は長々と水路を掘り,いままさに我が田に水を引き入れようとしている.美しき田園風景が目に浮かぶではないか.

履歴は履歴だ.Mercurialのrollbackすらメタデータ以外には適用すべきではない.Gitのresetなどとんでもない.すべて残せ.それらは滋養に満ちたコンテクストなのだ.そこからストーリーを,テクストを引き上げるのは考古学者の仕事ではないだろうか.

次に来るバージョン管理システムは,プログラマと考古学者の共同作業で運用されることを強く望むだろう.考古学者はコミットログの中を泳ぎ,一本のストーリーを見つけ,それに名前をつけ,ひょっとしたら注釈も載せて,ブランチヘッドをそこへ移動させる.プログラマは,まずストーリーを読むことから始めるだろう.一気に書いてしまったほうが速いケースはあるが,1年後の自分など他人だ.絶対にストーリーが必要になる.プログラマたちが織りなすタペストリーなんて,誰が鑑賞するものか.

人が失敗し続ける限り,考古学者は新たな仕事を見つけるだろう.

参考:

A Guide to Branching in Mercurial

(特にGitユーザには是非読んでおいて欲しい)Mercurialにおける『ブランチ』の概念

Originally published at blog.pineapple.cc.

--

--