gitstatus/gitstatus.plugin.zsh
xylous 8029f58990 Fix branch name spacing
On branches tracking remotes, there would be two spaces between the last
character and the first character in the status part. On other branches,
there'd only be one. Make it so that there's only one space at all
times.

In the function calculating differences between local and remote
histories, an extra space was added before the first part, thus where
the second space came from. Remove that.
2021-09-17 20:21:28 +03:00

154 lines
3.6 KiB
Bash
Executable File

function gitstatus()
{
is_in_git_repository || return 1
parse_git_status
local modified="${STATUS[1]}"
local staged="${STATUS[2]}"
local deleted="${STATUS[3]}"
local untracked="${STATUS[4]}"
unset STATUS
git_grab_current_branch
local branch="$REPLY"
git_grab_remote_branch
local remote="$REPLY"
[[ ! -z "$remote" ]] \
&& git_local_remote_diffs "$branch" "$remote" \
&& local commit_diffs="$REPLY"
git_determine_color $modified $staged $deleted $untracked
local color="$REPLY"
(( modified > 0 )) \
&& modified="!$modified "
(( staged > 0 )) \
&& staged="+$staged "
(( deleted > 0 )) \
&& deleted="-$deleted "
(( untracked > 0 )) \
&& untracked="?$untracked "
local output="$color"
output+="$branch "
output+="$commit_diffs"
output+="$modified"
output+="$staged"
output+="$deleted"
output+="$untracked"
local true_output="$(sed 's/[ \t]*$//' <<<"$output")" # remove trailing whitespace
true_output+=$'%F{default}'
echo "${true_output}"
unset REPLY
}
###
# Check if we're in a git repository
# Arguments: none
# Returns: 0 if in a git repo, 1 otherwise
###
function is_in_git_repository()
{
git rev-parse --git-dir &>/dev/null || return 1
}
###
# Return current branch we're on
# Arguments: none
###
function git_grab_current_branch()
{
typeset -g REPLY="$(git branch --show-current)"
}
###
# Return remote branch that the local one is tracking
# Arguemnts: none
###
function git_grab_remote_branch()
{
local symbolic_ref="$(git symbolic-ref -q HEAD)"
typeset -g REPLY="$(git for-each-ref --format='%(upstream:short)' "$symbolic_ref")"
}
###
# Find how many things have changed since last git commit
# Arguments: none
###
function parse_git_status()
{
git status --porcelain=v1 | while IFS= read -r status_line; do
case "$status_line" in
' M '*)
((modified++))
;;
'A '*|'M '*)
((staged++))
;;
' D '*)
((deleted++))
;;
'?? '*)
((untracked++))
;;
'MM '*)
((staged++))
((modified++))
;;
esac
done
typeset -g STATUS=("$modified" "$staged" "$deleted" "$untracked")
return 0
}
###
# Look at how many commits a local branch is ahead/behind of remote branch
# Arguments: $1 local branch
# $2 remote branch
###
function git_local_remote_diffs()
{
local local_branch="$1"
local remote_branch="$2"
local differences="$(git rev-list --left-right --count $local_branch...$remote_branch)"
local commits_ahead=$(echo -n "$differences" | awk '{print $1}')
local commits_behind=$(echo -n "$differences" | awk '{print $2}')
local ahead="" behind=""
(( $commits_ahead > 0 )) \
&& ahead="$commits_ahead"
(( $commits_behind > 0 )) \
&& behind="$commits_behind"
if [[ ! -z "${ahead}" ]] || [[ ! -z "${behind}" ]]; then
typeset -g REPLY="$ahead $behind"
return 0
fi
return 1
}
###
# If there is anything that changed from the past commit, return yelllow color.
# Otherwise, green.
# Arguments: list of how many things changed
###
function git_determine_color()
{
local green=$'%F{yellow}'
local yellow=$'%F{green}'
for i in "$@"; do
if (( $i > 0 )); then
typeset -g REPLY="$green"
return 0
fi
done
typeset -g REPLY="$yellow"
return 0
}