LoginSignup
27

More than 5 years have passed since last update.

gitのdiff, addをfzf でインタラクティブに

Posted at

こんな感じです。

out.gif

概要

Git管理下で作業していると開発に夢中になって、気付いたらワーキングディレクトリがたくさんのファイルで溢れている!
という状況にしばしば陥るときはありませんか?
ここで思い出すんです。。。
(commitの粒度は小さくしないと怒られる!!)
そこで僕はいつも git diff で差分見て、良い感じに git add して git commit しているんですけど、
これがまた面倒臭い作業でして、もっと楽にできないのか!と思い、fzfで選択的対話的にdiff addできるスクリプトを書きました。
(注:そうなる前に都度コミットするように気を付けましょう)

環境

  • Mac OSX El Capitan 10.11.5
  • Zsh 5.2
  • fzf

fzfは選択的インターフェースで曖昧検索ができるコマンドです。

スクリプト

.zshrc
fadd() {
  local out q n addfiles
  while out=$(
      git status --short |
      awk '{if (substr($0,2,1) !~ / /) print $2}' |
      fzf-tmux --multi --exit-0 --expect=ctrl-d); do
    q=$(head -1 <<< "$out")
    n=$[$(wc -l <<< "$out") - 1]
    addfiles=(`echo $(tail "-$n" <<< "$out")`)
    [[ -z "$addfiles" ]] && continue
    if [ "$q" = ctrl-d ]; then
      git diff --color=always $addfiles | less -R
    else
      git add $addfiles
    fi
  done
}

ざっくり言うと
git statusunstaged or untrackedなものを fzf に渡して

  • Ctrl-ddiff
  • Enteradd

しています。

シェルスクリプト初心者なので間違いがあるかもしれませんが、一応ソースコードを追って説明します。

ローカル変数

  • out (fzfからの出力)
  • q (コマンド)
  • n (複数選択の場合のファイル数)
  • addfiles (実際にaddするファイル)

git status --short

これは [XY] [path] という形式で、
Xがステージされたもので、Yがステージされていないものです。

$ git status --short
 M .vimrc       # modifiedでunstaged
M  .zshrc       # modifiedでstaged
?? newfile      # untracked
A  sample.rb    # new fileでstaged

わかりにくいですね^^;
他にもあるので詳しくはGitのdocsを見て下さい。

awk

awk '{if (substr($0,2,1) !~ / /) print $2}'
先程のgit status --shortから1行ずつ受取り、
status[XY]のうち、Yがブランクでないという条件で、unstaged, untrackedなファイルを判別し、
2列目(ファイルパス)をfzfに渡します。

fzf

--expectオプションで、ファイル選択のデフォルトキーであるEnterの代わりにCtrl-dで選択可能にしています。
そして、ローカル変数 out に コマンド、ファイル、、、、(--multiによりCtrl-iで複数選択可)と格納されます。

あとは、qにコマンドを(Ctrl-d or Enter)
nにファイル数を
addfilesにファイルを入れて

Ctrl-d -> git diff
Enter -> git add

としています。

最後の方雑になってしまいました。。。
何か、問題点や改善点がありましたらコメントして頂けると幸いです!!

githubでdotfiles管理しているので宜しければご覧になってください^^
https://github.com/yuuuuuki/dotfiles

参考

Browsing git commits with fzf

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27