Skip to content

Instantly share code, notes, and snippets.

@Moarram
Last active March 2, 2025 18:37
Show Gist options
  • Save Moarram/e76ae364b9469c62d5f51ef3673235db to your computer and use it in GitHub Desktop.
Save Moarram/e76ae364b9469c62d5f51ef3673235db to your computer and use it in GitHub Desktop.
A Zsh function to get the quantity of each Git status, in the form of an associative array
#!/bin/zsh
git-status-counts() {
local -A counts=(
'STAGED' 0 # staged changes
'CHANGED' 0 # unstaged changes
'UNTRACKED' 0 # untracked files
'BEHIND' 0 # commits behind
'AHEAD' 0 # commits ahead
'DIVERGED' 0 # commits diverged
'STASHED' 0 # stashed files
'CONFLICTS' 0 # conflicted files
'CLEAN' 1 # clean branch 1=true 0=false
)
# Retrieve status
local raw lines
raw="$(git status --porcelain -b 2> /dev/null)"
if [[ $? == 128 ]]; then
return 1 # catastrophic failure, abort
fi
lines=(${(@f)raw})
# Process tracking line
if [[ ${lines[1]} =~ '^## [^ ]+ \[(.*)\]' ]]; then
local items=("${(@s/,/)match}")
for item in $items; do
if [[ $item =~ '(behind|ahead|diverged) ([0-9]+)?' ]]; then
case $match[1] in
'behind') counts[BEHIND]=$match[2];;
'ahead') counts[AHEAD]=$match[2];;
'diverged') counts[DIVERGED]=$match[2];;
esac
fi
done
fi
# Process status lines
for line in $lines; do
if [[ $line =~ '^##|^!!' ]]; then
continue
elif [[ $line =~ '^U[ADU]|^[AD]U|^AA|^DD' ]]; then
counts[CONFLICTS]=$(( ${counts[CONFLICTS]} + 1 ))
elif [[ $line =~ '^\?\?' ]]; then
counts[UNTRACKED]=$(( ${counts[UNTRACKED]} + 1 ))
elif [[ $line =~ '^[MTADRC] ' ]]; then
counts[STAGED]=$(( ${counts[STAGED]} + 1 ))
elif [[ $line =~ '^[MTARC][MTD]' ]]; then
counts[STAGED]=$(( ${counts[STAGED]} + 1 ))
counts[CHANGED]=$(( ${counts[CHANGED]} + 1 ))
elif [[ $line =~ '^ [MTADRC]' ]]; then
counts[CHANGED]=$(( ${counts[CHANGED]} + 1 ))
fi
done
# Check for stashes
if $(git rev-parse --verify refs/stash &> /dev/null); then
counts[STASHED]=$(git rev-list --walk-reflogs --count refs/stash 2> /dev/null)
fi
# Update clean flag
for key val in ${(@kv)counts}; do
[[ $key == 'CLEAN' ]] && continue
(( $val > 0 )) && counts[CLEAN]=0
done
echo ${(@kv)counts} # key1 val1 key2 val2 ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment