#!/bin/sh # A script to recursively pull git repositories behind origin. # Copyright (c) 2022 Stefan Huber # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, # copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following # conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR # OTHER DEALINGS IN THE SOFTWARE. set -e set -u showHelp() { echo "Recursively pull git repositories behind origin." echo "" echo "Usage:" echo " git-pull-all [OPTIONS]" echo " git-pull-all [OPTIONS] DIR" echo "" echo "OPTIONS:" echo " -a, --ask ask user for each repo before pull" echo " -h, --help show this message" echo " -n, --dry-run do not actually perform pull" echo "" echo "" echo "Examples:" echo "" echo "Recursively find git repositories and invoke pull if" echo "branch is behind origin:" echo "" echo " git-pull-all" echo "" echo "Find git repositories in home directory and print" echo "whether they are up to date:" echo "" echo " git-pull-all -n ~" } if ! options=$(getopt -u -o ahn -l ask,help,dry-run -- "$@"); then showHelp >&2 exit 1 fi set -- $options optDryRun=0 optAsk=0 #Parse the arguments while [ $# -gt 0 ]; do case "$1" in -h|--help) showHelp; exit 0 ;; -n|--dry-run) optDryRun=1 ;; -a|--ask) optAsk=1 ;; --) shift; break ;; -*) echo "Unrecognized option $1" >&2; showHelp >&2; exit 1 ;; *) break ;; esac shift done for REPODIR in $(find "$@" -name .git -type d 2> /dev/null); do REPO=$(dirname ${REPODIR}) echo "Run ${REPO} …" if [ "${optAsk}" = 1 ]; then read -p " Process [y/N]? " -n1 response echo "" [ "${response}" = "y" ] || continue fi git -C ${REPO} remote update if [ -z "$(git -C ${REPO} status -uno | grep 'Your branch is behind')" ] ; then echo "\e[1;32m Already up to date\e[0m" else if [ "${optDryRun}" = 1 ]; then echo -e "\e[1;31m Skipping due to dry-run\e[0m" continue fi git -C ${REPO} pull fi done