stockholm/bin/fetchgit

72 lines
2.0 KiB
Plaintext
Raw Normal View History

2015-06-24 18:00:52 +00:00
#! /bin/sh
2015-06-26 15:58:30 +00:00
#
# usage: fetchgit git_rev git_url out_link
#
# Clone the specified Git repository and make it available as out_link.
#
2015-06-24 18:00:52 +00:00
set -euf
git_rev=$1
git_url=$2
2015-06-26 15:58:30 +00:00
out_link=$3
2015-06-24 18:00:52 +00:00
2015-06-26 15:58:30 +00:00
# Put all bases in the same place as out_link.
# Notice how out_link must not clash with cache_dir and work_dir.
cache_base=$(dirname "$out_link")
work_base=$(dirname "$out_link")
2015-06-24 18:00:52 +00:00
2015-06-26 15:58:30 +00:00
# cache_dir points to a (maybe non-existent) directory, where a shared cache of
# the repository should be maintained. The shared cache is used to create
# multiple working trees of the repository.
cache_dir=$cache_base/$(echo "$git_url" | urlencode)
2015-06-24 18:00:52 +00:00
2015-06-26 15:58:30 +00:00
# work_dir points to a (maybe non-existent) directory, where a specific
# revision of the repository is checked out.
2015-06-28 11:47:21 +00:00
work_dir=$work_base/$(echo "$git_rev" | urlencode)
2015-06-24 18:00:52 +00:00
2015-06-26 15:58:30 +00:00
cache_git() {
git --git-dir="$cache_dir" "$@"
}
work_git() {
git -C "$work_dir" "$@"
}
2015-06-24 18:00:52 +00:00
2015-06-26 15:58:30 +00:00
is_up_to_date() {
test -d "$cache_dir" &&
test -d "$work_dir" &&
test "$(cache_git rev-parse "$git_rev")" = "$git_rev" &&
test "$(work_git rev-parse HEAD)" = "$git_rev"
2015-06-26 15:58:30 +00:00
}
2015-06-24 18:00:52 +00:00
2015-06-28 11:51:04 +00:00
# Notice how the remote name "origin" has been chosen arbitrarily.
2015-06-26 15:58:30 +00:00
if ! is_up_to_date; then
if ! test -d "$cache_dir"; then
mkdir -p "$cache_dir"
cache_git init --bare
fi
if ! cache_git_url=$(cache_git config remote.origin.url); then
cache_git remote add origin "$git_url"
elif test "$cache_git_url" != "$git_url"; then
cache_git remote set-url origin "$git_url"
fi
cache_git fetch origin
if ! test -d "$work_dir"; then
git clone -n --shared "$cache_dir" "$work_dir"
fi
2015-06-28 11:47:21 +00:00
commit_name=$(cache_git rev-parse "$git_rev")
work_git checkout "$commit_name" -- "$(readlink -f "$work_dir")"
work_git checkout -q "$commit_name"
2015-06-26 15:58:30 +00:00
work_git submodule init
work_git submodule update
fi
work_git clean -dxf
# Relative links are nicer, and actually we know that work_dir and out_link are
# the same. But, for robustness, check anyway.. :)
if test "$(dirname "$work_dir")" = "$(dirname "$out_link")"; then
ln -snf "$(basename "$work_dir")" "$out_link"
else
ln -snf "$work_dir" "$out_link"
fi