Skip to content

Instantly share code, notes, and snippets.

@TimidRobot
Created April 23, 2025 08:56
Show Gist options
  • Save TimidRobot/9e21002076f7c5edb4b5789a652b7342 to your computer and use it in GitHub Desktop.
Save TimidRobot/9e21002076f7c5edb4b5789a652b7342 to your computer and use it in GitHub Desktop.
Assuming a directory of repositories, ensure they are all up-to-date
#!/usr/bin/env bash
#
# Assuming a directory of repositories, ensure they are all up-to-date if:
# 1. HEAD is one of: gh-pages, master, or main
# 2. there are no local modifications
#
# For example:
# cd git
# ./update_repos.sh creativecommons
#
# This script is dedicated to the public domain under the CC0 1.0 Universal
# (CC0 1.0) Public Domain Dedication:
# https://creativecommons.org/publicdomain/zero/1.0/
#### SETUP ####################################################################
set -o errexit
set -o errtrace
set -o nounset
# shellcheck disable=SC2154
trap '_es=${?};
printf "${0}: line ${LINENO}: \"${BASH_COMMAND}\"";
printf " exited with a status of ${_es}\n";
exit ${_es}' ERR
DIR_ORG="${1:?}"
DIR_ORG="${1%/}"
DIR_SCRIPT="$(cd -P -- "${0%/*}" && pwd -P)"
# https://en.wikipedia.org/wiki/ANSI_escape_code
E0="$(printf "\e[0m")" # reset
E30="$(printf "\e[30m")" # black foreground
E31="$(printf "\e[31m")" # red foreground
E33="$(printf "\e[33m")" # yellow foreground
E107="$(printf "\e[107m")" # bright white background
#### FUNCTIONS ################################################################
check_dir_org() {
if [[ ! -d "./${DIR_ORG}" ]]
then
error_exit "Invalid directory: '${DIR_ORG}'"
fi
}
error_exit() {
# Echo error message to stderr and exit with error
echo -e "${E31}ERROR:${E0}${*}" 1>&2
exit 1
}
print_header() {
# Print 80 character wide black on white heading with time
printf "${E30}${E107}# %-69s$(date '+%T')${E0}\n" "${@}"
}
print_warn() {
# echo warn message to stdout
echo -e "${E33}WARN:${E0}${*}"
}
process_repo() {
local _dir_repo _repo_name
_dir_repo="${1}"
_repo_name="${_dir_repo#./"${DIR_ORG}"/}"
print_header "${_dir_repo#./}"
_head="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${_head}" != 'gh-pages' ]] \
&& [[ "${_head}" != 'master' ]] \
&& [[ "${_head}" != 'main' ]]
then
print_warn "(skipping) current branch (${_head}) is not main"
echo
return
fi
if [[ $(git status --porcelain --untracked-files=no | wc -l) -gt 0 ]]
then
print_warn "(skipping) repository contains modified files"
echo
return
fi
git pull
echo
}
#### MAIN #####################################################################
cd "${DIR_SCRIPT}"
check_dir_org
for _dir_repo in ./"${DIR_ORG}"/*
do
[[ -d "${_dir_repo}" ]] || continue
[[ -d "${_dir_repo}/.git" ]] || continue
pushd "${_dir_repo}" >/dev/null
process_repo "${_dir_repo}"
popd >/dev/null
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment