「git bash PS1」とか「git commit 忘れる」とかで検索している君!!
なにはともあれ、このBashプロンプトを見てくれ!!どうだい、クールだろ?1
「Git Bash ブランチ」とか「Git Stash Bash」とかでググると、断片的な情報が山ほど出てくる。だがこのBashプロンプトは完全版だ。私や君に必要な機能は全て備わっている。
また、後述するようにこのプロンプトでは未コミットのファイルがあると警告を表示できる。世の中には git-remindというツールがあるらしいが、このBashプロンプトを使う限りgit-remind の出番はないだろう。
機能
現在のブランチ名が表示されるから、master にコミットしちまうなんてポカは起きえない。ついでに、まれによく使うHEAD
の現在のコミットIDも表示している。
また、
- 未コミットのファイル
- ファイルに変更
- stageされたファイルあり
- stashあり
といった状態も表示されるから、いちいち git
を実行しなくてもいい。
git stash list
なんてもう何年も使っていない。
ついでに、個人的な好みで時刻や前回の終了コードなんかも表示している。
どうだい、お前さんも使ってみたいだろう?
イカシたプロンプトを出すコマンド
クールなBashプロンプトのGitの情報を表示するには以下のスクリプトを使えば良い。~/bin/git-ps
とでもいう名前で保存して、実行権限をつけてくれ。
#!/bin/bash
set -euC
C() {
case $1 in
black) echo -e -n "\033[1;30m";;
red) echo -e -n "\033[1;31m";;
green) echo -e -n "\033[1;32m";;
yellow) echo -e -n "\033[1;33m";;
blue) echo -e -n "\033[1;34m";;
magenta) echo -e -n "\033[1;35m";;
cyan) echo -e -n "\033[1;36m";;
white) echo -e -n "\033[1;37m";;
*) echo -e -n "\033[0m";;
esac
}
status() {
local modified=0
local cached=0
local untracked=0
while read -r line; do
if [ "$line" = '_?_?_' ]; then
untracked=1
continue
fi
if [[ "$line" =~ ^_[^[:space:]]_.?_ ]]; then
cached=1
fi
if [[ "$line" =~ ^_._[^[:space:]]_ ]]; then
modified=1
fi
done < <(git status --short | cut -b -2 | sed -e 's/\(.\)\(.*\)/_\1_\2_/')
if [ $modified -ne 0 ]; then
C red
echo -n 'M'
fi
if [ $cached -ne 0 ]; then
C green
echo -n 'C'
fi
if [ $untracked -ne 0 ]; then
C red
echo -n '?'
fi
if [ -n "$(git stash list)" ]; then
C cyan
echo -n 'S'
fi
C reset
}
branch() {
local branch
branch="$(git branch 2>/dev/null | grep '^\*' | sed -e "s/^* //")"
if [[ "${branch}" =~ ^bug- ]]; then
C green
elif [[ "${branch}" =~ ^atc- ]]; then
C cyan
elif [[ "${branch}" =~ ^tmp ]]; then
C magenta
elif [[ "${branch}" = "(detached from hde/master)" ]]; then
C yellow
else
C white
fi
echo -n "${branch}"
C reset
}
hash() {
git log --pretty=format:'%h' -n 1
}
git_ps() {
if ! git status --ignore-submodules &>/dev/null; then
return
fi
echo "git[$(status)]=$(branch):$(hash)"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
git_ps
fi
プロンプトの設定方法
Bashのプロンプトは、環境変数 PS1
によって設定可能だ。
単にデフォルトのプロンプトにGitの情報を追加したいだけなら、~/.bashrc
に
export PS1='$(git-ps)\n[\u@\h \W]\\$ '
なんて定義を追加すればOKだ。
PS1
には「\u
でユーザー名」など、特殊文字が使えるが bashのプロンプトを変更するには - @IT などに一覧表がある。
また、PS1
はプロンプト表示毎に評価されるから、全体をダブルクオート"
ではなく '
で囲むことに注意だ。
ちなみに、こっちは私が普段使っている、完全版のPS1だ。Gitの他に、RailsやJava、Scala、たまに使うSVNなどのためのコードも含んでいる。
あとは自由にカスタマイズしてくれ!
#!/bin/bash
# PS1の設定
C() {
case $1 in
black) echo -e -n "\033[1;30m";;
red) echo -e -n "\033[1;31m";;
green) echo -e -n "\033[1;32m";;
yellow) echo -e -n "\033[1;33m";;
blue) echo -e -n "\033[1;34m";;
magenta) echo -e -n "\033[1;35m";;
cyan) echo -e -n "\033[1;36m";;
white) echo -e -n "\033[1;37m";;
*) echo -e -n "\033[0m";;
esac
}
ps1_svn() {
if ! svn info &> /dev/null; then
return
fi
echo -n ' svn'
}
ps1_rails() {
if [ -z "${RAILS_ENV-}" ]; then
return
fi
echo -n " RAILS_ENV=$(C white)$RAILS_ENV$(C reset)"
}
ps1_play() {
if [ -z "${PLAY_ENV-}" ]; then
return
fi
echo -n " PLAY_ENV=$(C white)$PLAY_ENV$(C reset)"
}
ps1_skinny() {
if [ -z "${SKINNY_ENV-}" ]; then
return
fi
echo -n " SKINNY_ENV=$(C white)$SKINNY_ENV$(C reset)"
}
ps1_login() {
echo -n "${USER}@"
echo -n -e "$(C "cyan")$(hostname -s)$(C reset)"
}
ps1_date() {
date +'%F %H:%M:%S'
}
ps1_exit_status() {
local END_CODE=$1
echo -n ' $?='
if [ 0 -ne "${END_CODE}" ]; then
echo -n "$(C red)${END_CODE}$(C reset)"
else
echo -n 0
fi
}
ps1_git() {
if ! git status --ignore-submodules &>/dev/null; then
return
fi
echo -n ' '
git-ps
}
ps1_java() {
if [ -n "${JAVA_HOME}" ]; then
local version
version=$(java -version |& head -1 | cut -d ' ' -f 3 | tr -d '"')
echo -n " java=$(C white)${version}$(C reset)"
fi
}
ps1_docker() {
if [ -z "${DOCKER_MACHINE_NAME}" ]; then
return
fi
local docker_host_ip
docker_host_ip="${DOCKER_HOST/tcp:\/\//}"
docker_host_ip="${docker_host_ip/:*/}"
echo -n " docker=[${docker_host_ip}]"
if [ -n "${COMPOSE_FILE}" ]; then
echo -n ","
echo -n docker-compose.qa-hosted.yml | sed -e 's/^docker-compose.//' -e 's/.yml$//'
fi
}
ps1_prompt() {
if [ "$(id -u)" -eq 0 ]; then
echo -n "$(C red)# $(C reset)"
else
echo -n "$(C "${HOST_COLOR}")$ $(C reset)"
fi
}
ps1_path() {
echo " $(pwd | sed -e "s|^${HOME%/}|~|")"
}
function ps1_info() {
local END_CODE=$?
echo "$(ps1_login)$(ps1_exit_status "$END_CODE")$(ps1_git)$(ps1_svn)$(ps1_rails)$(ps1_skinny)$(ps1_play)$(ps1_java)$(ps1_docker)"
echo "$(ps1_date)$(ps1_path)"
}
PS1='$(ps1_info)'
# カーソル位置がずれる問題を回避するため、ここの部分だけは文字列連結にする
if [ "$(id -u)" -eq 0 ]; then
PS1="${PS1}\n\[$(C red)\]#\[$(red)\] " # rootの場合はシャープ
else
PS1="${PS1}\n\[$(C cyan)\]\$\[$(C reset)\] " # 非rootユーザの場合はドル
fi
export PS1
なお、私はサーバーで Bash を使用している関係上、開発用PCでも Bash を使用しています。Zsh や Fish などを使用されている方は適当に読み替えてください。
-
ついカッとなり、いささかお見苦しい表現の記事となっておりますが、ご笑覧いただければ幸いです。 ↩