Bash
Git

git status, git stash list, git logを同時に出力するサブコマンドを作ったらすごい捗った話

More than 1 year has passed since last update.


経緯

最近忘れっぽいのか、stashしたままほっぽったり、pushするの忘れて帰ったりってことをよくしてしまいます。

特にstashなんかはたまにしか使わないため、git stash listして、保存したstashのリストをチェックする、なんて体が覚えてくれません。


そんなわけで……

git localinfo というサブコマンドを作ってみました。

実行すると、ローカルリポジトリでの変更内容が以下のようにコンパクトに出力されます。

shell_prompt.png

出力されるのは、


  • 現在のブランチ名(1行目のパスの末尾)

  • unstaged, stagedなファイルの一覧

  • stash一覧

  • 未pushのコミット一覧

です。何も変更がなければパス&ブランチ名も出力しません。

これを、git statusの代わりに叩くように癖をつけたら1、stashしたままほっぽったり、push忘れて帰ったり、ってことが無くなりました。


もうちょっと進んだ使い方

引数に、git loggit stash list の両方で有効なオプションを指定できます。--prettyで出力内容を調節したり、--name-statusで変更ファイル名も出力したりするのに使ってます。

shell_prompt.png

また、引数に複数のパスを指定することで、複数のローカルリポジトリの内容を出力できます。

git localinfo `ghq list -p`

とかすると全ての作業中の内容が表示されるので、複数のリポジトリを行ったり来たりしていてもpush漏れが無くなりました。


作成したもの

GitHubにも置いてますが、私のdotfilesの一部としてなので、ソースをそのまま貼っておきます。


git-localinfo

#!/bin/bash

function show_git_status() {
path=$1
shift
status=`
cd $path
if [ -n "$(git rev-parse --git-dir 2> /dev/null)" ]; then
git -c color.ui=always status -s;
git -c color.ui=always stash list --oneline --decorate $*;
git -c color.ui=always log --branches --not --remotes --oneline --graph --decorate $*
fi
`
if [ "$status" != "" ]; then
if
[ "$path" != "" ]; then
branch=`cd $path; git symbolic-ref --short HEAD`
echo -e "\e[92m$path\e[0m (\e[32m$branch\e[0m)"
fi
echo "$status"
fi
}

# parse options
declare -a argv=()
declare -a options=()
while [ $# -gt 0 ]; do
case
"$1" in
-*) options=("${options[@]}" "$1");;
*) argv=("${argv[@]}" "$1");;
esac
shift
done
if
[ ${#argv[@]} -eq 0 ]; then
argv=(`pwd`)
fi

# show git status
for path in ${argv[@]}; do
show_git_status $path ${options[@]}
done



知ったこと

このサブコマンドを作成する際に知ったオプションを紹介します。


-c color.ui=always

git status などを行った結果、出力があるかどうか(変更があるかどうか)を知るために、いったん変数に入れているのですが、そうすると色情報が出力されません。

git loggit status list--colorオプションで強制的に色情報を出力できるのですが、git statusには同様のオプションがないため、-cオプションを使用して一時的にconfigを切り替えています。


git log --not --remotes

リモートリポジトリ(の、origin)にpushしていないコミットのみを表示します。

--notを付け、次のオプションで指定しているコミットの意味を反転させることで表示しています。


終わりに

git log --help するといろいろなオプションがあるのがわかるから一度読むとよいよ。


2016-11-24 追記

ブランチ名の取得時にcdしていなくて、引数を指定していても常に現在のディレクトリのブランチ名を出力するようになってしまっていました。また、git管理下ではないディレクトリを指定して実行するとエラーメッセージが出てしまっていました。

これらを修正しましたので、使ってくれている方は以下のように修正をお願いします。

index 8cd58bb..eb014ea 100755

--- a/.myscript/bin/git-localinfo
+++ b/.myscript/bin/git-localinfo
@@ -5,15 +5,13 @@ function show_git_status() {
shift
status=`
cd $path
- if [ -n "$(git rev-parse --git-dir 2> /dev/null)" ]; then
- git -c color.ui=always status -s;
- git -c color.ui=always stash list --oneline --decorate $*;
- git -c color.ui=always log --branches --not --remotes --oneline --graph --decorate $*
- fi
+ git -c color.ui=always status -s;
+ git -c color.ui=always stash list --oneline --decorate $*;
+ git -c color.ui=always log --branches --not --remotes --oneline --graph --decorate $*
`
if [ "$status" != "" ]; then
if [ "$path" != "" ]; then
- branch=`cd $path; git symbolic-ref --short HEAD`
+ branch=`git symbolic-ref --short HEAD`
echo -e "\e[92m$path\e[0m (\e[32m$branch\e[0m)"
fi
echo "$status"





  1. 私は、alias gs="git localinfo"alias gsall='gs `ghq list -p`' を定義してます。何かするたびにgsを叩くように手が覚えました^^