Darcsっていうバージョン管理システム触ってみた

Darcs

Darcsとはgitやmercurialといった分散型バージョン管理システムの1つ。 Haskellで作られてて以前はGHCの開発に使われていた(今はgit)。

Git使えれば別にいいんですけど、なんか面白そうなので個人的にちょっと使ってみました。

install

自分はstackの環境があるのでstack install darcsですぐにインストールできました。

stackの環境がない人は先にstackを入れてからで→ The Haskell Tool Stack

バイナリ配布もされてます。 Darcs - Download Darcs

tutorial

ローカルでレポジトリを作成する場合は

$ mkdir repo
$ cd repo
$ darcs init

git initとおんなじやね

リモートからcloneする場合は

$ darcs clone user@hub.darcs.net:user/repo

Darcsのホスティングサービスはdarcs hubってのがある。 公開リポジトリを持つ全ユーザがトップページの左側に載ってる。めっちゃこじんまりしてて面白い。

基本的な流れ(gitで言うadd, commit, push)は以下の通りです.

$ darcs whatsnew
No changes!
$ darcs whatsnew -l
a ./hoge.txt
$ darcs add hoge.txt
addfile ./hoge.txt
hunk ./hoge.txt 1
+hoge
$ darcs record -m "init"
addfile ./hoge.txt
Shall I record this change? (1/2)  [ynW...],  or ? for more options: y
hunk ./hoge.txt 1
+hoge
Shall I record this change? (2/2)  [ynW...],  or ? for more options: y
Do you want to Record these changes? [Yglqk...],  or ? for more options: y
Finished recording patch 'init'
$ darcs push

whatsnewはgit statusみたいな感じです。コマンドにwhatsnewってなんか良いですね。 とりあえずdarcs addでパッチとして記録するファイルを選択して、darcs recordでgit commitのように差分を記録することができます。

recordや他のコマンド実行時にいちいちどのファイルを記録しますか?って聞かれることが多々あると思います。 この時に-aをコマンドライン引数につければ、実行時に尋ねられる質問に全てyesを答えるようになるのでいちいち聞かれるのが面倒な場合は便利です。

ちなみにgitでいう.gitフォルダはdarcsだと_darcsです。 ドットで始まってないので見えちゃいます。lsコマンドで普通に見えちゃいます。

今回はとりあえずUndo・Redo系コマンドを見てみましょう。

Undo・Redo

試しにgit reset的な、Undo・Redo的なことをしてみようと思います。

  • darcs revert
    working directoryの最新patchとの差分を戻す。
    darcs unrevertでrevertさせた差分を復元可能。 ただしgit stashとは違いスタック形式で差分を保持できず、1回分しか退避できません。

  • darcs unrecord
    recordしたパッチを削除するコマンド
    git reset HEAD~的なやつ。
    unrecordして削除したパッチは復元できない(っぽい)ので気を付けましょう。

  • darcs obliterate
    recordしたパッチを削除してworking directoryのファイルにもその変更を適用するコマンド
    git reset HEAD~ --hard的なやつ。

  • darcs rollback
    特定のrecordの状態にworking directoryを変更する。
    git checkoutに近い感じ。

これらのコマンドも実行すると対話的に「どのrecordに戻しますか?本当に実行しますか?」と親切に訊いてくれます。 逆にコマンドライン引数にどういう文字列を入れるとコマンド一発で実行できるのかはよくわかってません。 いろいろオプションを調べてはいるのですが、やっぱり対話的に訊いてきます。 めっちゃ喋りたがりやな。 もっと調べておきます。

今回は試しにrollbackとobliterateを動かしてみます。

以下のlogの状態でそれぞれのコマンドを打ってみます。

$ darcs log
patch f91626830cfbc4411bafcaec3b57cb98f6318c4d
Author: ****@gmail.com
Date:   Fri Nov 24 20:05:23 JST 2017
  * add "bbbb"

patch 3cad4b61e314a12e3f6c7b862d2ef760e16995ab
Author: ****@gmail.com
Date:   Fri Nov 24 20:05:03 JST 2017
  * add "aaaa"

patch de3025a8c00de51150379f8dba139fe9cdf0c8f6
Author: ****@gmail.com
Date:   Tue Oct 17 20:03:38 JST 2017
  * init

最初はrollback
checkoutみたいな感じでworking directoryの内容を特定のパッチ時点に戻せます。 rollbackコマンド実行後にどのパッチに戻すか聞かれます。

$ darcs rollback
patch f91626830cfbc4411bafcaec3b57cb98f6318c4d
Author: horoama929@gmail.com
Date:   Fri Nov 24 20:05:23 JST 2017
  * add "bbbb"
Shall I rollback this patch? (1/3)  [ynW...],  or ? for more options: y
patch 3cad4b61e314a12e3f6c7b862d2ef760e16995ab
Author: horoama929@gmail.com
Date:   Fri Nov 24 20:05:03 JST 2017
  * add "aaaa"
Shall I rollback this patch? (2/3)  [ynW...],  or ? for more options: n
Will not ask whether to rollback 1 already decided patch.
Do you want to Rollback these patches? [Yglqk...],  or ? for more options: y
hunk ./hoge.txt 3
+bbbb
Shall I rollback this change? (1/1)  [ynW...],  or ? for more options: y
Do you want to Rollback these changes? [Yglqk...],  or ? for more options: y
Changes rolled back in working directory
$ darcs diff
hunk ./hoge.txt 3
-bbbb

で、これ思ったんすけどrollback後にやっぱ最新のパッチ反映時に戻したいって時どうすんでしょ。 rollbackは指定したパッチを逆に当てるって感じなので、それができません。
汚い方法は以下の通り

$darcs diff -n 1 > /tmp/patch.diff
$patch -u < /tmp/patch.diff

もうdarcsの機能使ってないじゃねーか。
てかよくよく考えたらdarcs revertで良かったわ。

他の機能

なんかrabaseコマンドとかあるっぽいんですが、よくわかんないっす。 もうちょっといじってみます…

まとめ

あくまでパッチを管理するツールって感じなんですかねえ。もちろんブランチ機能はないです。 間違えてコマンド打った時に救済措置がなくてちょっと辛い。 gitより機能は乏しいですが、最低限のことはできそうなので普通に使えそう。

まぁgit使いますけど