Files
shell-scripts/status-all.sh
T

93 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# perform a "git status" on each location specified (recursively), or current location if none specified.
# git will quietly ignore any git repo stored in a folder you lack permission on.
# just listing current status of repos,
#
# will only search symbolic links when passed "-l" option, must be before any locations
# status-all.sh [-l] # current location implied
# status-all.sh [-l] ~/my-projects /var/group-projects
# check for "-l" in command prompt
followLinks="-H"
while getopts "l" option; do
case $option in
l)
followLinks="-L"
;;
esac
done
shift "$((OPTIND-1))"
if [[ "-H" == "$followLinks" ]]; then
echo "use -l to follow symbolic links"
fi
# function to process each location
function process_git_list () {
startedIn=$(pwd)
location=$(realpath $(dirname "$@"))
line="--- --- --- --- --- --- --- --- --- ---"
# use "--" to tell printf there are no more commands, only strings to print
printf -- "--- git status %s %s ---\n" "$location" "${line:${#location}}"
cd "$location"
output=""
info=$(git -c color.status=always status)
remote=$(git remote -vv)
upstream=$(git for-each-ref --format='%(upstream)' $(cat .git/HEAD))
# 33 is yellow text
# display any tracking issue, 43 is yellow background
if [[ "$remote" == "" ]]; then
output="$output\n *  no upstream repo "
elif [[ "$info" == *"HEAD detached at"* ]]; then
output="$output\n *  on detached head "
elif [[ "$upstream" == "" ]]; then
output="$output\n *  on untracked branch "
fi
# various file statuses
if [[ "$info" == *"Changes to be committed"* ]]; then
# 42 is green background
output="$output\n *  has staged changes "
fi
if [[ "$info" == *"Changes not staged for commit"* ]]; then
# 41 is red background
output="$output\n *  has unstaged changes "
fi
if [[ "$info" == *"Untracked files"* ]]; then
# 31 is red text
output="$output\n *  has new files "
fi
# various branch statuses
if [[ "$info" == *"branch is behind"* ]]; then
# 45 is magenta background
output="$output\n *  branch is behind "
fi
if [[ "$info" == *"branch is ahead"* ]]; then
# 46 is cyan background
output="$output\n *  branch is ahead "
fi
if [[ "$info" == *"nothing to commit, working tree clean"* ]]; then
# 90 is gray text
output="$output\n *  nothing to commit, working tree clean "
fi
# fallback to displaying the full message
if [[ "$output" == "" ]]; then
output="\n$info"
fi
# output is prefixed with "\n", skip it
printf "${output:2}\n"
cd "$startedIn"
}
# find all folders named ".git" under given locations,
# and call process_git_list on each location that was found.
# we then work on the folder that contained the ".git" folder.
find "$followLinks" "$@" -type d -name ".git" | while read -r file; do process_git_list "$file"; done