distribution/scripts/get_git

145 lines
5.3 KiB
Text
Executable file

# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2018-present Team LibreELEC (https://libreelec.tv)
# Handler for git
# Usage (in package.mk):
# PKG_URL (mandatory) must point to a git repository (git://... or https://example.com/repo.git)
# PKG_VERSION (mandatory) must point to a commit SHA, e.g. a1b2c3d
# PKG_GIT_SHA (optional) full hash of git commit
# PKG_GIT_CLONE_BRANCH (optional) clone specific branch
# PKG_GIT_CLONE_SINGLE (optional) clone single branch only (set to yes)
# PKG_GIT_CLONE_DEPTH (optional) history to clone, must be a number
# PKG_GIT_SUBMODULE_DEPTH (optional) history of submodules to clone, must be a number
_get_repo_already_downloaded() {
if [ -d "${PACKAGE}" ]; then
(
cd "${PACKAGE}"
_get_repo_clean
[ -n "$(git ls-remote . | grep -m1 HEAD | awk "/^${PKG_VERSION}/ {print \$1;}")" ] || die "ERROR: ${PACKAGE}: failed to determine git HEAD"
[ "${PKG_URL}" = "$(git remote get-url origin)" ] || die "ERROR: ${PACKAGE}: failed to obtain URL of origin"
[ -z "${PKG_GIT_CLONE_BRANCH}" ] && exit 0
[ "${PKG_GIT_CLONE_BRANCH}" = "$(git branch | grep ^\* | cut -d ' ' -f2)" ] || die "ERROR: ${PACKAGE}: failed to determine current git branch"
exit 0
)
return
else
return 1
fi
}
_get_repo_clean() {
git clean -fdx
git checkout -- .
}
# Latest file already present, exit now...
_get_repo_already_downloaded && exit 0
lock_source_dir "${1}"
# Check again in case of concurrent access - if nothing needs to be downloaded, exit now...
_get_repo_already_downloaded && exit 0
# At this point, we need to download something...
build_msg "CLR_GET" "GET" "${1} (git)" "indent"
pkg_lock_status "GETPKG" "${PKG_NAME}" "unpack" "processing package repository..."
rm -f "${STAMP_URL}" "${STAMP_SHA}"
GIT_CLONE_PARAMS="--recursive --shallow-submodules --filter=tree:0"
GIT_SUBMODULE_PARAMS=""
[ -n "${PKG_GIT_CLONE_BRANCH}" ] && GIT_CLONE_PARAMS="${GIT_CLONE_PARAMS} --branch ${PKG_GIT_CLONE_BRANCH}"
[ "${PKG_GIT_CLONE_SINGLE}" = "yes" ] && GIT_CLONE_PARAMS="${GIT_CLONE_PARAMS} --single-branch"
if [ -n "${PKG_GIT_CLONE_DEPTH}" ]; then
if [[ "${PKG_GIT_CLONE_DEPTH}" =~ ^[0-9]+$ ]]; then
GIT_CLONE_PARAMS="${GIT_CLONE_PARAMS} --depth ${PKG_GIT_CLONE_DEPTH}"
else
die "ERROR: PKG_GIT_CLONE_DEPTH is not a number! (${PKG_GIT_CLONE_DEPTH})"
fi
fi
if [ -n "${PKG_GIT_SUBMODULE_DEPTH}" ]; then
if [[ "${PKG_GIT_SUBMODULE_DEPTH}" =~ ^[0-9]+$ ]]; then
GIT_SUBMODULE_PARAMS="${GIT_SUBMODULE_PARAMS} --depth ${PKG_GIT_SUBMODULE_DEPTH}"
else
die "ERROR: PKG_GIT_SUBMODULE_DEPTH is not a number! (${PKG_GIT_SUBMODULE_DEPTH})"
fi
fi
GIT_FOUND="no"
opwd="$(pwd)"
for d in "${SOURCES}/${1}/${1}-"* ; do
if [ -d "${d}/.git" ]; then
if [ "${GIT_FOUND}" = "no" ]; then
cd "${d}"
if [ "${PKG_URL}" = "$(git remote get-url origin)" ]; then
if [[ -z "${PKG_GIT_CLONE_BRANCH}" ]] || [[ $(git branch | grep "^\* ${PKG_GIT_CLONE_BRANCH}$" | wc -l) -eq 1 ]]; then
GIT_FOUND="yes"
GIT_DIR="${d}"
_get_repo_clean
elif [ $(git branch | grep "^ ${PKG_GIT_CLONE_BRANCH}$" | wc -l) -eq 1 ]; then
GIT_FOUND="yes"
GIT_DIR="${d}"
_get_repo_clean
git checkout "${PKG_GIT_CLONE_BRANCH}"
elif [ $(git branch -a | grep "^ remotes/origin/${PKG_GIT_CLONE_BRANCH}$" | wc -l) -eq 1 ]; then
GIT_FOUND="yes"
GIT_DIR="${d}"
_get_repo_clean
git checkout -b "${PKG_GIT_CLONE_BRANCH}" "origin/${PKG_GIT_CLONE_BRANCH}"
else
build_msg "CLR_CLEAN" "DELETE" "(${d})"
cd "${opwd}"
rm -rf "${d}"
fi
if [ "${GIT_FOUND}" = "yes" ]; then
build_msg "CLR_GET" "GIT PULL" "${1}"
# If there is an error with 'git pull' or updating the submodules, just reclone
# NOTE: we run the submodule update twice if the clone already
# exists - but deduplicating would complicate the logic quite a lot and
# the second time is almost a no-op
if ! git pull || ! git submodule update --init --recursive ${GIT_SUBMODULE_PARAMS}; then
cd "${opwd}"
build_msg "CLR_CLEAN" "DELETE" "(${d})"
GIT_FOUND=NO
rm -rf "${d}"
fi
cd "${opwd}"
fi
else
build_msg "CLR_CLEAN" "DELETE" "(${d})"
cd "${opwd}"
rm -rf "${d}"
fi
fi
else
build_msg "CLR_CLEAN" "DELETE" "(${d})"
rm -rf "${d}"
fi
done
cd "${opwd}"
if [ "${GIT_FOUND}" = "no" ]; then
build_msg "CLR_GET" "GIT CLONE" "${1}"
git clone ${GIT_CLONE_PARAMS} "${PKG_URL}" "${PACKAGE}"
elif [ ! "${GIT_DIR}" = "${PACKAGE}" ]; then
mv "${GIT_DIR}" "${PACKAGE}"
fi
( cd "${PACKAGE}"
[ $(git log --oneline --pretty=tformat:"%H" | grep "^${PKG_VERSION}" | wc -l) -eq 1 ] || die "There is no commit '${PKG_VERSION}' on branch '$(git branch | grep ^\* | cut -d ' ' -f2)' of package '${1}'! Aborting!"
git reset --hard "${PKG_VERSION}"
build_msg "CLR_GET" "GIT SUBMODULE" "${1}"
git submodule update --init --recursive ${GIT_SUBMODULE_PARAMS}
)
GIT_SHA="$(git ls-remote "${PACKAGE}" | grep -m1 HEAD | awk '{print $1;}')"
if [ -n "${PKG_GIT_SHA}" -a "${PKG_GIT_SHA}" != "${GIT_SHA}" ]; then
build_msg "CLR_WARNING" "WARNING" "Incorrect git hash in repository: got ${GIT_SHA}, wanted ${PKG_GIT_SHA}"
fi