このエントリは はてなデベロッパーアドベントカレンダーの21日目のエントリです。
developer.hatenastaff.com
id:motemen さん作のリポジトリ管理ツールであるところの
ghq を最近ようやく使い始めたところ大変便利だったのですが、いかんせん手元の~/work/や~/hobby/にはすでにgit cloneしたリポジトリが山ほど転がっています。今回、それをghq管理下のディレクトリにさっと移してghqライフをスタートさせた話をします。
ghq
ghq そのものについての説明は作者のid:motemenさんのエントリが詳しいので、そちらをご参照ください。
motemen.hatenablog.com
代表的な使い方は↓こういう感じで、まぁだいたいどういうことかわかっていただけるのではないかと思います。
[asato@praline01 ~]$ ghq get git@github.com:astj/p5-Test-WWW-Stub.git
clone ssh://git@github.com/astj/p5-Test-WWW-Stub.git -> /Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub
git clone ssh://git@github.com/astj/p5-Test-WWW-Stub.git /Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub
Cloning into '/Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub'...
remote: Counting objects: 329, done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 329 (delta 16), reused 0 (delta 0), pack-reused 283
Receiving objects: 100% (329/329), 55.39 KiB | 0 bytes/s, done.
Resolving deltas: 100% (121/121), done.
Checking connectivity... done.
$ ghq list -p | grep p5
/Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub
$ ghq look p5-Test-WWW-Stub
cd /Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub
[github.com/astj/p5-Test-WWW-Stub]$ pwd
/Users/asato/.ghq/github.com/astj/p5-Test-WWW-Stub
ghqを使い始めて何が良かったか
まぁいろいろあるのですが、個人的に感じている主なメリットは
あたりです。なんだかあまり嬉しそうに見えませんが、リポジトリのディレクトリに移動したり新しくgit clone時は基本的に「やるぞ!」という気持ちなので、そこに水を差されずに済むのはそれだけで結構幸せという気持ちがあります。
後は、手元に入っていたpercolと組み合わせてaliasを定義してリポジトリ名をインクリメンタルサーチしてそのディレクトリに移動、というのをスムーズに行えるようにしてあります。
alias repo="ghq look \`ghq list | percol\`"
ghqを使い始める前に悩んだこと
とまぁ便利にghqを使っているのですが、ghqの便利さを説く人たちが周りに続々増えつつある中僕がずっとためらっていたのは、エントリの冒頭にも書いたように雑多にgit cloneしたディレクトリたちの末路でした。コード読むためだけにcloneしたリポジトリは最悪見捨てて再度ghq getすれば良いのですが、実際にコード書いてるリポジトリでは、秘蔵のブランチやgit stashがあったり、ローカルビルドの成果でgit管理していないファイルが転がっていたり……というのがままあるので捨てるわけにもいきません。また、数が増えてくるとどれが大事に使うべきでどれが雑に捨てていいリポジトリなのか考えるのも億劫です。
ghq-migrator
そこで、既存のリポジトリのgit remoteを見ていい感じにディレクトリを移してくれる雑なシェルスクリプトを書いて、それでガーッと引越ししてしまうことにしました。
ghq-migratorなどとカッコつけた名前でgithubにもアップロードしてあります。bashのスクリプトが1枚と、10分ほどで書いた雑なREADMEが置いてあるだけです。自分の引越しに使った程度なので中身は雑だしコメントや出力の英語はぶっ壊れていますが、最近のMacの環境でなら動くことは動くのではないかなと思います。
github.com
シェルスクリプトで凝ったオプションの解析をやるのも面倒だったので、手抜きして動作にまつわる設定もすべて環境変数で済ませてあります。~/work/SuperCoolRepository/をghq管理下に引っ越したい場合は
$ GHQ_MIGRATOR_ACTUALLY_RUN=1 ghq-migrator.bash ~/work/SuperCoolRepository
と実行すると、シェルスクリプトがgit remoteを頑張って読んでいい感じにmvしてくれます。
頭のGHQ_MIGRATOR_ACTUALLY_RUN=1がないとdry-runになるので、いきなり実行する前に一度dry-runするとやや安全です。
また、デフォルトだとgit remoteが複数設定されている場合は引越しを行わないのですが、これまた環境変数でGHQ_MIGRATOR_PREFER_ORIGIN=1を指定しておくとoriginのurlに合わせたディレクトリに勝手に移動してくれます。(originに複数urlが設定されていた場合のハンドリングは諦めています。諦めて手で動かしてください…)
urlを切り貼りするのに一部はsedを使いましたが、簡単な文字列の加工にはbashの変数の特殊展開を使っています。今回初めて知ったけど便利、ただしリファレンス毎回読まないとわからんという感想でした。以下のエントリにお世話になりました。
ghq-migratorを使った引越し
わたしの手元では、以下のように雑に~/work/以下を全部migratorにかけ、残ったリポジトリは必要に応じてGHQ_MIGRATOR_PREFER_ORIGIN=1を指定して走らせ直したり諦めて手で動かすなどしました。
$ export GHQ_MIGRATOR_ACTUALLY_RUN=1
$ cd ~/work; ls | xargs -I{} ~/hobby/ghq-migrator/ghq-migrator.bash {}
$ ls -l
(残ったディレクトリを眺める)
$ GHQ_MIGRATOR_PREFER_ORIGIN=1 ~/hobby/ghq-migrator/ghq-migrator.bash ./(originのurlに移して問題無さそうなリポジトリ)/移動しきれなかった一部は手で動かすなどしましたが、手元に転がしていたリポジトリの大半がghq管理下に移行できたため、安心して今日もrepoと一発打って作業ディレクトリへと移動しています。