set -e
set -o pipefail
BASE_BRANCHES='main'
repo=$(
perl -MTOML -we '
use strict;
undef $/;
my $toml = from_toml(<STDIN>);
print $toml->{package}{repository} // die;
' <Cargo.toml
)
repo_host=$(
perl -we '
$ARGV[0] =~ m{^https://[-.0-9a-z]+/}
or die "bad repository url";
print "$&\n";
' "$repo"
)
echo "Cargo.toml package.repository: $repo"
echo "Upstream repository instance: $repo_host"
case "$CI_PROJECT_URL" in
"$repo_host"*)
git remote rm upstream.tmp >/dev/null 2>&1 ||:
git remote rename upstream upstream.tmp >/dev/null 2>&1 ||:
git remote add upstream "$repo"
ORIGIN=upstream
;;
'')
ORIGIN=origin
;;
*)
echo >&2 "CI_PROJECT_URL $CI_PROJECT_URL not recognised!"
exit 4
;;
esac
echo "Baseline repo remote $ORIGIN, at:"
git remote get-url "$ORIGIN"
tlref () {
echo "refs/remotes/$ORIGIN/$tbranch"
}
x () {
echo "+ $*"
"$@"
}
git_checkout_maybe_clean () {
x=$1; shift
if
$x git checkout -q "$1"
then :
else
echo "Checkout failed, trying with git clean and git reset"
x git clean -xdff
x git reset --hard
x git checkout -q "$1"
fi
}
old_branch=$(git symbolic-ref -q HEAD || test $? = 1)
restore_old_branch () {
case "$old_branch" in
refs/heads/*)
git_checkout_maybe_clean '' "${old_branch#refs/heads/}" ||
echo '*** Failed to return to original branch ***'
;;
*)
echo "*** Was not originally on a branch, HEAD changed! ***"
;;
esac
}
trap 'restore_old_branch' 0
refspecs=()
for tbranch in $BASE_BRANCHES; do
refspecs+=(+"refs/heads/$tbranch:$(tlref)")
done
if [ "x$(git rev-parse --is-shallow-repository)" != xfalse ]; then
git fetch --unshallow "$ORIGIN" "${refspecs[@]}"
fi
for tbranch in $BASE_BRANCHES; do
trevlist="$(tlref)..HEAD"
tcount=$(git rev-list --count "$trevlist")
printf "HEAD is %3d commits ahead of %s\n" "$tcount" "$tbranch"
if [ "$count" ] && [ $count -le $tcount ]; then continue; fi
count=$tcount
branch=$tbranch
revlist=$trevlist
done
echo "Testing every commit not already on $branch"
commits=$(git rev-list --reverse "$revlist")
i=0
for commit in $commits; do
banner='##############################'
printf "|\n%s %d/%d %s\n|\n" "$banner" "$i" "$count" "$banner"
git log -n1 "$commit" | sed 's/^/| /'
echo '|'
git_checkout_maybe_clean x "$commit"
if x "$@"; then :; else
rc="$?"
printf "
|
========================= Failed after $i/$count =========================
|
Earliest broken commit is
"
git --no-pager log -n1 --pretty=oneline "$commit"
exit "$rc"
fi
i=$(( $i + 1 ))
done
echo "|
$banner ok $banner
|"
rc=0