( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

一時的にブランチを切り替えてコマンドを実行するgit-switchっての作った話

gitで、一瞬だけ他のブランチに切り替えてコマンド実行したいときに毎回checkoutとかすんのタルいし、workspaceに変更があったらgit-nowしたりstashしたりしないとブランチ切り替えられなくてタルいので、一時的に他のブランチに切り替えて指定したコマンドを実行するラッパーを書いた。書いた。


dotfiles/bin/git-switch at master · yuroyoro/dotfiles · GitHub

git switch [--repository=<path>] [--new-workdir=<path>] <branch> <command...>


`git switch foo_master git show`ってやると、fooブランチに切り替えて`git show`を実行する。コマンドは別になんでもいいので、`git switch hogehoge rspec spec/hoge_spec.rb`のように、他のブランチでrspec流したり可能です。


以下は、一時的にcomposable_procに移動してgit show -sを実行した様子。

ozaki@mbp-4 ( ꒪⌓꒪) $ git br
  composable_proc
* trunk

ozaki@mbp-4 ( ꒪⌓꒪) $ git switch composable_proc git show -s
Already on 'composable_proc'
commit 20c1b806490233db0467ac4332ba073edca7889f
Author: Tomohito Ozaki <ozaki@yuroyoro.com>
Date:   Sun Mar 10 02:34:12 2013 +0900

    proc.c: Add Proc#flip


内部的に、git-new-workdirを使っているので、以下を参考にgit-new-workdirが使えるようにしておく必要があるです。

git-new-workdir が便利 - #生存戦略 、それは - subtech


デフォルトの動作では、/tmp以下に現在のリポジトリと同じディレクトリ名でgit-new-workdirして、そこでコマンドを実行するようになっている。すでにnew-workdirする先が存在する場合は再利用する。
workdirはオプション'--new-workdir='で変更可能だし。


注意点として、gitのコマンド実行とシグナルハンドラの関係上、シグナルをもらうプロセスがforkされるようなコマンドの実行には注意する必要がある。例えば、pryはCTRL-CによるSIGINTをtrapするが、fork元のgitプロセスはSIGINTでプロセスを終了する。そのため、git-switchではSIGINTをトラップして、forkしたコマンドの子プロセスを頑張ってぬっころすように実装している。このへんうまいことやる方法知りたい。