#!/usr/bin/env bash
# git mirror -- clone a Git repository in "mirror branches" configuration
#
# Unlike `git clone --mirror`, this tool only clones remote branches (and
# associated tags) but not any other refs, e.g. no GitHub/GitLab pull-request
# heads.
#
# Previously this could be simplified to:
#
#git clone --bare --config remote.origin.fetch='+refs/heads/*:refs/heads/*' "$@"
#
# However, with Git 2.21 this no longer works and results in "fatal: multiple
# updates for ref '<ref>' not allowed".

. lib.bash || exit

while (( $# )); do
	url=$1; shift
	if [[ $url != *:* ]]; then
		die "expected repository URL, got '$url' instead"
	fi

	if [[ $1 != */* ]]; then
		dir=$1; shift
	fi

	if [[ $dir && $dir != *.git ]]; then
		dir+=.git
	fi

	if [[ ! $dir ]]; then
		tmp=$url
		while [[ $tmp == */ ]]; do tmp=${tmp%/}; done
		tmp=${tmp%.git}
		while [[ $tmp == */ ]]; do tmp=${tmp%/}; done
		tmp=${tmp##*/}
		dir=$tmp.git
		info "cloning to '$dir'"
	fi

	if [[ -e $dir ]]; then
		err "target '$dir' already exists"
		continue
	fi

	git init --bare "$dir" &&
	git -C "$dir" remote add origin "$url" &&
	git -C "$dir" config remote.origin.fetch "+refs/heads/*:refs/heads/*" &&
	git -C "$dir" remote update
done

((!errors))
