git さんと darcs さん

HIMA' に参加してきました。今回のお題は「gitとdarcsの使い方」。
darcs のパッチ理論の話とか聞けるかなーと思っていたのですが、聞けなかったのでちょっと残念でした。そもそもパッチ理論の話出来る人っているのかなっていう…

とりあえず恐らく利用者が多いであろう git ユーザー向けに darcs の特徴とか。

  • バージョン管理というよりパッチ管理。
  • 歴史(コミットが形成する DAG)は存在しない。あるのは積み重なったパッチだけ。
    • パッチ間の依存関係を考慮したシステム。依存関係さえ問題なく解決されていれば、昔のパッチを削除しようが何しようが関係なし…ヒエー
  • ブランチはない。ブランチが欲しければリポジトリを作る。
  • インデックスはない。
  • author と committer の区別はない。あるのはパッチの作成者だけ。
  • パッチに名前がある。基本的にパッチは名前で指定。

こんなもんですかね。あとはコマンドの比較表とかあればいいんでしょうか。

説明 darcs git
リポジトリパス _darcs .git
無視ファイル設定 _darcs/boring .git/info/exclude
リポジトリの初期化 darcs initialize git init
リポジトリの複製 darcs get git clone
追跡するファイルの追加 darcs add git add
ファイルの移動 darcs move git mv
ワーキングディレクトリの状態確認 darcs whatsnew git diff
パッチの閲覧 darcs changes git log
パッチの閲覧(差分付き) darcs changes -v git log -p
パッチの作成 darcs record git add -u -p && git commit
パッチの修正 darcs amend-record git commit --amend
パッチの削除 darcs unrecord git reset HEAD~
パッチの削除とワーキングディレクトリの巻き戻し darcs obliterate git reset --hard HEAD~
作業内容の退避 darcs revert git stash
退避した作業内容の復元 darcs unrevert git stash pop
リモートリポジトリのパッチのローカルへの適用 darcs pull git pull
リモートリポジトリに対するローカルのパッチの適用 darcs push git push
タグの付与 darcs tag git tag
タグの閲覧 darcs show tags git tag(引数なし)
最後に変更したパッチの特定 darcs annotate git annotate
メールによるパッチの送信 darcs send git send-email とか?よくしらない
パッチの適用 darcs apply git applypatch とか?よくしらない
設定の変更 darcs setpref かな?使ってないので違うかも git config

割と正確でない一覧です。

darcs add は追跡対象を増やすコマンドですが、git add は正確にはインデックスに変更をステージするコマンドです。
そうそう、途中「git add って分かりにくいよね git stage みたいな名前なら良かったのに」という話になりましたが、調べてみたところ矢張り既に git stage コマンドは git add の別名としてデフォルトで存在していました…

darcs unrecord は、他のどのパッチからも依存されていないパッチ全てを対象に、対話的にどのパッチの適用をやめるか聞かれます。大体どのコマンドも対話的に利用できます。一方 git reset HEAD~ は直前のコミットの取り消しなので、より正確には git rebase --interactive のほうが近いです。が、それも完全に同じではありません。

darcs obliterate も darcs unrecord と同様。darcs obliterate は darcs unrecord には触れない、他のパッチに依存されているようなパッチも無理やり削除できるのかな?試してないです。ちなみに darcs unrecord で -p オプションとかで他のパッチに依存されているようなパッチを指定しようとすると、まずは依存するパッチ取り消せボケ、と依存しているパッチを先に聞いてきます。何それすごい…

darcs revert は git stash のように作業内容を複数スタックすることはできません。二度 revert すると、最初の revert の内容は失われてしまいます。

darcs amend-record は、他のどのパッチからも依存されていないパッチ全てを修正することができます。一方 git commit --amend は直前のコミットしか変更することができません。git rebase --interactive と組み合わせることでどのコミットも修正することができますが、矢張り完全に同じではありません。

darcs annotate は行ごとには出力されないので、それなりにパッチが積み重なってくると git annotate に比べて見づらいです。多分。

あとは git でよく利用されるけれど darcs にないコマンドについて書けばいいかな。

darcs のパッチは、名前の通り git のコミット程には情報を持っていない、タダの差分の集合なので、git show に相当するコマンドはありません。darcs diff で十分ということでしょう。最新のパッチは darcs diff --last=1 で確認することができます。

そもそもパッチはグラフを構成したりしてないので git rebase のようなものもありません。無理やり _darcs を書き換えて根元をすげ替えるみたいなパワフルな運用が実際に行われていると聞きました。クレイジー

ブランチがないので git checkout がないっていうのはまあいいですかね。単に HEAD の状態に特定のファイルを戻したい、という時には revert が代替になると思います。

矢張り同様に、ブランチがないので git merge のような、ブランチをマージするためのコマンドもありません。

git grep や git bisect (これをよく利用されているとは言えないと思うけれど)に相当するものはありません。残念。

ビジュアライザありません。折角の依存関係も目に見えないんじゃ、こう、台無しだろうと思うんですが…しかも昔はあったそうです。なんだそれ?

あと darcs の _darcs/boring にはデフォルトで色々書いてあるのでちょっとうれしいかもしれません。何故 .cvsignore は書いてあるのに .svnignore とか .gitignore はないんだみたいな切なさはありますが…

大体こんな感じでしょうか。個人的には、ツールとしては git のほうがはるかにこなれているなあ、と思います。お節介なメッセージであるとか、たまに嬉しいちょっと便利なコマンドであるとか。darcs のパッチ間の依存解析はちょっとすごいなって思いますが、現実にどういう場合に嬉しいのか、が結局分かってないのでよく分かりません。

とりあえず、新しく何か書き始めるような機会があったら、ちょっと試してみようかなと思っています。というかそんな感じで初心者なので嘘書いてたら教えてください。

バージョン管理と一言にいっても色々なので、バージョン管理システムは目的にあわせて正しく選択しましょう、みたいなありきたりな締めにしかならないんですが。おしまい。