#!/bin/sh # # See README for up to date usage examples. # vim: syntax=sh noexpandtab # umask 022 cd "$(dirname "$0")/.." TOP="$(pwd)" . build/nano_env . build/functions.sh . build/repos.sh # Using shallow "--depth 1" git checkouts is problematic, so we default # it to off. # https://github.com/phinze/homebrew-cask/issues/1003 # # @phinze I think the only solution is for homebrew to not use --depth # 1 in git clone. I experienced many issues with that option, and # cloned repo practically not useable, if you want to commit something # / browse history. Maybe it's not exactly issue with "fatal: git # fetch-pack: expected shallow list", but generally --depth 1 causes # lot of problems. # # Internally we were having trouble with not being able to incrementally # update repos checked out with --depth1 so turn this off until we have # a better understanding of what is going on. if [ "x$GIT_SHALLOW" != "xyes" ] ; then GIT_DEEP=yes fi do_git_update() { local my_branch=$1 local my_tag=$2 git fetch origin if [ "$my_tag" ] ; then git checkout "$my_tag" else # if "my branch doesn't exist" then create it. if ! git rev-parse "${my_branch}" ; then git checkout -b ${my_branch} origin/${my_branch} else git checkout "${my_branch}" git pull --rebase fi fi } # # Checkout a module, expects the following parameters: # $1 - repo_name, (example: FREEBSD, PORTS, ZFSD) this variable will be # expanded for globals below. "${GIT_${repo_name}_REPO}" to get the # rest of the information for branch, repo, cache, etc. # Globals: # ${GIT_${repo_name}_REPO} - authoritive repo path # ${GIT_${repo_name}_BRANCH} - which branch to pull # ${GIT_${repo_name}_TAG} - which tag to pull, superscedes "branch" # ${GIT_${repo_name}_DEEP} - set to non-empty string to do a full checkout # this is on by default right now. # example: # # generic_checkout_git FREEBSD "${AVATAR_ROOT}/FreeBSD/src" # # This will checkout into the top level the repo under $GIT_FREEBSD_REPO # into the directory FreeBSD/src under your build directory. # generic_checkout_git() { local repo_name=$1 eval local checkout_path=\${GIT_${repo_name}_CHECKOUT_PATH} eval local my_deep=\${GIT_${repo_name}_DEEP} eval local my_deep=\${GIT_${repo_name}_SHALLOW} eval local my_repo=\${GIT_${repo_name}_REPO} eval local my_branch=\${GIT_${repo_name}_BRANCH} eval local my_tag=\${GIT_${repo_name}_TAG} if [ -z "$my_repo" ]; then echo "repo not specified!" exit 1 fi echo "Checkout: $repo_name -> $my_repo" if [ "$BRANCH" ]; then echo "Overrding branch: ${my_branch}, using branch: ${BRANCH}" my_branch=${BRANCH} fi if [ "$TAG" ]; then echo "Overrding tag: ${my_tag}, using tag: ${TAG}" my_tag=${TAG} fi if [ -z "$my_branch" -a -z "$my_tag" ] ; then my_branch=master fi ( local spl spl="$-";set -x mkdir -p "$checkout_path" local _depth_arg="" if [ "x${GIT_SHALLOW}" = "xYES" -o "x${my_shallow}" != "xYES" ] ; then _depth_arg="--depth 1" fi # If tags are set, then it appears we need a full checkout to get # the tags. If GIT_DEEP is set, then we don't want a shallow # copy because we need to tag for a release or otherwise work # on the repo we are cloning. if [ "x${GIT_DEEP}" != "x" -o "x${my_deep}" != "x" ] ; then _depth_arg="" fi cd "${checkout_path}" # XXX: there are a few git fetch commands below. # can we optimize by using # git remote add -t remote-branch remote-name remote-url ? # instead of a fetch of all of origin? if [ -d ${checkout_path}/.git ] ; then ## do stuff if there is already a checkout... cd ${checkout_path} local old_branch=`git rev-parse --abbrev-ref HEAD` if [ "x${old_branch}" != "x${my_branch}" ]; then # Some forms of checkout set a specific fetch spec for only # the specific branch head. Basically this means that we are # only going to fetch that one branch. # # Detect this scenario and remove the more specific fetch specification # and set our own fetch specification. # # This is somewhat ugly and I'm tempted to just set: # +refs/heads/*:refs/remotes/origin/* if ! git config --unset remote.origin.fetch \ "\\+refs/heads/${old_branch}:refs/remotes/origin/${old_branch}" ; then echo "Unable to clear old specific origin." echo "clearing all origins." git config --unset remote.origin.fetch '.*' git config --add remote.origin.fetch \ "+refs/heads/*:refs/remotes/origin/*" else git config --unset remote.origin.fetch '.*' git config --add remote.origin.fetch \ "+refs/heads/${my_branch}:refs/remotes/origin/${my_branch}" fi git remote set-url origin "${my_repo}" git fetch origin do_git_update "${my_branch}" "${my_tag}" fi git pull $_depth_arg cd .. else # do a fresh checkout... git clone -b "$my_branch" ${my_repo} $_depth_arg ${checkout_path} if [ "$my_tag" ]; then cd ${checkout_path} git checkout "$my_tag" cd .. fi fi echo $spl | grep -q x || set +x mkdir -p $(dirname ${SRCS_MANIFEST}) echo "${my_repo}" `cd ${checkout_path} && git rev-parse HEAD` >> ${SRCS_MANIFEST} ) } checkout_source() { local repo # First try to get the freenas repo which we're building from if [ -f .git/config ]; then mkdir -p $(dirname ${SRCS_MANIFEST}) echo `awk '/url = / {print $3}' .git/config` `git log -1 --format="%H"` > ${SRCS_MANIFEST} fi for repo in ${REPOS}; do generic_checkout_git ${repo} done mkdir -p ${AVATAR_ROOT}/FreeBSD # Nuke newly created files to avoid build errors. git_status_ok="${AVATAR_ROOT}/FreeBSD/.git_status_ok" rm -rf "$git_status_ok" ( cd $GIT_FREEBSD_CHECKOUT_PATH && git status --porcelain ) | tee "$git_status_ok" awk '$1 == "??" { print $2 }' < "$git_status_ok" | xargs rm -Rf # Mark git clone/pull as being done already. echo "$NANO_LABEL" > ${AVATAR_ROOT}/FreeBSD/.pulled } main() { set -e checkout_source } main "$@"