enter_chroot: add support for git object pool indirection

This adds repo --references awareness (which maps down to git shared object
pools; see git clone -s); specifically, it sets up the appropriate indirection
bindings back to the actual shared source for use from within the chroot.

Note that the approach is a bit complex, but it's required complexity- via
this approach the references are accessible both from within, and without
the chroot.

BUG=chromium-os:19939
TEST=cbuildbot x86-generic-full --clobber --notests --nouprev
TEST=cbuildbot x86-generic-full --notests --nouprev
CQ-DEPEND=I986f17503dc154234ecadd90f6975d7164117cdb

Change-Id: I8498863010cefe0bf5b8f20350fa45a5f2a093d3
Reviewed-on: https://gerrit.chromium.org/gerrit/13467
Tested-by: Brian Harring <ferringb@chromium.org>
Reviewed-by: David James <davidjames@chromium.org>
Commit-Ready: Brian Harring <ferringb@chromium.org>
diff --git a/sdk_lib/enter_chroot.sh b/sdk_lib/enter_chroot.sh
index f55d3a5..e8d0d5d 100755
--- a/sdk_lib/enter_chroot.sh
+++ b/sdk_lib/enter_chroot.sh
@@ -250,6 +250,44 @@
     fi
     queue_mount "${FLAGS_trunk}" "--bind" "${CHROOT_TRUNK_DIR}"
 
+
+    debug "Setting up referenced repositories if required."
+    REFERENCE_DIR=$(git config --file  \
+      "${FLAGS_trunk}/.repo/manifests.git/config" \
+      repo.reference)
+    if [ -n "${REFERENCE_DIR}" ]; then
+
+      IFS=$'\n';
+      required=( $( "${FLAGS_trunk}/chromite/lib/rewrite_git_alternates.py" \
+        "${FLAGS_trunk}" "${REFERENCE_DIR}" "${CHROOT_TRUNK_DIR}" ) )
+      unset IFS
+
+      queue_mount "${FLAGS_trunk}/.repo/chroot/alternates" --bind \
+        "${CHROOT_TRUNK_DIR}/.repo/alternates"
+
+      # Note that as we're bringing up each referened repo, we also
+      # mount bind an empty directory over its alternates.  This is
+      # required to suppress git from tracing through it- we already
+      # specify the required alternates for CHROOT_TRUNK_DIR, no point
+      # in having git try recursing through each on their own.
+      #
+      # Finally note that if you're unfamiliar w/ chroot/vfs semantics,
+      # the bind is visible only w/in the chroot.
+      mkdir -p ${FLAGS_trunk}/.repo/chroot/empty
+      position=1
+      for x in "${required[@]}"; do
+        base="${CHROOT_TRUNK_DIR}/.repo/chroot/external${position}"
+        queue_mount "${x}" "--bind" "${base}"
+        if [ -e "${x}/.repo/alternates" ]; then
+          queue_mount "${FLAGS_trunk}/.repo/chroot/empty" "--bind" \
+            "${base}/.repo/alternates"
+        fi
+        position=$(( ${position} + 1 ))
+      done
+      unset required position base
+    fi
+    unset REFERENCE_DIR
+
     if [ $FLAGS_ssh_agent -eq $FLAGS_TRUE ]; then
       if [ -n "${SSH_AUTH_SOCK}" -a -d "${HOME}/.ssh" ]; then
         TARGET_DIR="${FLAGS_chroot}/home/${USER}/.ssh"