Last active
January 19, 2022 21:44
-
-
Save nrutman/771f4cd64683a0c9eec8efcb3cb2c9d6 to your computer and use it in GitHub Desktop.
A bash script that will pull from upstream on a directory of git repositories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Does a git pull for every git repository in a directory and tracks the results | |
# Resolves a relative directory | |
# source: https://stackoverflow.com/questions/7126580/expand-a-possible-relative-path-in-bash | |
function dir_resolve() | |
{ | |
cd "$1" 2>/dev/null || return $? | |
pwd -P | |
} | |
# prints an error message in red | |
function print_error() | |
{ | |
printf "\x1B[91m%b\x1B[0m" "$1" | |
} | |
# prints a success message in green | |
function print_success() | |
{ | |
printf "\x1B[32m%b\x1B[0m" "$1" | |
} | |
# prints a warning in yellow | |
function print_warning() | |
{ | |
printf "\x1B[33m%b\x1B[0m" "$1" | |
} | |
# outputs usage | |
function usage() | |
{ | |
echo "pull-all [directory] [search_depth]" | |
echo " directory Source directory to search for git repositories (defaults to current directory)" | |
echo " search_depth Depth to search when looking for repositories (defaults to \"2\")" | |
} | |
# catch usage cases (--help flag or no parameters) | |
if [ "$1" == "--help" ]; then | |
usage | |
exit 0 | |
fi | |
if [ $# -eq 0 ]; then | |
usage | |
exit 0; | |
fi | |
# parameters | |
src_dir=$(dir_resolve "$1") | |
default_git_find_depth=${2:-2} # 2 by default | |
# utility characters | |
str_check="\xE2\x9C\x94" # check mark | |
# find the git repositories | |
repos=$(find "$src_dir" -type d -maxdepth "$default_git_find_depth" -name ".git" | sort | sed 's/\/\.git$//g') | |
#loop through the repos | |
for repo in $repos; do | |
# output the repo name | |
printf "\x1B[1m%s\x1B[0m" "$(basename "$repo")" | |
# go to the repo and do pre-pull checks | |
cd "$repo" || exit $? | |
printf " [%s]..." "$(git rev-parse --abbrev-ref HEAD)" | |
has_upstream=$(git status -sb | grep "\.\.\..*$") | |
upstream_gone=$(echo "$has_upstream" | grep "\[gone\]") | |
local_changes=$(git diff-index --name-only HEAD --) | |
if [ -z "$has_upstream" ]; then | |
print_warning "No upstream!\n" | |
continue | |
elif [ -n "$upstream_gone" ]; then | |
print_error "Upstream gone!\n" | |
continue | |
elif [ -n "$local_changes" ]; then | |
print_warning "Local changes exist\n" | |
continue | |
fi | |
# try to pull and display output | |
pull_output=$(git pull) | |
if [ "$?" != "0" ]; then | |
# pull failed | |
print_error "Error!\n" | |
elif [ "Already up to date." == "$pull_output" ]; then | |
# no changes to pull | |
print_success "$str_check\n" # check | |
elif [[ "$pull_output" =~ "Updating".* ]]; then | |
# we got changes | |
print_success "$str_check Updated!\n" | |
else | |
# something unknown happened but without an error | |
print_warning "???" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment