Split large function into smaller ones
Split former `parse_git_status` function, which was around 60 lines of code, into multiple small functions. Also, instead of polluting the global namespace with a lot of variables, make functions return something through a $REPLY variable. Or the $STATUS variable, in the case of the *new* parse_git_status function.
This commit is contained in:
parent
208cfc43ee
commit
70cec22db5
|
@ -1,103 +1,130 @@
|
|||
#!/usr/bin/zsh
|
||||
|
||||
###
|
||||
# Unset global variables
|
||||
# Globals: all
|
||||
# Arguments: none
|
||||
###
|
||||
function sanitize() {
|
||||
unset GIT_CURRENT_BRANCH GIT_STATUS
|
||||
unset GIT_STAGED GIT_MODIFIED GIT_UNTRACKED GIT_DELETED
|
||||
unset GIT_COMMITS_BEHIND GIT_COMMITS_AHEAD GIT_COMMITS_STATUS
|
||||
git rev-parse --git-dir &>/dev/null || return 1
|
||||
function main() {
|
||||
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" ]] \
|
||||
&& get_differences_between_remote_and_local \
|
||||
&& local remote_local_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+="$local_remote_diffs"
|
||||
output+="$modified"
|
||||
output+="$staged"
|
||||
output+="$deleted"
|
||||
output+="$untracked"
|
||||
output+=$'\e[0m'
|
||||
|
||||
sed 's/[ ]+$//' <<<"$output" # remove trailing whitespace
|
||||
}
|
||||
|
||||
###
|
||||
# Get necessary information from git, like current branch, amount of modified
|
||||
# files etc. to then put them all into a global variable, GIT_STATUS
|
||||
# Check if we're in a git repository
|
||||
# Globals: none
|
||||
# Arguments: none
|
||||
###
|
||||
function parse_git_status() {
|
||||
local modified_files=0 staged_files=0 untracked_files=0 deleted_files=0
|
||||
local git_has_changes=0
|
||||
GIT_CURRENT_BRANCH="$(git branch --show-current)"
|
||||
function is_in_git_repository()
|
||||
{
|
||||
git rev-parse --git-dir &>/dev/null || return 1
|
||||
}
|
||||
|
||||
function git_grab_current_branch()
|
||||
{
|
||||
typeset -g REPLY="$(git branch --show-current)"
|
||||
}
|
||||
|
||||
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 commit
|
||||
# Globals: none
|
||||
# Arguments: none
|
||||
###
|
||||
function parse_git_status()
|
||||
{
|
||||
git status --porcelain=v1 | while IFS= read -r status_line; do
|
||||
git_has_changes=1
|
||||
case "$status_line" in
|
||||
' M '*)
|
||||
((modified_files++))
|
||||
((modified++))
|
||||
;;
|
||||
'A '*|'M '*)
|
||||
((staged_files++))
|
||||
((staged++))
|
||||
;;
|
||||
' D '*)
|
||||
((deleted_files++))
|
||||
((deleted++))
|
||||
;;
|
||||
'?? '*)
|
||||
((untracked_files++))
|
||||
((untracked++))
|
||||
;;
|
||||
'MM '*)
|
||||
((staged_files++))
|
||||
((modified_files++))
|
||||
((staged++))
|
||||
((modified++))
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
GIT_REMOTE_BRANCH=$(git for-each-ref --format='%(upstream:short)' "$(git symbolic-ref -q HEAD)")
|
||||
local ahead_behind_status commits_behind commits_ahead
|
||||
if [[ ! -z ${GIT_REMOTE_BRANCH} ]]; then
|
||||
local ahead_behind_status=$(git rev-list --left-right --count \
|
||||
${GIT_CURRENT_BRANCH}...${GIT_REMOTE_BRANCH})
|
||||
local commits_ahead=$(echo -n "$ahead_behind_status" | awk '{print $1}')
|
||||
local commits_behind=$(echo -n "$ahead_behind_status" | awk '{print $2}')
|
||||
|
||||
(( ${commits_behind} > 0 )) \
|
||||
&& GIT_COMMITS_BEHIND="↓${commits_behind} " \
|
||||
&& git_has_changes=1
|
||||
(( ${commits_ahead} > 0 )) \
|
||||
&& GIT_COMMITS_AHEAD="↑${commits_ahead} " \
|
||||
&& git_has_changes=1
|
||||
fi
|
||||
GIT_COMMITS_STATUS="${GIT_COMMITS_AHEAD}${GIT_COMMITS_BEHIND}"
|
||||
|
||||
if (( $git_has_changes )); then
|
||||
(( ${staged_files} > 0 )) \
|
||||
&& GIT_STAGED="+${staged_files} "
|
||||
(( ${modified_files} > 0 )) \
|
||||
&& GIT_MODIFIED="!${modified_files} "
|
||||
(( ${deleted_files} > 0 )) \
|
||||
&& GIT_DELETED="-${deleted_files} "
|
||||
(( ${untracked_files} > 0 )) \
|
||||
&& GIT_UNTRACKED="?${untracked_files}"
|
||||
local fg_special=$'\e[0;33m'
|
||||
else
|
||||
local fg_special=$'\e[01;32m'
|
||||
fi
|
||||
|
||||
GIT_STATUS="${fg_special}"
|
||||
GIT_STATUS+=" ${GIT_CURRENT_BRANCH} "
|
||||
GIT_STATUS+="${GIT_COMMITS_STATUS}"
|
||||
GIT_STATUS+="${GIT_MODIFIED}${GIT_STAGED}"
|
||||
GIT_STATUS+="${GIT_DELETED}${GIT_UNTRACKED}"
|
||||
GIT_STATUS+=$'\e[0m'
|
||||
|
||||
# Remove trailing whitespace
|
||||
GIT_STATUS="$(sed 's/[ ]+$//' <<<"$GIT_STATUS")"
|
||||
typeset -g STATUS=("$modified" "$staged" "$deleted" "$untracked")
|
||||
return 0
|
||||
}
|
||||
|
||||
###
|
||||
# Control script from here
|
||||
# Globals:
|
||||
# none
|
||||
# Arguments:
|
||||
# none
|
||||
###
|
||||
function main() {
|
||||
sanitize || return 1
|
||||
function get_differences_between_remote_and_local()
|
||||
{
|
||||
local local_branch="$1"
|
||||
local remote_branch="$2"
|
||||
|
||||
parse_git_status
|
||||
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}')
|
||||
|
||||
(( $commits_ahead > 0 )) \
|
||||
&& local ahead="↑$commits_ahead"
|
||||
(( $commits_behind > 0 )) \
|
||||
&& local behind="↓$commits_behind"
|
||||
|
||||
typeset -g REPLY="$ahead $behind"
|
||||
return 0
|
||||
}
|
||||
|
||||
function git_determine_color()
|
||||
{
|
||||
for i in "$@"; do
|
||||
if (( $i > 0 )); then
|
||||
typeset -g REPLY=$'\e[93m'
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
typeset -g REPLY=$'\e[92m'
|
||||
return 0
|
||||
}
|
||||
|
||||
main
|
||||
|
|
Loading…
Reference in New Issue