Skip to content

Instantly share code, notes, and snippets.

@etuttle
Last active June 29, 2020 00:48
Show Gist options
  • Save etuttle/82c68e98a128c4c0c60f284373ab84a2 to your computer and use it in GitHub Desktop.
Save etuttle/82c68e98a128c4c0c60f284373ab84a2 to your computer and use it in GitHub Desktop.
shell script to find un-committed / un-pushed work in local git repos
#!/bin/bash
if [[ $# -eq 0 || $1 == '-h' || $1 == '--help' ]]; then
echo >&2 "Usage: $0 <dirs>"
echo >&2 "Use the IGNORE_REMOTES environment variable to ignore"
echo >&2 "remotes whose hosts match the ignore value."
exit 1
fi
res=0
main() {
pwd=$(pwd)
for dir in "$@"; do
cd "$pwd"
check_dir "${dir}"
((res|=$?))
done
exit $res
}
check_dir() {
local dir=$1
if ! test -d "$dir"; then
h 0 "Not a directory: $dir"
return 1
fi
cd "$dir"
local dname=$(basename "$(pwd)")
echo "${dname}"
if ! is_git; then
return 1
fi
res=0
has_remotes && has_unpushed
((res|=$?))
has_mods
((res|=$?))
has_untracked
return $res
}
is_git() {
if ! test -d .git; then
h 0 "Not a git dir"
return 1
fi
}
has_remotes() {
local num_remotes=0
if [[ -n "$IGNORE_REMOTES" ]]; then
# ignore remotes matching IGNORE_REMOTES in the URL part, before the :
num_remotes=$(set -o noglob; \
git remote -v \
| awk '{print $2}' \
| egrep -v "${IGNORE_REMOTES}.*:" \
| wc -l)
else
num_remotes=$(git remote | wc -l)
fi
if [[ $num_remotes -eq 0 ]]; then
h 0 "No remotes!"
return 0
fi
}
has_unpushed() {
unpushed=$(git -c color.ui=always log --oneline --decorate --branches --not --remotes)
if [[ -n $unpushed ]]; then
h 0 "Committed and never pushed!"
p 1 "$unpushed"
return 1
fi
}
has_mods() {
modified=$(git -c color.ui=always ls-files --modified)
if [[ -n $unmodified ]]; then
h 0 "Modified and never committed"
p 2 "$modified"
return 1
fi
}
has_untracked() {
untracked=$(git -c color.ui=always ls-files --others --exclude-standard)
if [[ -n $untracked ]]; then
count=$(echo $(echo "$untracked" | wc -l))
h 0 "$count UNTRACKED FILES"
fi
}
p() {
local level=$(($1 + 1))
local lines=$2
(IFS=$'\n'; for line in $lines; do
if [[ $level -gt 0 ]]; then
for n in $(seq 1 $level); do
echo -n " "
done
fi
echo "$line"
done)
}
h() {
p $1 "--> $2"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment