LoginSignup
9
17

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-11-18

経緯

最近忘れっぽいのか、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を叩くように手が覚えました^^ 

9
17
0

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
9
17