mizdra's blog

ぽよぐらみんぐ

ghq+peco とゴミ置き場

ghq は、git clone したリポジトリを特定のディレクトリ規則に従って管理するコマンドです。そして peco は、インクリメンタル検索をするコマンドです。この 2 つを組み合わせると、git clone したリポジトリを簡単に cd できます。

# ~/.gitconfig
[ghq]
    root = ~/src
# ~/.zshrc
function peco-src() {
  local selected_dir=$(ghq list | peco --query "$LBUFFER")
  if [[ -n "$selected_dir" ]]; then
    BUFFER="cd $(ghq root)/$selected_dir"
    zle accept-line
  fi
  zle redisplay
}
zle -N peco-src
stty stop undef # disable builtin "^s" keybind
bindkey '^s' peco-src

ghq+peco でディレクトリを切り替える様子。

数多くのブログで紹介されている有名なテクニックですので、使っている人も多いでしょう。使ってない人は是非使ってみて下さい。

ゴミ置き場

ghq+peco により、バージョン管理システム (VCS) で管理されるリポジトリを整理できる訳ですが、現実には VCS で管理されないものも扱いたくなります。例えば、ライブラリの動作確認のためのリポジトリや、ライブラリの不具合を再現するためのリポジトリとかです。ちょっとしたコードは書きたいけど、わざわざ git 管理するほどでもない、みたいなやつです。

そうしたリポジトリを管理するため、id:mizdra~/src/localhost/gomi ディレクトリを作ってます。

~/src
├── github.com
│   ├── x-motemen
│   │   └── repository-1
│   └── mizdra
│        ├── repository-1
│        └── repository-2
└── localhost
     └── gomi
          ├── repository-1
          └── repository-2

ゴミ置き場なので gomi です。直球ですね。

気軽に ~/src/localhost/gomi に移動できるよう、zsh で auto_cd と名前付きディレクトリを設定しています。これで ~gomi と打つだけで移動できます *1

# ~/.zshrc
setopt auto_cd
hash -d gomi=~/src/localhost/gomi

VCS 管理しないものは ~gomi に置いていき、不定期に rm -rf ~gomi/* で削除しています。もし何らかの事情で ~gomi に置いたものを VCS 管理したくなったら、git push => rm ~gomi/repo => ghq get ... で ghq 管理のディレクトリへと移動する運用にしてます。

~gomi と ghq+peco の相性問題

~gomi は便利ではあるのですが、冒頭で紹介した ghq+peco を使ったディレクトリ移動のテクニックと組み合わせると、ちょっとした問題が起きます。~gomi にあるリポジトリが一覧されないのです。

~gomi 配下にリポジトリがあるが、ghq+peco によるリポジトリ切り替えの候補にそれが表示されない様子。

これは、リポジトリの一覧を取得するコマンドに ghq list を使用していることが原因です。ghq list は VCS 管理されているディレクトリしか返してくれないのです。ghq は VCS 管理されるリポジトリを整理するためのコマンドなので、自然な挙動ではあります。

とはいえ、~gomi のようなディレクトリを作っている身としては困ります。そこで id:mizdrafind $(ghq root) -mindepth 3 -maxdepth 3 -type d でリポジトリの一覧を取得しています。

# ~/.zshrc
function peco-src() {
  local ghq_root="$(ghq root)"
  local selected_dir=$(find $ghq_root -mindepth 3 -maxdepth 3 -type d | sed "s|$ghq_root/||" | peco --query "$LBUFFER")
  if [[ -n "$selected_dir" ]]; then
    BUFFER="cd $ghq_root/$selected_dir"
    zle accept-line
  fi
  zle redisplay
}
zle -N peco-src
stty stop undef # disable builtin "^s" keybind
bindkey '^s' peco-src

これで、ghq+peco によるリポジトリ切り替えの候補に ~gomi 配下のものが表示されます。

ちょっとした注意点

今回紹介したスクリプトは、https://<domain>/subpath/<org>/<repo>.git というサブパス付き URLを持ち、~/src/<domain>/subpath/<org>/<repo> に配置されるリポジトリには対応してません。-mindepth 3 -maxdepth 3 で深さ 3 にあるディレクトリを抽出してるからです。

サブパスを URL に含むリポジトリなんてそう滅多にないので、ほとんどの場合は問題ないはず...。どうしてもサブパスを URL に含むリポジトリを扱いたい人は、ghq listfind $ghq_root/localhost -mindepth 3 -maxdepth 3 -type d を組み合わせてみてください。ghq list はサブパスを持つディレクトリに対応してるので、それで問題を回避できるはずです。

*1:https://pocke.hatenablog.com/entry/2014/07/23/173811 も合わせて読むと面白いでしょう

ポケットモンスター・ポケモン・Pokémon・は任天堂・クリーチャーズ・ゲームフリークの登録商標です.

当ブログは @mizdra 個人により運営されており, 株式会社ポケモン及びその関連会社とは一切関係ありません.