Shallow Clone for CircleCI 2.0 Builds

config

#1

I opened a PR to add this to the docs, but seems there really isn’t a good place for it. As such, it was recommended I add it here.

At the top of your config.yml , add the following (please forgive the spacing):

aliases:
  # Shallow Clone
  - &checkout-shallow
    name: Checkout
    command: |
#!/bin/sh
set -e

# Workaround old docker images with incorrect $HOME
# check https://github.com/docker/docker/issues/2968 for details
if [ "${HOME}" = "/" ]
then
  export HOME=$(getent passwd $(id -un) | cut -d: -f6)
fi

mkdir -p ~/.ssh

echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
' >> ~/.ssh/known_hosts

(umask 077; touch ~/.ssh/id_rsa)
chmod 0600 ~/.ssh/id_rsa
(cat <<EOF > ~/.ssh/id_rsa
$CHECKOUT_KEY
EOF
)

# use git+ssh instead of https
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true

if [ -e /home/circleci/project/.git ]
then
    cd /home/circleci/project
    git remote set-url origin "$CIRCLE_REPOSITORY_URL" || true
else
    mkdir -p /home/circleci/project
    cd /home/circleci/project
    git clone --depth=1 "$CIRCLE_REPOSITORY_URL" .
 fi

 if [ -n "$CIRCLE_TAG" ]
 then
   git fetch --depth=10 --force origin "refs/tags/${CIRCLE_TAG}"
 elif [[ "$CIRCLE_BRANCH" =~ ^pull\/* ]]
 then
 # For PR from Fork
   git fetch --depth=10 --force origin "$CIRCLE_BRANCH/head:remotes/origin/$CIRCLE_BRANCH"
 else
   git fetch --depth=10 --force origin "$CIRCLE_BRANCH:remotes/origin/$CIRCLE_BRANCH"
 fi

if [ -n "$CIRCLE_TAG" ]
then
    git reset --hard "$CIRCLE_SHA1"
    git checkout -q "$CIRCLE_TAG"
elif [ -n "$CIRCLE_BRANCH" ]
then
    git reset --hard "$CIRCLE_SHA1"
    git checkout -q -B "$CIRCLE_BRANCH"
fi

git reset --hard "$CIRCLE_SHA1"

Then, when checking out you can use the following:

 - run: *checkout-shallow

This is by no means perfect but will solve for 90% of use cases. It allowed us to reduce a 1.5 GB clone from 7 minutes to just 10 seconds. Your mileage may vary.

Happy building!


#2