From 0704670f8e73026fda3ee24dd85db125acc92fdc Mon Sep 17 00:00:00 2001 From: Alan Stebbens Date: Mon, 20 Jan 2014 17:00:24 -0800 Subject: [PATCH 1/4] aks: added gitstatus.sh, and configured it in gitprompt.sh --- README.md | 2 ++ gitprompt.sh | 12 +++++++- gitstatus.sh | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100755 gitstatus.sh diff --git a/README.md b/README.md index 0275a31..018ab20 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ The symbols are as follows: 2. If you want to tweak the colors, currently you have to tweak it in the ``gitprompt.sh`` 3. You can define ``prompt_callback`` function to tweak your prompt dynamicly +4. The current git repo information is obtained by the script `gitstatus.sh` or + `gitstatus.py`. Both scripts do the same thing. ```sh function prompt_callback { diff --git a/gitprompt.sh b/gitprompt.sh index 7d6cd3e..a87e04c 100644 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -81,7 +81,17 @@ function git_prompt_config() if [ "x$__GIT_STATUS_CMD" == "x" ] then git_prompt_dir - __GIT_STATUS_CMD="${__GIT_PROMPT_DIR}/gitstatus.py" + local sfx file + # look first for a '.sh' version, then use the python version + for sfx in sh py ; do + file="${__GIT_PROMPT_DIR}/gitstatus.$sfx" + if [[ -x "$file" ]]; then + __GIT_STATUS_CMD="$file" + break + fi + done + # The old way + #__GIT_STATUS_CMD="${__GIT_PROMPT_DIR}/gitstatus.py" fi } diff --git a/gitstatus.sh b/gitstatus.sh new file mode 100755 index 0000000..0561ee5 --- /dev/null +++ b/gitstatus.sh @@ -0,0 +1,86 @@ +#/bin/bash +# -*- coding: UTF-8 -*- + +# change those symbols to whatever you prefer +declare -a symbols +symbols['ahead']='↑·' +symbols['behind']='↓·' +symbols['prehash']=':' + +gitsym=`git symbolic-ref HEAD` + +# if "fatal: Not a git repo .., then exit +case "$gitsym" in fatal*) exit 0 ;; esac + +# the current branch is the tail end of the symbolic reference +branch="${gitsym##*/}" # get the basename after "refs/head/" + +tmp="/tmp/$$-gitstatus.out" +trap "rm -f \"$tmp\"" EXIT + +status=`git diff --name-status >$tmp` + +# if the diff is fatal, exit now +if grep -s "^fatal:" $tmp 2>/dev/null ; then + exit +fi + +# count_lines U +count_lines() { egrep -c "^$1" <$tmp ; } + +num_changed=$(( `wc -l <$tmp` - `count_lines U` )) + +staged_files=`git diff --staged --name-status >$tmp` +num_conflicts=`count_lines U` +num_staged=$(( `wc -l <$tmp` - num_conflicts )) +num_untracked=`git status -s -uall | grep -c "^??"` +num_stashed=`git stash list | wc -l` + +clean=0 +if (( num_changed == 0 && num_staged == 0 && num_U == 0 && num_untracked == 0 && num_stashed == 0 )) ; then + clean=1 +fi + +remote= + +if [[ -z "$branch" ]]; then + tag=`git describe --exact-match` + if [[ -n "$tag" ]]; then + branch="$tag" + else + branch="${symbols['prehash']}`git rev-parse --short HEAD`" + fi +else + remote_name=`git config branch.${branch}.remote` + if [[ -n "$remote_name" ]]; then + merge_name=`git config branch.${branch}.merge` + else + remote_name='origin' + merge_name="refs/heads/${branch}" + fi + if [[ "$remote_name" == '.' ]]; then + remote_ref="$merge_name" + else + remote_ref="refs/remotes/$remote_name/${merge_name##*/}" + fi + # get the revision list, and count the leading "<" and ">" + revgit=`git rev-list --left-right ${remote_ref}...HEAD >$tmp` + num_revs=`wc -l <$tmp` + num_ahead=`count_lines "^>"` + num_behind=$(( num_revs - num_ahead )) + if (( num_behind > 0 )) ; then + remote="${remote}${symbols['behind']}${num_behind}" + fi + if (( num_ahead > 0 )) ; then + remote="${remote}${symbols['ahead']}${num_ahead}" + fi +fi +if [[ -z "$remote" ]] ; then + remote='.' +fi + +for w in "$branch" "$remote" $num_staged $num_conflicts $num_changed $num_untracked $num_stashed $clean ; do + echo "$w" +done + +exit From 817bdf358485d2973ad261b844b7bc57ef304856 Mon Sep 17 00:00:00 2001 From: Alan Stebbens Date: Mon, 20 Jan 2014 17:00:24 -0800 Subject: [PATCH 2/4] aks: added gitstatus.sh, and configured it in gitprompt.sh --- README.md | 5 +++ gitprompt.sh | 12 ++++++- gitstatus.sh | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100755 gitstatus.sh diff --git a/README.md b/README.md index 0275a31..7647320 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ In particular the branch name, difference with remote branch, number of files st (an original idea from this [blog post][]). +`gitstatus.sh` added by [AKS](http://github.com/aks). + ## Examples The prompt may look like the following: @@ -56,6 +58,9 @@ The symbols are as follows: 2. If you want to tweak the colors, currently you have to tweak it in the ``gitprompt.sh`` 3. You can define ``prompt_callback`` function to tweak your prompt dynamicly +4. The current git repo information is obtained by the script `gitstatus.sh` or + `gitstatus.py`. Both scripts do the same thing, but the bash script is a tad + bit more quick, and is used by default. ```sh function prompt_callback { diff --git a/gitprompt.sh b/gitprompt.sh index 7d6cd3e..a87e04c 100644 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -81,7 +81,17 @@ function git_prompt_config() if [ "x$__GIT_STATUS_CMD" == "x" ] then git_prompt_dir - __GIT_STATUS_CMD="${__GIT_PROMPT_DIR}/gitstatus.py" + local sfx file + # look first for a '.sh' version, then use the python version + for sfx in sh py ; do + file="${__GIT_PROMPT_DIR}/gitstatus.$sfx" + if [[ -x "$file" ]]; then + __GIT_STATUS_CMD="$file" + break + fi + done + # The old way + #__GIT_STATUS_CMD="${__GIT_PROMPT_DIR}/gitstatus.py" fi } diff --git a/gitstatus.sh b/gitstatus.sh new file mode 100755 index 0000000..d290e07 --- /dev/null +++ b/gitstatus.sh @@ -0,0 +1,90 @@ +#/bin/bash +# -*- coding: UTF-8 -*- +# gitstatus.sh -- produce the current git repo status on STDOUT +# Functionally equivalent to 'gitstatus.py', but written in bash (not python). +# +# Alan K. Stebbens [http://github.com/aks] + +# change those symbols to whatever you prefer +declare -a symbols +symbols['ahead']='↑·' +symbols['behind']='↓·' +symbols['prehash']=':' + +gitsym=`git symbolic-ref HEAD` + +# if "fatal: Not a git repo .., then exit +case "$gitsym" in fatal*) exit 0 ;; esac + +# the current branch is the tail end of the symbolic reference +branch="${gitsym##*/}" # get the basename after "refs/head/" + +tmp="/tmp/$$-gitstatus.out" +trap "rm -f \"$tmp\"" EXIT + +status=`git diff --name-status >$tmp` + +# if the diff is fatal, exit now +if grep -s "^fatal:" $tmp 2>/dev/null ; then + exit +fi + +# count_lines U +count_lines() { egrep -c "^$1" <$tmp ; } + +num_changed=$(( `wc -l <$tmp` - `count_lines U` )) + +staged_files=`git diff --staged --name-status >$tmp` +num_conflicts=`count_lines U` +num_staged=$(( `wc -l <$tmp` - num_conflicts )) +num_untracked=`git status -s -uall | grep -c "^??"` +num_stashed=`git stash list | wc -l` + +clean=0 +if (( num_changed == 0 && num_staged == 0 && num_U == 0 && num_untracked == 0 && num_stashed == 0 )) ; then + clean=1 +fi + +remote= + +if [[ -z "$branch" ]]; then + tag=`git describe --exact-match` + if [[ -n "$tag" ]]; then + branch="$tag" + else + branch="${symbols['prehash']}`git rev-parse --short HEAD`" + fi +else + remote_name=`git config branch.${branch}.remote` + if [[ -n "$remote_name" ]]; then + merge_name=`git config branch.${branch}.merge` + else + remote_name='origin' + merge_name="refs/heads/${branch}" + fi + if [[ "$remote_name" == '.' ]]; then + remote_ref="$merge_name" + else + remote_ref="refs/remotes/$remote_name/${merge_name##*/}" + fi + # get the revision list, and count the leading "<" and ">" + revgit=`git rev-list --left-right ${remote_ref}...HEAD >$tmp` + num_revs=`wc -l <$tmp` + num_ahead=`count_lines "^>"` + num_behind=$(( num_revs - num_ahead )) + if (( num_behind > 0 )) ; then + remote="${remote}${symbols['behind']}${num_behind}" + fi + if (( num_ahead > 0 )) ; then + remote="${remote}${symbols['ahead']}${num_ahead}" + fi +fi +if [[ -z "$remote" ]] ; then + remote='.' +fi + +for w in "$branch" "$remote" $num_staged $num_conflicts $num_changed $num_untracked $num_stashed $clean ; do + echo "$w" +done + +exit From 3a97752a25e8057a1983a54a98995d68c8efee3c Mon Sep 17 00:00:00 2001 From: Alan Stebbens Date: Mon, 20 Jan 2014 17:26:12 -0800 Subject: [PATCH 3/4] aks: fixed order of config items --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7647320..25af1fd 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ The symbols are as follows: 1. You can use ``GIT_PROMPT_START`` and ``GIT_PROMPT_END`` to tweak your prompt 2. If you want to tweak the colors, currently you have to tweak it in the ``gitprompt.sh`` -3. You can define ``prompt_callback`` function to tweak your prompt dynamicly -4. The current git repo information is obtained by the script `gitstatus.sh` or +3. The current git repo information is obtained by the script `gitstatus.sh` or `gitstatus.py`. Both scripts do the same thing, but the bash script is a tad bit more quick, and is used by default. +4. You can define ``prompt_callback`` function to tweak your prompt dynamicaly ```sh function prompt_callback { From f60217ae2cefb06f1a16750c4e6d48b47abf4adf Mon Sep 17 00:00:00 2001 From: Alan Stebbens Date: Mon, 20 Jan 2014 17:53:43 -0800 Subject: [PATCH 4/4] aks: added Cyan as a color, and used it for untracked files. Updated README --- README.md | 9 +++++---- gitprompt.sh | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) mode change 100644 => 100755 gitprompt.sh diff --git a/README.md b/README.md index 25af1fd..794a2a4 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,12 @@ The symbols are as follows: ## Configuration 1. You can use ``GIT_PROMPT_START`` and ``GIT_PROMPT_END`` to tweak your prompt -2. If you want to tweak the colors, - currently you have to tweak it in the ``gitprompt.sh`` +2. If you want to tweak the colors, currently you have to tweak it in the + ``gitprompt.sh``. See the definitions of ``GIT_PROMPT_xxx1``, which include + various colors names. 3. The current git repo information is obtained by the script `gitstatus.sh` or - `gitstatus.py`. Both scripts do the same thing, but the bash script is a tad - bit more quick, and is used by default. + `gitstatus.py`. Both scripts do the same thing, but the bash script is a + tad bit more quick, and is used by default. 4. You can define ``prompt_callback`` function to tweak your prompt dynamicaly ```sh diff --git a/gitprompt.sh b/gitprompt.sh old mode 100644 new mode 100755 index a87e04c..de6fa98 --- a/gitprompt.sh +++ b/gitprompt.sh @@ -42,6 +42,7 @@ function git_prompt_config() local White='\[\033[37m\]' local Red="\[\033[0;31m\]" local Blue="\[\033[0;34m\]" + local Cyan="\[\033[0;36m\]" # Default values for the appearance of the prompt. Configure at will. GIT_PROMPT_PREFIX="[" @@ -52,8 +53,8 @@ function git_prompt_config() GIT_PROMPT_CONFLICTS="${Red}✖ " GIT_PROMPT_CHANGED="${Blue}✚ " GIT_PROMPT_REMOTE=" " - GIT_PROMPT_UNTRACKED="…" - GIT_PROMPT_STASHED="⚑ " + GIT_PROMPT_UNTRACKED="${Cyan}…" + GIT_PROMPT_STASHED="${BoldBlue}⚑ " GIT_PROMPT_CLEAN="${BoldGreen}✔" # Various variables you might want for your PS1 prompt instead