ghq + fzf で複数リポジトリ環境を快適にする(移動・pull・削除)
はじめに
複数の GitHub リポジトリを並行して触っていると、次のような困りごとが出がちです。
- 目的のリポジトリに移動するまでが面倒
- リポジトリが乱立する
- どこに clone したか忘れる
- 別リポジトリへの移動がめっちゃめんどくさい
この記事では、リポジトリ管理ツールの ghq と、対話型ファジーファインダーの fzf を組み合わせると、以下のようにターミナル上でGUI形式でリポジトリを選択させることができます。
さらに、そこから選択したリポジトリのディレクトリへ移動させたり、特定の処理を実行したりもできます。

複数のリポジトリ管理サービス、Organization、リポジトリを活用される方は特におすすめです。ではやっていきましょう。
インストール
試した環境
- VS Code: 1.108.2
- Ubuntu: 22.04
ghq のインストール
unzip のインストール
ghq のバイナリ(zip)を展開するため、まず unzip を入れます。
sudo apt update
sudo apt-get install unzip -y
which unzip
# /usr/bin/unzip
ghq のインストール(zip バイナリ)
GitHub Releases から ghq_linux_amd64.zip を取得し、展開したバイナリを /usr/local/bin/ に配置します。
# 例: ダウンロード済みの zip を展開
unzip ghq_linux_amd64.zip
# ghq を PATH の通った場所に配置
sudo mv ghq_linux_amd64/ghq /usr/local/bin/
# 動作確認
ghq --version
# ghq version 1.8.0 (rev:406c7dc)
# 後片付け(任意)
rm -rf ghq_linux_amd64 ghq_linux_amd64.zip
参考: ghq
fzf のインストール
Ubuntu では apt で導入できます。
sudo apt install fzf
which fzf
# /usr/bin/fzf
参考: fzf
実際に使ってみる
効果的に利用するための事前準備
ghq と fzf の役割はざっくり以下です。
- ghq: ローカルにあるリポジトリの一覧取得・ルートディレクトリ配下のパス解決
- fzf: ghqで取得したリポジトリを一覧化する UI の提供(プレビューも可能)
これらをシェルスクリプトとして組み合わせることで、ターミナル上で利用できる便利なコマンドを作り出すことができます。
まず、ghqコマンドでリポジトリの一覧を改めてクローンしておきます。
コマンドは以下の通りです。
ghq get <リモートリポジトリのURL.git>
このコマンドを実行すると、githubリポジトリの場合は ~/ghq/github.com配下に配置されます。
便利なコマンド一例(bash/zsh 関数)
ghqでリポジトリをローカルに整理して配置したうえで、コマンドを作っていきましょう。
以下は ~/.bashrc または ~/.zshrc に追記して使う想定です。
ちなみに、関数の名前は好きにカスタム可能ですので、自分の好みに合わせてカスタムしてみてください。
1) ghq & fzf でリポジトリに移動する(cd)
grg() {
local selected dir
# github.com/ を消して owner/repo のみ表示、プレビューあり
selected=$(ghq list | sed 's|^github.com/||' \
| fzf --height=40% --layout=reverse --border \
--preview 'ls -la "$(ghq root)/github.com/{}"')
# 何も選択されなかった場合は終了
[ -n "$selected" ] || return
# パス取得して移動
dir=$(ghq list -p "github.com/$selected")
[ -d "$dir" ] || return
cd "$dir" || return
}
2) ghq & fzf で選択したリポジトリで git pull する
cd せずに git -C を使う形にしておくと、カレントディレクトリを汚しません。
gpl() {
local selected dir
selected=$(ghq list | sed 's|^github.com/||' \
| fzf --height=40% --layout=reverse --border \
--preview 'ls -la "$(ghq root)/github.com/{}"')
[ -n "$selected" ] || return
dir=$(ghq list -p "github.com/$selected")
[ -d "$dir" ] || return
echo "Pulling $selected..."
git -C "$dir" pull
}
3) ghq & fzf で選択したリポジトリを削除(要注意)
この関数は ローカルディレクトリを rm -rf で削除します。
誤操作すると復元が大変なので、必ず確認プロンプトを入れてください。
gdl() {
local selected dir answer
selected=$(ghq list | sed 's|^github.com/||' \
| fzf --height=40% --layout=reverse --border \
--preview 'ls -la "$(ghq root)/github.com/{}"')
[ -n "$selected" ] || return
dir=$(ghq list -p "github.com/$selected")
[ -d "$dir" ] || return
echo "Delete $dir? (y/N): "
read -r answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
rm -rf -- "$dir"
echo "Deleted: $selected"
else
echo "Cancelled."
fi
}
まとめ
- ghq でローカルのリポジトリを一覧化・パス解決できるようにしておくと、リポジトリ数が増えても迷子になりにくい
- fzf を組み合わせると、一覧から目的のリポジトリを素早く選んで、そのまま処理(移動/pull/削除などの処理)ができる
ぜひ、使ってみてください。
Discussion