Gitリポジトリをまとめて操作するコマンドを作る


カレントディレクトリ以下のGitリポジトリをまとめて操作するコマンドを作ってみた。

#!/bin/zsh

SILENT=0
if [[ $1 = "-s" ]]; then
    shift
    SILENT=1
fi

declare -a COMMAND=(git --no-pager $argv)
if [[ $1 = "!" ]]; then
    shift
    COMMAND=($argv)
fi

for D in $(find -L $PWD \( -name vendor -o -name node_modules \) -prune -o -type d -name .git -print -prune)
do
    cd $(dirname $D)
    [[ $SILENT = 0 ]] && echo -e "\e[37;44;1m${PWD}\e[m"
    $COMMAND[*]
done

使いかたは git-recursive pullgit-recursive status のように使う。 カレントディレクトリ以下のGitリポジトリで pull したり status が見れる。複数のリポジトリを操作した後に、 push し忘れてるとかを簡単に確認できる。また、 git-recursive ! ls のように ! を使うとGitのサブコマンド以外も実行できる。

色をつけたり -prune で打ち切って高速化していたりしている。元々は xargs でワンライナーにして Ctrl+r で引っ張りだしていたけど、拡張していくうちに複数行にした。並列化しても良いが status が意味不明になるのが嫌でやめた。並列化オプションとかつけても良いと思うけど面倒なので誰か頑張ってほしい。

使用例

# 全部の status
git-recursive status
# 全部 pull
git-recursive pull
# 全部の最後のログ
git-recursive log -n1
# node_modules 以外から git grep
git-recursive grep TODO -- ':!/node_modules/'
git-recursive grep "// TODO:" -- ':!/vendor/' 
# 全部で make
git-recursive ! make
# 全部のパスを表示(-s でリポジトリの場所の表示をやめる)
git-recursive -s ! pwd