mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Koen Zandberg
96cad82910
A number of scripts use features from bash such as `local` which are not in the POSIX spec. This breaks on systems where sh is not symlinked to bash. This patch changes the interpreter indicated by the hashbang to bash for those scripts
290 lines
7.3 KiB
Bash
Executable File
290 lines
7.3 KiB
Bash
Executable File
#!/bin/bash -e
|
|
|
|
[ "$GIT_CACHE_VERBOSE" != "1" ] && Q=-q
|
|
|
|
git_cache() {
|
|
git -C "${GIT_CACHE_DIR}" $*
|
|
}
|
|
|
|
git_cache_initialized() {
|
|
local _git_dir="$(git_cache rev-parse --git-dir 2>/dev/null)"
|
|
test "$_git_dir" = "." -o "$_git_dir" = ".git"
|
|
}
|
|
|
|
init() {
|
|
git_cache_initialized || {
|
|
mkdir -p "${GIT_CACHE_DIR}"
|
|
|
|
git_cache init --bare
|
|
git_cache config core.compression 1
|
|
}
|
|
}
|
|
|
|
startswith() {
|
|
case "$1" in
|
|
"${2}"*)
|
|
return 0
|
|
;;
|
|
*)
|
|
return 1
|
|
esac
|
|
}
|
|
|
|
add() {
|
|
local repo="$1"
|
|
|
|
_locked "$GIT_CACHE_DIR/$name.addlock" _add "$repo"
|
|
}
|
|
|
|
_add() {
|
|
local repo="$1"
|
|
local name="$(_remote_name $repo)"
|
|
|
|
if ! is_cached "$repo"; then
|
|
git_cache remote add "$name" "$repo"
|
|
git_cache config --add remote.${name}.fetch "+refs/tags/*:refs/tags/${name}/*"
|
|
else
|
|
echo "git-cache: $url already in cache"
|
|
fi
|
|
}
|
|
|
|
if [ "$(uname)" = Darwin ]; then
|
|
_locked() {
|
|
local lockfile="$1"
|
|
shift
|
|
|
|
while ! shlock -p $$ -f $lockfile; do
|
|
sleep 0.2
|
|
done
|
|
|
|
$*
|
|
|
|
rm $lockfile
|
|
}
|
|
else
|
|
_locked() {
|
|
local lockfile="$1"
|
|
shift
|
|
|
|
(
|
|
flock -w 600 9 || exit 1
|
|
$*
|
|
) 9>"$lockfile"
|
|
}
|
|
fi
|
|
|
|
update() {
|
|
local REMOTE=${1}
|
|
if [ -n "$REMOTE" ]; then
|
|
local REMOTES=$(_remote_name $REMOTE)
|
|
else
|
|
local REMOTES="$(git_cache remote show)"
|
|
fi
|
|
|
|
for remote in $REMOTES; do
|
|
echo "git-cache: updating remote $remote"
|
|
_locked "$GIT_CACHE_DIR/$remote.lock" git_cache --namespace $remote fetch $Q -n $remote
|
|
done
|
|
}
|
|
|
|
is_cached() {
|
|
local url="$1"
|
|
local REMOTES="$(git_cache remote show)"
|
|
for remote in $REMOTES; do
|
|
[ "$(git_cache ls-remote --get-url $remote)" = "$url" ] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
list() {
|
|
local REMOTES="$(git_cache remote show)"
|
|
for remote in $REMOTES; do
|
|
echo "$(git_cache ls-remote --get-url $remote)"
|
|
done
|
|
}
|
|
|
|
drop() {
|
|
local REMOTE=${1}
|
|
[ -z "$REMOTE" ] && {
|
|
echo "usage: git cache drop <url>"
|
|
exit 1
|
|
}
|
|
local REMOTES="$(git_cache remote show)"
|
|
for remote in $REMOTES; do
|
|
[ "$(git_cache ls-remote --get-url $remote)" = "$REMOTE" ] && {
|
|
git_cache remote remove $remote
|
|
break
|
|
}
|
|
done
|
|
}
|
|
|
|
_check_commit() {
|
|
git_cache cat-file -e ${1}^{commit} 2>/dev/null
|
|
}
|
|
|
|
_remote_name() {
|
|
echo "$*" | git hash-object --stdin
|
|
}
|
|
|
|
_tag_to_sha1() {
|
|
local out="$(git_cache log -n 1 --pretty=oneline $1 -- 2>/dev/null || true)"
|
|
[ -n "$out" ] && echo $out | cut -f 1 -d" "
|
|
}
|
|
|
|
_check_tag_or_commit() {
|
|
local SHA1=$1
|
|
local REMOTE_NAME=$2
|
|
|
|
if _check_commit $SHA1 ; then
|
|
local tag=commit$SHA1-$$
|
|
git_cache tag $tag $SHA1 2> /dev/null || true # ignore possibly already existing tag
|
|
echo "$tag"
|
|
elif _tag_to_sha1 ${REMOTE_NAME}/$SHA1 > /dev/null; then
|
|
echo "${REMOTE_NAME}/$SHA1"
|
|
fi
|
|
}
|
|
|
|
clone() {
|
|
local REMOTE="${1}"
|
|
local SHA1="${2}"
|
|
local REMOTE_NAME="$(_remote_name $REMOTE)"
|
|
local TARGET_PATH="${3}"
|
|
|
|
[ -z "$TARGET_PATH" ] && TARGET_PATH="$(basename $REMOTE)"
|
|
|
|
# make sure git won't ask for credentials
|
|
export GIT_TERMINAL_PROMPT=0
|
|
|
|
if git_cache_initialized; then
|
|
if ! is_cached "$REMOTE"; then
|
|
echo "git cache: auto-adding $REMOTE"
|
|
add "$REMOTE"
|
|
fi
|
|
|
|
local pull=0
|
|
if startswith "$SHA1" "pull/"; then
|
|
pull=1
|
|
fi
|
|
|
|
if [ $pull -eq 0 ]; then
|
|
local tag="$(_check_tag_or_commit $SHA1 $REMOTE_NAME)"
|
|
if [ -z "$tag" ]; then
|
|
# commit / tag not in cache, try updating repo
|
|
update "$REMOTE"
|
|
tag="$(_check_tag_or_commit $SHA1 $REMOTE_NAME)"
|
|
fi
|
|
else
|
|
local tag="remotes/$REMOTE_NAME/master"
|
|
if [ -z "$(_tag_to_sha1 $tag)" ]; then
|
|
update "$REMOTE"
|
|
fi
|
|
tag="$(_check_tag_or_commit $(_tag_to_sha1 $tag) $REMOTE_NAME)"
|
|
if [ -z "$tag" ]; then
|
|
echo "git-cache: cannot checkout master branch of $REMOTE"
|
|
false
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$tag" ]; then
|
|
echo "git-cache: cloning from cache. tag=$tag"
|
|
git -c advice.detachedHead=false clone $Q --reference "${GIT_CACHE_DIR}" --shared "${GIT_CACHE_DIR}" "${TARGET_PATH}" --branch $tag
|
|
|
|
# rename tags from <remote-hash>/* to *
|
|
git -C "${TARGET_PATH}" fetch $Q origin "refs/tags/${REMOTE_NAME}/*:refs/tags/*"
|
|
|
|
# remove all commit* and <remote-hash>/* tags
|
|
git -C "${TARGET_PATH}" tag -l \
|
|
| grep -P '(^[a-f0-9]{40}/|^commit[a-f0-9]{40}(-\d+)?$)' \
|
|
| xargs git -C "${TARGET_PATH}" tag -d > /dev/null
|
|
|
|
# cleanup possibly created helper tag
|
|
case $tag in
|
|
commit*)
|
|
git_cache tag -d $tag 2>&1 > /dev/null || true
|
|
;;
|
|
esac
|
|
|
|
|
|
if [ $pull -eq 1 ]; then
|
|
git -C "${TARGET_PATH}" fetch $Q $REMOTE $SHA1:$SHA1
|
|
git -C "${TARGET_PATH}" checkout $Q $SHA1
|
|
fi
|
|
else
|
|
echo "git-cache: trying checkout from source"
|
|
git clone $Q --reference "${GIT_CACHE_DIR}" --shared "${REMOTE}" "${TARGET_PATH}"
|
|
git -c advice.detachedHead=false -C "${TARGET_PATH}" checkout $Q $SHA1
|
|
fi
|
|
else
|
|
git clone "${REMOTE}" "${TARGET_PATH}"
|
|
git -c advice.detachedHead=false -C "${TARGET_PATH}" checkout $SHA1
|
|
fi
|
|
}
|
|
|
|
cleanup() {
|
|
git_cache tag -l \
|
|
| grep -P '(^commit[a-f0-9]{40}(-\d+)?$)' \
|
|
| xargs git -C "${GIT_CACHE_DIR}" tag -d > /dev/null
|
|
}
|
|
|
|
usage() {
|
|
echo "git cache uses a bare git repository containing all objects from multiple"
|
|
echo "upstream git repositories."
|
|
echo ""
|
|
echo "usage:"
|
|
echo ""
|
|
echo " git cache init initialize git cache"
|
|
echo " git cache add <url> add repository <url>"
|
|
echo " git cache list list cached repositories"
|
|
echo " git cache drop <url> drop repo from cache"
|
|
echo " git cache update [<url>] fetch repo <url> (or all)"
|
|
echo " git cache clone <url> <SHA1> clone repository <url> from cache"
|
|
echo " git cache show-path print's the path that can be used as "
|
|
echo " '--reference' parameter"
|
|
echo " git cache cleanup cleanup dangling temporary tags"
|
|
echo " (appear if git-cache gets inter-"
|
|
echo " rupted, but are harmless)"
|
|
echo ""
|
|
echo "To retrieve objects from cache (will use remote repository if needed):"
|
|
echo ' git clone --reference $(git cache show-path) <repo>'
|
|
}
|
|
|
|
[ $# -eq 0 ] && {
|
|
usage
|
|
exit 1
|
|
}
|
|
|
|
ACTION=$1
|
|
shift 1
|
|
|
|
GIT_CACHE_DIR=${GIT_CACHE_DIR:-${HOME}/.gitcache}
|
|
|
|
case $ACTION in
|
|
init)
|
|
init $*
|
|
;;
|
|
add)
|
|
add $*
|
|
;;
|
|
update)
|
|
update $*
|
|
;;
|
|
list)
|
|
list $*
|
|
;;
|
|
drop)
|
|
drop $*
|
|
;;
|
|
show-path)
|
|
echo ${GIT_CACHE_DIR}
|
|
;;
|
|
clone)
|
|
clone $*
|
|
;;
|
|
cleanup)
|
|
cleanup
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|