Edited at

git操作はGUIツール派な自分もCUIに乗り換えた便利git拡張まとめ

top.gif


はじめに

自分は「楽でわかりやすい」という理由から、git操作にはGUIツールのSourcetreeを使用していました。

ただ、GUIツールを使えない状況などではCUIに直接gitコマンドを入力するわけで、GUIツールの恩恵を得られないことも多々ありました。

そこでいっそのこと、GUIツールを真似てgitコマンドを拡張し、CUIに乗り換えることにしました。

本記事は、その際に作成した拡張のまとめになります。


目次(〇〇したいところ)

拡張を作成するにあたって、GUIツールと同じように「gitコマンドでも〇〇したい!」と思ったところをピックアップしました。

このピックアップ項目をもとに、gitコマンドを拡張していきます。

(なので、この項目が本記事の目次でもあります)

〇〇したいところ

1. branch一覧から選んでcheckoutしたい

2. 差分の内容をもっと見やすくしたい

3. 差分から選んでadd・resetしたい

4. stash一覧をもっと見やすくしたい

5. stash一覧から選んでapply・dropしたい

6. 現在のbranchのpushを楽にしたい


便利拡張を紹介する前に

gitコマンドを拡張するにあたって一つ、依存しているツールがあります。

それは、fzfpecoをはじめとするインタラクティブフィルターです。

インタラクティブフィルターとは、受け取ったリストを対話形式でユーザーに選択させ、それを出力する機能を持ったツールのことで、例えば、

git branch | fzf | xargs git checkout

とすれば、「branch一覧から一つ選んでcheckoutする」ということができるようになります。

fzf.gif

今回はこのインタラクティブフィルターのうち、曖昧検索とpreview機能があるfzfを使用しました。


便利拡張まとめ

gitコマンドを拡張するにあたって、本記事ではaliasで拡張しています。

ただ、aliasに記述する方式は少し制約もあったりするので、もし必要になればサブコマンド化も検討いただければと思います。


1. branch一覧から選んでcheckoutしたい


git co

co.gif

リモート含めたbranch一覧から一つ選んでcheckoutできるコマンドです。

GUIツールでは当然できることですが、gitコマンドで同じことをするには、複数のコマンドを駆使する必要があり面倒なため拡張しました。

やっていることは以下の通りです。


  • 引数がない場合、branch一覧をfzfに渡してリスト表示し、選択されればcheckoutする

  • 引数がある場合、特別な処理はせずgit checkout [引数]を実行する

[alias]

co = "!f() { args=$@; if [ -z \"$args\" ]; then branch=$(git branch --all | grep -v HEAD | fzf --preview 'echo {} | cut -c 3- | xargs git log --color=always' | cut -c 3-); git checkout $(echo $branch | sed 's#remotes/[^/]*/##'); else git checkout $args; fi }; f"


2. 差分の内容をもっと見やすくしたい


git d

d.gif

差分をファイルごとに切り替えながら確認できるコマンドです。

gitコマンドのgit diffは、


  • 差分がまとめて表示されるため、差分が大きいと見にくくなる

  • Untrackedなファイルが表示されない(git add -Nが必要)

と、個人的に少し使いづらかったため、Sourcetreeの作業コピーを参考に拡張しました。

diff.jpg

引数を指定すれば、commitやbranch間の差分もこの形式で確認でき、よく使うコマンドの一つになっています。

やっていることは以下の通りです。


  • 引数がない場合、git statusからUntrackedなファイルも含めた差分を取得し、それをfzfに渡してリスト表示


  • git d d1319bc2..37efebdbのように引数がある場合、git diff --name-statusから差分を取得し、それをfzfに渡してリスト表示

[alias]

d = "!f() { args=$@; [ -z \"$args\" ] && args=HEAD; ([ \"$args\" = \"HEAD\" ] && git status --short || git diff --name-status $args | sed 's/\t/ /') | fzf --preview \"echo {} | cut -c 4- | xargs git diff --color=always $args --\" --multi --height 90% | cut -c 4-; }; f"


3. 差分から選んでadd・resetしたい


git da

da.gif

上記の拡張コマンドgit dで表示されるリストから、差分ファイルを選んでaddできるコマンドです(Ctrl+iで複数選択)。

gitコマンドのgit addは、全差分が対象であれば問題ありませんが、差分を見ながら一部のファイルだけaddしたい場合に使いづらかったため拡張しました。

[alias]

da = !git d | xargs git add --


git dr

上記の拡張コマンドgit daのresetバージョンになります。

[alias]

dr = !git d | xargs git reset --


4. stash一覧をもっと見やすくしたい


git stl

stl.gif

stash一覧を変更内容も含めて確認できるコマンドです。

gitコマンドのgit stash list -pは、stash内容がまとめて表示されるため、stashの数が多くなると見にくくなるため拡張しました。

[alias]

stl = !git stash list | fzf --preview 'echo {} | grep -o stash@{.*} | xargs git stash show -p --color=always' --height 90% | grep -o stash@{.*}


5. stash一覧から選んでapply・dropしたい


git sta

sta.gif

上記の拡張コマンドgit stlで表示されるリストから、stashを選んでapplyできるコマンドです。

GUIツールのように、stashの内容を確認しながら目的のstashを探してapplyしたかったため、拡張しました。

[alias]

sta = !git stl | xargs git stash apply


git std

上記の拡張コマンドgit staのdropバージョンになります。

[alias]

std = !git stl | xargs git stash drop


6. 現在のbranchのpushを楽にしたい


git ps

現在のbranchをpushするコマンドです。

gitコマンドのgit pushは、リモートにbranchが存在しない状態でpushする際、引数でbranch名を指定する必要があります。

これが地味に面倒だったため、デフォルトで現在のbranchをpushするよう拡張しました。

[alias]

ps = "!f() { args=$@; [ -z \"$args\" ] && git push origin HEAD || git push $args; }; f"

または、

[push]

default = current


その他

拡張というわけではありませんが、できるだけ入力が少なくて済むように省略形をaliasに追加しています。

[alias]

b = branch
c = commit
cm = commit -m
f = fetch
s = status
st = stash
rh = reset --hard


これらの拡張を導入するには?

今回の拡張はaliasに追加しているため、自身の~/.gitconfigのaliasに追加すれば使用できるようになります。

また、自分のdotfilesリポジトリにて、これらの拡張をまとめた.gitconfigを公開しているため、参考にどうぞ。

https://gitlab.com/yukiarrr/dotfiles/blob/master/.gitconfig


まとめ

CUIに乗り換えた自分ですが、GUIツールはあらためて便利だと感じました。

特に差分の操作が素晴らしく、行単位でadd・reset・checkoutできたりします。

CUI上でもできるだけ便利にできるよう、今後も拡張を続けていきたいと思います。

Twitter: @yukiarrr