3
\$\begingroup\$

I've tried to write a bash script that gives me a general overview of the status of git repos I have cloned/created. It's not meant to replace git status by any means, but give an overview of several repos.

Keep in mind I'm not the most knowledgeable about bash scripting AND git, so I imagine there is a better way to do this:

#!/bin/bash
# Help from: http://www.leancrew.com/all-this/2010/12/batch-comparison-of-git-repositories/
index=0
gitrepos=()
#TODO: There has got to be a better way to add all these folders to the array
#add repos folder
for d in ~/repos/*; do
 gitrepos[(index+=1)]="$d"
done
#add other important folders
gitrepos[(index+=1)]=~/.vim
gitrepos[(index+=1)]=~/dot_files
gitrepos[(index+=1)]=~/bin
for d in "${gitrepos[@]}"; do
 if [ -e $d ]; then
 cd $d
 else
 echo " Did not find repo: $d"
 continue
 fi
 reponame="`basename $d`"
 ok=true
 git fetch --quiet origin 2>/dev/null
 if [ ! -z "`git diff HEAD origin/HEAD 2> /dev/null`" ]; then
 echo " $reponame --> Out of sync with origin/HEAD"
 ok=false
 fi
 if [ ! -z "`git ls-files --other --exclude-standard 2> /dev/null`" ]; then
 echo " $reponame --> Untracked files present"
 ok=false
 fi
 if [ ! -z "`git diff --cached --shortstat 2> /dev/null`" ]; then
 echo " $reponame --> Changes to be committed"
 ok=false
 fi
 if [ ! -z "`git diff --shortstat 2> /dev/null`" ]; then
 echo " $reponame --> Changes to be staged/committed"
 ok=false
 fi
 if $ok; then
 echo " OK --> $reponame"
 fi
done
asked Feb 14, 2013 at 3:01
\$\endgroup\$
1
  • \$\begingroup\$ Have you tried fgit? It's served me well for years. Disclaimer: I'm the author. \$\endgroup\$ Commented Apr 3, 2013 at 11:48

1 Answer 1

3
\$\begingroup\$

Yes there is a better way of filling an array. You can use globbing inside of array parens. Also I suggest being explicit about what you do in bash and use declare -a to declare arrays and later on declare for other variables

declare -a repos=(~/repos/* ~/.vim ~/dot_files ~/bin)

In case of adding stuff to an array, after it got created:

repos+=("more stuff" here)

Maybe you want to name you iterating variable more verbose, instead of d repodir or something.

Your first if contains a continue so you can emphasize on this one and just go on with no else. Also don't miss the double quotes in case of directory names with spaces in them. Also you should check for -d since you cd into it.

if [ -d "$d" ]; then
 echo "No repo at $d"
 continue
fi
cd "$d"

[ ! -z "`cmd`" ] is more verbose than it needs to be. You can just do [ "`cmd`" ].

Read the "Arrays" chapter in the bash manpage.

I attach my test file for this answer which also shows functions and some refactoring which allows to discard this ok variable.

#!/bin/bash
main() {
 local -a repos=(* /foo/bar)
 echo -e "repos: ${repos[@]}"
 for path in "${repos[@]}"; do
 check_repo "$path"
 done
}
check_repo() {
 local path="1ドル"
 local name="`basename "$path"`"
 local report=""
 if [ ! -d "$path" ]; then
 echo -e "$name\n not a directory: $path"
 return
 fi
 cd "$path"
 if [ "`echo foo 2> /dev/null`" ]; then
 report+="\n oh oh"
 fi
 cd - > /dev/null
 if [ -z "$report" ]; then
 report+="\n OK"
 fi
 echo -e "$name$report"
}
main
answered Feb 19, 2013 at 0:11
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your comments! They have taught me quite a lot about bash. \$\endgroup\$ Commented Feb 19, 2013 at 5:08
  • \$\begingroup\$ Me too. Never have read "Arrays" before. \$\endgroup\$ Commented Feb 19, 2013 at 17:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.