gitstatus/gitstatus.plugin.zsh

104 lines
3.0 KiB
Bash
Raw Normal View History

2021-05-15 16:47:38 +03:00
#!/usr/bin/zsh
###
2021-05-15 17:34:41 +03:00
# Unset global variables
# Globals: all
# Arguments: none
2021-05-15 16:47:38 +03:00
###
function sanitize() {
2021-05-15 17:34:41 +03:00
unset GIT_CURRENT_BRANCH GIT_STATUS
unset GIT_STAGED GIT_MODIFIED GIT_UNTRACKED GIT_DELETED
2021-05-15 17:48:12 +03:00
unset GIT_COMMITS_BEHIND GIT_COMMITS_AHEAD GIT_COMMITS_STATUS
2021-05-15 17:34:41 +03:00
git rev-parse --git-dir &>/dev/null || return 1
2021-05-15 16:47:38 +03:00
}
###
# Get necessary information from git, like current branch, amount of modified
# files etc. to then put them all into a global variable, GIT_STATUS
2021-05-15 17:34:41 +03:00
# Globals: none
# Arguments: none
2021-05-15 16:47:38 +03:00
###
function parse_git_status() {
local modified_files=0 staged_files=0 untracked_files=0 deleted_files=0
2021-05-15 17:34:41 +03:00
local git_has_changes=0
GIT_CURRENT_BRANCH="$(git branch --show-current)"
2021-05-15 16:47:38 +03:00
git status --porcelain=v1 | while IFS= read -r status_line; do
2021-05-15 17:34:41 +03:00
git_has_changes=1
2021-05-15 16:47:38 +03:00
case "$status_line" in
' M '*)
((modified_files++))
;;
'A '*|'M '*)
((staged_files++))
;;
' D '*)
((deleted_files++))
;;
'?? '*)
((untracked_files++))
;;
'MM '*)
((staged_files++))
((modified_files++))
;;
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
2021-05-15 17:34:41 +03:00
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}')
2021-05-15 16:47:38 +03:00
2021-05-15 17:48:12 +03:00
(( ${commits_behind} > 0 )) \
2021-05-15 16:47:38 +03:00
&& GIT_COMMITS_BEHIND="${commits_behind} " \
2021-05-15 17:48:12 +03:00
&& git_has_changes=1
(( ${commits_ahead} > 0 )) \
2021-05-15 16:47:38 +03:00
&& GIT_COMMITS_AHEAD="${commits_ahead} " \
2021-05-15 17:48:12 +03:00
&& git_has_changes=1
2021-05-15 16:47:38 +03:00
fi
2021-05-15 17:34:41 +03:00
GIT_COMMITS_STATUS="${GIT_COMMITS_AHEAD}${GIT_COMMITS_BEHIND}"
2021-05-15 16:47:38 +03:00
2021-05-15 17:34:41 +03:00
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}"
2021-05-15 17:48:12 +03:00
local fg_special='%F{yellow}'
2021-05-15 16:47:38 +03:00
else
2021-05-15 17:48:12 +03:00
local fg_special='%F{34}'
2021-05-15 16:47:38 +03:00
fi
2021-05-15 17:48:12 +03:00
GIT_STATUS="${fg_special}"
2021-05-15 17:34:41 +03:00
GIT_STATUS+="${GIT_CURRENT_BRANCH} "
2021-05-15 16:47:38 +03:00
GIT_STATUS+="${GIT_COMMITS_STATUS}"
GIT_STATUS+="${GIT_MODIFIED}${GIT_STAGED}"
GIT_STATUS+="${GIT_DELETED}${GIT_UNTRACKED}"
GIT_STATUS+="${FG_CLR}"
# Remove trailing whitespace
GIT_STATUS="$(sed 's/[ ]+$//' <<<"$GIT_STATUS")"
2021-05-15 16:47:38 +03:00
}
###
# Control script from here
# Globals:
# none
# Arguments:
# none
###
function main() {
2021-05-15 17:34:41 +03:00
sanitize || return 1
2021-05-15 16:47:38 +03:00
parse_git_status
}
main