#!/bin/bash # # To use this create a directory that you want to use for git repos, e.g. $HOME/git and copy/symlink this script into it. # Then you can use it like this: # # ./clone github.com/robertgzr/dotfiles # ./clone https://bitbucket.org/foo/bar # # TODO: does it still? # This requires url aliases to be setup for the git-clone to work properly: # # [url "git@github.com:"] # insteadOf = "gh:" # insteadOf = "https://github.com/" # pushInsteadOf = "github:" # pushInsteadOf = "git://github.com/" # set -e [ -n "$DEBUG" ] && set -x SHALLOW= RECURSE_SUBMODULES= TEMP="$(mktemp -d -p /tmp clone.XXXXXXXXXX)" URL= while getopts ":hsr" opt; do case ${opt} in s) SHALLOW=1 ;; r) RECURSE_SUBMODULES=1 ;; h | \?) printf "usage: clone [-s][-r] URL\n" printf "\n" printf " URL example.com/user/repo\n" printf " http[s]://example.com/user/repo\n" printf "\n" printf " -s shallow clone\n" printf " -r recurse submodules\n" printf " -n don't cd after cloning\n" printf "\n" exit 0 ;; esac done shift $((OPTIND - 1)) fail() { printf "error: %s\n" "${1:-error}" exit "${2:-1}" } confirm() { printf "%s, ok (y/n)? " "${1:-'do something'}" read -r yn if [[ "$yn" = "${yn#[Yy]}" ]]; then fail "ok, exiting" 0 fi } git_clone() { declare -a GIT_FLAGS if [[ -n "${SHALLOW}" ]]; then printf "* shallow clone\n" GIT_FLAGS+=("--depth=${SHALLOW}") fi if [[ -n "${RECURSE_SUBMODULES}" ]]; then printf "* recurse submodules\n" GIT_FLAGS+=("--recurse-submodules") fi git clone "${GIT_FLAGS[@]}" "${@}" } ssh_clone() { prefix=$1 in=$2 to=$3 IFS='/' read -r -a url <<<"${in}" ssh_url="${prefix}:${url[1]}/${url[2]}" printf "* via ssh: %s\n" "${ssh_url}" git_clone "${ssh_url}" "${to}" } http_clone() { to=$2 http_url="https://${URL}" printf "* via http: %s\n" "${ssh_url}" git_clone "${http_url}" "${to}" } clone() { in=$1 to=$2 mkdir -p "${to}" IFS='/' read -r -a url <<<"${in}" case "${url[0]}" in github.com) ssh_clone git@github.com "${in}" "${to}" ;; gitlab.com) ssh_clone git@gitlab.com "${in}" "${to}" ;; bitbucket.org) ssh_clone git@bitbucket.org "${in}" "${to}" ;; git.sr.ht) ssh_clone git@git.sr.ht "${in}" "${to}" ;; *) http_clone "${url/ /\/}" "${to}" ;; esac if [ -e "${to}/.gitmodules" ]; then git -C "${to}" submodule update --init --recursive fi } URL=$1 if [[ -z "${URL}" ]]; then fail "no input" else URL="${URL//http*:\/\//}" URL="${URL//#*/}" fi target="${PWD}/$(dirname "${URL}")" name="$(basename "${URL}")" if [ ! -d "${target}/${name}" ]; then clone "${URL}" "${TEMP}/${URL}" || fail install -d "${target}" || fail mv "${TEMP}/${URL}" "${target}" || fail fi