Skip to content

Instantly share code, notes, and snippets.

@derfshaya
Forked from mzabriskie/README.md
Last active September 11, 2018 12:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derfshaya/f9140314866b5c68cc12bf3bc885efa2 to your computer and use it in GitHub Desktop.
Save derfshaya/f9140314866b5c68cc12bf3bc885efa2 to your computer and use it in GitHub Desktop.
Check git status of multiple repos
#!/bin/bash
dir="$1"
inner="$2"
# No directory has been provided, use current
if [ -z "$dir" ]
then
dir="`pwd`"
fi
# Make sure directory ends with "/"
if [[ $dir != */ ]]
then
dir="$dir/"
else
dir="$dir"
fi
# remove error files possibly created by previous run
if [ "$inner" != "true" -a -e /tmp/git-status-errors ]; then
rm /tmp/git-status-errors
fi
# Loop all sub-directories
DIRLST="$(ls -la $dir | awk '{print $9}' | sed 1,3d | sed -e "s|^|$dir|")"
for f in $DIRLST
do
# Only interested in directories
[ -d "${f}" ] || continue
# Check if directory is a git repository
if [ -d "$f/.git" ]
then
mod=0
cd $f
# track statuses in array to show later
statuses=()
# Check for modified files
if [ $(git status 2>>/tmp/git-status-errors | grep modified -c) -ne 0 ]
then
mod=1
statuses+=('m')
fi
# Check for untracked files
if [ $(git status 2>>/tmp/git-status-errors | grep Untracked -c) -ne 0 ]
then
mod=1
statuses+=('f')
fi
# Check for unpushed changes
if [ $(git status 2>>/tmp/git-status-errors | egrep 'Your branch is ahead' -c) -ne 0 ]
then
mod=1
statuses+=('c')
fi
# Check for unpulled changes
if [ $(git status 2>>/tmp/git-status-errors | egrep 'Your branch is behind' -c) -ne 0 ]
then
mod=1
statuses+=('p')
fi
# Check for branch diversion
if [ $(git status 2>>/tmp/git-status-errors | egrep 'Your branch and .*? have diverged' -c) -ne 0 ]
then
mod=1
statuses+=('d')
fi
# Check if everything is peachy keen
if [ $mod -ne 0 ]
then
echo -en "\033[0;35m"
echo "${f}"
echo -en "\033[0m"
# show all statuses tracked in array
for status in ${statuses[@]}
do
if [ "$status" == 'm' ]; then
echo -en "\033[0;31m"
echo "Modified file(s)"
elif [ "$status" == 'f' ]; then
echo -en "\033[0;34m"
echo "Untracked file(s)"
elif [ "$status" == 'c' ]; then
echo -en "\033[0;32m"
echo "Unpushed commit(s)"
elif [ "$status" == 'p' ]; then
echo -en "\033[0;33m"
echo "Unpulled commit(s)"
elif [ "$status" == 'd' ]; then
echo -en "\033[0;95m"
echo "Diverged branch(es)"
else
echo -en "\033[0;37m"
echo "Unlisted mod state"
fi
done
echo -en "\033[0m"
echo
fi
cd ../
elif [ $(ls -la $f/* 2>>/tmp/git-status-errors | grep ^d.*\.git$ -c) -ne 0 ];
# if there are git repositories in this directory, run this command recursively
git-status $f true
fi
done
# print any errors piped to /tmp/git-status-errors
if [ "$inner" != "true" -a -e /tmp/git-status-errors ]; then
echo "Error(s):"
cat /tmp/git-status-errors
rm /tmp/git-status-errors
fi

Changes

  • Only lists a git repository when there is special state associated to it
    • Special states:
      • Modified files
      • Untracked files
      • Unpushed commits
      • Unpulled commits
      • Diverged branches
  • Recursively searches a directory for subdirectories that are git repositories if the directory is not already one
  • Shows all errors at the bottom of output
  • Searches dotfiles too

Description from the original author

If you're like me you have a dir like ~/Workspace/Github where all your git repos live. I often find myself making a change in a repo, getting side tracked and ending up in another repo, or off doing something else all together. After a while I end up with several repos with modifications. This script helps me pick up where I left off by checking the status of all my repos, instead of having to check each one individually.

Usage:

git-status [directory]

This will run git status on each repo under the directory specified. If called with no directory provided it will default to the current directory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment