Gitを使っていて最も面倒なことのひとつはファイル名の入力だと思います。
git add
する前にgit status
をしてファイル名を確認し、ファイル名をコピー&ペーストしてgit add
する。場合によっては先にgit diff
で差分を確認したりします。
できればもっとスマートにやりたいものです。そこでインクリメンタルサーチの代名詞であるfzf
を使ってちょっとしたツールを作ってみました。下記のデモをご覧ください。
デモからおわかりいただけると思いますが、git status
の結果を候補にfzf
を実行しています。ついでに右側には選んでいるファイルの差分が出ます。
まだ個人的に使っている段階ですが、とても便利なのでぜひ使っていただければと思います。もしバグを見つけたらPRを投げていただければ幸いです。
以降は少しfzf-git
の仕組み的な話をしてみたいと思います。
fzf-git
は仕組みとしてはとても単純で、git status --short
の結果をfzf
にパイプしているだけです。
ソースコードは今のところ50行ほどの1ファイルのみで、その大半を文字列マッチのためのAwkスクリプトが占めています。
このAwkスクリプトの役割は2つあります。ひとつはカラーコード込みのマッチングを頑張ること、もうひとつはGitのワーキングディレクトリとステージングエリアの両方に同時に存在するファイルの扱いです。
前者は調べると(カラーコードだけに)色々情報が出てくるので特に説明はしません。
後者のGitファイルの扱いについて少し説明します。
Gitのワーキングディレクトリとステージングエリアの両方に同じファイルが存在するとき、git status --short
の結果は次のようになります。
$ git status --short
MM foo.txt
M
はmodifiedを表しており、MM
の1文字目がステージングエリア、2文字目がワーキングディレクトリを表しています。
ステージングエリアにあるファイルとワーキングディレクトリにあるファイルとではgit diff
コマンドのオプションが異なります。つまり、ワーキングディレクトリの差分は単にgit diff <file>
となるのに対し、ステージングエリアの差分はgit diff --staged <file>
となります。
ですのでMM foo.txt
を下記のように2行に分解してあげる必要があります。
M foo.txt
M foo.txt
こうしておけば、1文字目がM
のファイルに対してはgit diff --staged <file>
で、2文字目がM
のファイルに対してはgit diff <file>
で差分を表示できるようになります。
awk { print $2 }
とすればファイル名foo.txt
が取得できます。
将来的にはUntrackedなファイルも色付きで差分を表示できたら良いなとは思っています(cat
だと味気ない)。
以上です。
このエントリではGit管理ファイルをインクリメンタルサーチできるzshウィジェットfzf-git
を紹介しました。
fzf-git
を作るにあたって下記エントリをたいへん参考にさせていただきました。ありがとうございます。
コメントを送る
コメントはブログオーナーのみ閲覧できます