|
#! /bin/bash |
|
CWD=`pwd` |
|
|
|
printUsage() { |
|
echo "gitr - Git for multiple repositories made easy!" |
|
echo -e "Usage: gitr <branch|status|push|pull|fetch|merge|stash|checkout [options] [arguments]> [--repos <repo>...] [--gitr-base <path>]" |
|
} |
|
|
|
println() { |
|
echo "$1" |
|
} |
|
|
|
_pushd() { |
|
pushd "$1" > /dev/null |
|
} |
|
|
|
_popd() { |
|
popd > /dev/null |
|
} |
|
|
|
is_git_repo() { |
|
_pushd "$1" && git rev-parse --is-inside-work-tree &> /dev/null |
|
local result=$? |
|
_popd |
|
return $result |
|
} |
|
|
|
_exit() { |
|
cd $CWD |
|
exit $1 |
|
} |
|
|
|
GITR_ARGS=("--repos" "--gitr-base") |
|
is_gitr_arg() { |
|
for arg in ${GITR_ARGS[@]}; do |
|
if [[ "$1" == "$arg" ]]; then |
|
return 0 |
|
fi |
|
done |
|
return 1 |
|
} |
|
|
|
if [[ "$#" == "0" || "$1" == "-h" || "$1" == "--help" ]]; then |
|
printUsage |
|
_exit 1 |
|
fi |
|
|
|
GIT_CMD_INDEX=0 |
|
until [[ "$#" == "0" ]] || is_gitr_arg "$1"; do |
|
GIT_CMD[$GIT_CMD_INDEX]=$1 |
|
GIT_CMD_INDEX=$GIT_CMD_INDEX+1 |
|
shift |
|
done |
|
|
|
if [[ "$GIT_CMD_INDEX" == "0" ]]; then |
|
printUsage |
|
echo No git command found, what do you want to do? |
|
_exit 1 |
|
fi |
|
|
|
# parse gitr arguments: --repos, --gitr-base |
|
REPO_INDEX=0 |
|
until [[ "$#" == "0" ]]; do |
|
case "$1" in |
|
("--repos") |
|
shift |
|
until [[ "$#" == "0" ]] || is_gitr_arg "$1"; do |
|
REPOS[$REPO_INDEX]=$1 |
|
REPO_INDEX=$REPO_INDEX+1 |
|
shift |
|
done |
|
;; |
|
("--gitr-base") |
|
shift |
|
GITR_BASE_DIR=$1 |
|
shift |
|
;; |
|
esac |
|
done |
|
|
|
BASE_DIR=${GITR_BASE_DIR:-$CWD} |
|
echo -e "The base directory is: $BASE_DIR" |
|
println |
|
|
|
if [[ $REPO_INDEX -gt 0 ]]; then |
|
for repo in ${REPOS[@]}; do |
|
if ! is_git_repo $BASE_DIR/$repo/; then |
|
echo "Unknown git repository: $repo in directory $BASE_DIR" |
|
_exit 1 |
|
fi |
|
done |
|
else |
|
REPO_COUNT=0 |
|
for dir in `find $BASE_DIR -mindepth 1 -maxdepth 1 -type d`; do |
|
if is_git_repo $dir; then |
|
# TODO: exclude repo via arguments, e.g. `-x <repo>...` |
|
if [ ! -e $dir/gitr-excluded ]; then |
|
ALL_REPOS[$REPO_COUNT]=`basename $dir` |
|
REPO_COUNT=$REPO_COUNT+1 |
|
fi |
|
fi |
|
done |
|
|
|
if [[ "$REPO_COUNT" == "0" ]]; then |
|
echo "No git repository found in $BASE_DIR or are all excluded?" |
|
_exit 1 |
|
fi |
|
|
|
# All by default |
|
REPOS=${ALL_REPOS[@]} |
|
fi |
|
|
|
for repo in ${REPOS[@]}; do |
|
_pushd $BASE_DIR/$repo/ |
|
echo -e "\033[1;33m[$repo] \033[1;36m${GIT_CMD[0]}\033[0m" |
|
# Need to quote git commands here in order to parse arguments with spaces (e.g. commit message) |
|
git "${GIT_CMD[@]}" |
|
GIT_CMD_STATUS=$? |
|
if [ $GIT_CMD_STATUS -ne 0 ]; then |
|
_exit $GIT_CMD_STATUS |
|
fi |
|
println |
|
_popd |
|
done |
|
|
|
_exit 0 |
|
|