git-auto-merge is not just a cronjob.

This commit is contained in:
Darren 'Tadgy' Austin 2023-11-11 20:58:06 +00:00
commit 00990348c9

69
git-auto-merge Executable file
View file

@ -0,0 +1,69 @@
#!/bin/bash
# Version: 0.1.0
# Copyright (c) 2023:
# Darren 'Tadgy' Austin <darren (at) afterdark.org.uk>
# Licensed under the terms of the GNU General Public License version 3.
#
# Automatically fetch and merge (if possible) upstream changes into a local git repository.
# What platform we're running on.
PLATFORM="$(uname -s)"
# Only operate on repositories that are set for maintenance work in ~/.gitconfig.
while IFS= read -r REPO; do
# Get into the working directory.
pushd "$REPO" >/dev/null 2>&1 || {
printf "%s: %s\\n" "${0##*/}" "failed to change to working directory '$REPO'" >&2
RET=1
continue
}
# Skip processing if auto-merging is disabled in this repository.
[[ "$(git config --local --get --type bool script.AutoMergeDisabled 2>/dev/null)" != "true" ]] && {
# Fetch the latest updates.
if git fetch --all --atomic --tags >/dev/null 2>&1; then
# Try to merge using fast-forward only, so no clobbering is done.
if MERGE="$(git merge --ff-only 2>/dev/null)"; then
[[ "$(printf "%s" "$MERGE" | awk '{ print $1; exit }')" == "Updating" ]] && {
if [[ "$PLATFORM" == "Linux" ]]; then
# Linux, how I love thee.
NOW="$(date +'%s%3N')"
elif [[ "$PLATFORM" == "Darwin" ]]; then
# This sucks... but so does Darwin.
NOW="$(perl -e 'use Time::HiRes; printf "%.3f", Time::HiRes::time();')"
NOW="${NOW/.}"
else
printf "%s: %s\\n" "${0##*/}" "unsupported platform: $PLATFORM" >&2
RET=2
break
fi
git config --local --replace-all --type int script.AutoMergeLast "$NOW" >/dev/null 2>&1 || {
printf "%s: %s\\n" "${0##*/}" "updating AutoMergeLast timestamp failed for '$REPO'" >&2
RET=1
}
git config --local --replace-all --type bool script.AutoMergeSuccess true >/dev/null 2>&1 || {
printf "%s: %s\\n" "${0##*/}" "updating AutoMergeSuccess marker failed for '$REPO'" >&2
RET=1
}
}
else
git config --local --replace-all --type bool script.AutoMergeSuccess false >/dev/null 2>&1 || {
printf "%s: %s\\n" "${0##*/}" "updating AutoMergeSuccess marker failed for '$REPO'" >&2
RET=1
}
fi
else
# Mark that the auto-merge failed.
printf "%s: %s\\n" "${0##*/}" "git fetch failed for '$REPO'" >&2
git config --local --replace-all --type bool script.AutoMergeSuccess false >/dev/null 2>&1 || {
printf "%s: %s\\n" "${0##*/}" "updating AutoMergeSuccess marker failed for '$REPO'" >&2
RET=1
}
fi
}
# Back to where we started...
popd >/dev/null 2>&1 || continue
done < <(git config --global --get-all maintenance.repo 2>/dev/null)
exit "${RET:-0}"