#!/bin/sh

# Usage:    ssh git@host fork <repo1> <repo2>
#
# Forks repo1 to repo2.  You must have read permissions on repo1, and create
# ("C") permissions for repo2, which of course must not exist.
#
# A fork is functionally the same as cloning repo1 to a client and pushing it
# to a new repo2.  It's just a little more efficient, not just in network
# traffic but because it uses git clone's "-l" option to share the object
# store also, so it is likely to be almost instantaneous, regardless of how
# big the repo actually is.

die() { echo "$@" >&2; exit 1; }
usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; }
[ -z "$1" ] && usage
[ "$1" = "-h" ] && usage
[ -z "$GL_USER" ] && die GL_USER not set

# ----------------------------------------------------------------------
from=$1; shift
to=$1; shift
[ -z "$to" ] && usage

gitolite access -q "$from" $GL_USER R any || die "'$from' does not exist or you are not allowed to read it"
gitolite access -q "$to"   $GL_USER ^C any || die "'$to' already exists or you are not allowed to create it"

# ----------------------------------------------------------------------
# IMPORTANT NOTE: checking whether someone can create a repo is done as above.
# However, make sure that the env var GL_USER is set, and that too to the same
# value as arg-2 of the access command), otherwise it won't work.

# Ideally, you'll leave such code to me.  There's a reason ^C is not listed in
# the help message for 'gitolite access'.
# ----------------------------------------------------------------------

# clone $from to $to
git clone --bare -l $GL_REPO_BASE/$from.git $GL_REPO_BASE/$to.git
[ $? -ne 0 ] && exit 1

echo "$from forked to $to" >&2

# fix up creator, default role permissions (gl-perms), and hooks
cd $GL_REPO_BASE/$to.git
echo $GL_USER > gl-creator

gitolite query-rc -q LOCAL_CODE && ln -sf `gitolite query-rc LOCAL_CODE`/hooks/common/* hooks
ln -sf `gitolite query-rc GL_ADMIN_BASE`/hooks/common/* hooks

# record where you came from
echo "$from" > gl-forked-from

# cache control, if rc says caching is on
gitolite query-rc -q CACHE && perl -I$GL_LIBDIR -MGitolite::Cache -e "cache_control('flush', '$to')";

# trigger post_create
gitolite trigger POST_CREATE $to $GL_USER fork
