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
1 Answer 1
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
-
\$\begingroup\$ Thanks for your comments! They have taught me quite a lot about bash. \$\endgroup\$lawrensm– lawrensm2013年02月19日 05:08:50 +00:00Commented Feb 19, 2013 at 5:08
-
\$\begingroup\$ Me too. Never have read "Arrays" before. \$\endgroup\$payload– payload2013年02月19日 17:46:29 +00:00Commented Feb 19, 2013 at 17:46
fgit
? It's served me well for years. Disclaimer: I'm the author. \$\endgroup\$