#!/usr/bin/env bash
# We want to catch any unexpected failure, and exit immediately
-set -e
+set -E
# Download helper for git, to be called from the download wrapper script
#
# Environment:
# GIT : the git command to call
+# Save our path and options in case we need to call ourselves again
+myname="${0}"
+declare -a OPTS=("${@}")
+
+# This function is called when an error occurs. Its job is to attempt a
+# clone from scratch (only once!) in case the git tree is borked, or in
+# case an unexpected and unsupported situation arises with submodules
+# or uncommitted stuff (e.g. if the user manually mucked around in the
+# git cache).
+_on_error() {
+ local ret=${?}
+
+ printf "Detected a corrupted git cache.\n" >&2
+ if ${BR_GIT_BACKEND_FIRST_FAULT:-false}; then
+ printf "This is the second time in a row; bailing out\n" >&2
+ exit ${ret}
+ fi
+ export BR_GIT_BACKEND_FIRST_FAULT=true
+
+ printf "Removing it and starting afresh.\n" >&2
+
+ popd >/dev/null
+ rm -rf "${git_cache}"
+
+ exec "${myname}" "${OPTS[@]}" || exit ${ret}
+}
+
verbose=
recurse=0
while getopts "${BR_BACKEND_DL_GETOPTS}" OPT; do
mkdir -p "${git_cache}"
pushd "${git_cache}" >/dev/null
+# Any error now should try to recover
+trap _on_error ERR
+
# Caller needs to single-quote its arguments to prevent them from
# being expanded a second time (in case there are spaces in them)
_git() {
printf "Could not fetch special ref '%s'; assuming it is not special.\n" "${cset}"
fi
-# Check that the changeset does exist. If it does not, no reason to go
-# on, we can fast-track to the exit path.
+# Check that the changeset does exist. If it does not, re-cloning from
+# scratch won't help, so we don't want to trash the repository for a
+# missing commit. We just exit without going through the ERR trap.
if ! _git rev-parse --quiet --verify "'${cset}^{commit}'" >/dev/null 2>&1; then
printf "Commit '%s' does not exist in this repository\n." "${cset}"
exit 1