指定したディレクトリ配下のgitリポジトリを再帰的にpullする

久しぶりの更新になってしまった…

rbenvやpyenvなど、いわゆる**env系のツールを常用しているのですが、これらのツールツールそのものも、プラグインもgitでインストールを行います。
すると、以下のようなディレクトリ構成になります。

$HOME/.rbenv
├ .git/
├ rbenv本体
├ ...
└ plugins/
  ├ rbenv-rehash
  ├ ...
  └ ruby-build
    ├ .git/
    ├ ruby-build本体

例えば、新しいバージョンのRubyがリリースされたので、ruby-buildの更新を行いたい、ついでにrbenv配下のプラグイン群も更新したいと思うと、それぞれのディレクトリ(.gitディレクトリがあるところ)にcdで移動してgit pullを実行しないといけません。

そこで、指定したディレクトリ配下のgitリポジトリにcdしてgit pullするスクリプトを書いて、.zshrcに登録してみました。名前はgitpull-rにした。

# 指定したディレクトリ配下を再帰的にgit pullする
function gitpull-r(){
    if [ $# -ne 1 ]; then
        echo "gitpull-r <directory>"
        return
    fi
    
    cdir=`pwd`
    
    destdir=`ruby -e 'puts File.expand_path("#{ARGV[0]}")' $1`
    
    for gitdir in `find $destdir -name ".git" | sed -e s/\.git$//g`
    do
        echo "== git pull results [$gitdir] =="
        cd $gitdir
        git pull
    done
    
    cd $cdir
}

動くけど、指定したディレクトリを絶対パスに変換するところをRubyワンライナーにしているところが気に入らない…。realpathってコマンドもあるらしいけど、デフォルトでは入っていないことが多いようなので、自分の開発環境なら間違いなく入っているRubyワンライナーにしました。

実行スクリプトの絶対パスを得る方法ならあるけど、コマンドライン引数に渡したパスを絶対パスに変換する方法を思いつかなかったので、手っ取り早くRubyの力を借りました。何かいい方法があるのかな。

ちなみに、git submoduleってのもあるらしいけど、あくまでgitリポジトリ間の依存関係を定義するためのもので、複数のリポジトリをまとめて最新にしたいみたいな用途で使うものではなさそう。