#!/bin/bash summary="$0 [options] " ref=main dst='.' nonempty_target=false use_home=false be_aggressive=false while getopts ":hr:d:NHa" option; do case $option in h) # display Help Help exit;; r) # branch or tag wanted ref="$OPTARG";; d) # destination of clone dst="$OPTARG";; N) # clone to a Non-empty target. Existing files will be overwritten nonempty_target="true";; H) # use real home dir use_home="false";; a) # use git clean with the aggressive option be_aggressive="true";; \?) # invalid option echo "Error: Invalid option here" exit;; esac done shift $((OPTIND-1)) repo="$1" if [ -z "$repo" ] ; then exit "$0: Empty repo given\n$summary" fi if [ ! $use_home ] ; then set -a export HOME=/dev/null set +a fi mkdir -p "$dst" cd "$dst" if [ -d .git ] ; then git submodule update --init --recursive --force --depth=1 --remote git fetch --tags --depth=1 --prune --prune-tags --force origin $ref git reset --hard FETCH_HEAD git reflog expire --expire=now --all if "$be_aggressive" ; then git gc --prune=now --aggressive else git gc --prune=now fi # Preserve existing files in some cases if ! "$nonempty_target" ; then #we keep uncommitted files when in -N mode git clean -qfdx fi else clone_dst='.' # To override an existing dir, we need to clone elsewhere first if "$nonempty_target" ; then clone_dst="$(mktemp -d)" fi git clone -b "$ref" --recurse-submodules --shallow-submodules --depth 1 "$repo" "$clone_dst" # To override an existing dir, we then move everything to that dir if "$nonempty_target" ; then mv "$clone_dst/"{*,.*} . rmdir "$clone_dst" fi fi