Skip to content

Instantly share code, notes, and snippets.

@samdfonseca
Created January 3, 2016 17:15
Show Gist options
  • Save samdfonseca/49bc560cae455d523457 to your computer and use it in GitHub Desktop.
Save samdfonseca/49bc560cae455d523457 to your computer and use it in GitHub Desktop.
update all repos in a directory at once
#!/usr/bin/env bash
readonly ARGS=$@
readonly LOG=$([ "$VERBOSE" = 1 ] && echo /dev/stdout || echo /dev/null)
readonly ERR=$([ "$VERBOSE" = 1 ] && echo /dev/stderr || echo /dev/null)
_check_repo_for_updates() {
local action=$1; shift
local nofetch=$1; shift
local repo=$1; shift
local remote=$1; shift
local branches=$1;
pushd $repo &>/dev/null
[ "$nofetch" = 0 ] && printf "%s: %s %s\n" $repo $(git fetch --all) &>$LOG
local behind_branches=($(git branch -vv | egrep "($branches).*$remote.*behind" | awk -F ' +' '! /\(no branch\)/ {printf "%s\n", $2}'))
for branch in ${behind_branches[@]}; do
if [ "$action" = "update" ]; then
printf "\nREPO: %s REMOTE: %s BRANCH: %s\n" $repo $remote $branch
git checkout $branch && git pull $remote $branch
elif [ "$action" = "check" ]; then
local branch_info=$(git branch -vv | egrep "$branch.*$remote")
printf "%s\n" "$repo:${branch_info:2}"
fi
done
popd &>/dev/null
}
git-outdated() {
local progname="git-outdated"
local progargs=$@
local helptext="${BOLD}Usage: ${NORM}${progname} ${BOLD}[-hirb]${NORM}\n
${BOLD}-i INCLUDE_PATTERN${NORM} A grep pattern used to select which directories will be checked (Defaults to '.*')\n
${BOLD}-r REMOTE_NAME${NORM} The name of the remote to check against (Defaults to 'origin')\n
${BOLD}-b BRANCHES${NORM} A comma-separated list of branch names or a single branch name to check. Can be used multiple
times (Defaults to all local branches tracking REMOTE_NAME)"
local include_pattern=".*"
local remote_name="origin"
# local ignore_if_no_tracking_branch=0 # 1 - True, 0 - False
local nofetch=0
while getopts :i:r:b:hn opt; do
case $opt in
h) # show usage
echo -e $helptext
exit 0
;;
i) # include_pattern
local include_pattern=$OPTARG
;;
r)
local remote_name=$OPTARG
;;
b)
local _branches=${OPTARG//,/|}
[ "$branches" ] && branches+=\|$_branches || local branches=$_branches
;;
n)
local nofetch=1
;;
\?) # unrecognized option
echo -e "Use ${BOLD}$progname -h${NORM} to see help doc."\\n
exit 2
;;
esac
done
shift $((OPTIND-1))
local action=${1:-check}
local branches=${branches:-"."}
[ "$action" != "check" ] && [ "$action" != "update" ] && printf "%s: %s\n" "Invalid Action" $action && exit 1
for repo in $(ls -F | grep "/" | grep "$include_pattern"); do
if [ -d "$repo/.git" ]; then
_check_repo_for_updates $action $nofetch ${repo:0:-1} $remote_name $branches
else
printf "%s: %s\n" ${repo:0:-1} "No .git directory found in $PWD/$repo" &>/dev/stderr
fi
done
}
main() {
readonly NORM=$(tput sgr0)
readonly BOLD=$(tput bold)
readonly REV=$(tput smso)
git-outdated $ARGS
}
main 2>$ERR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment