2012-04-22 06:04:06 +02:00
|
|
|
#!/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.
|
|
|
|
#
|
|
|
|
# The only caveat is that the repo you cloned *from* must not later become
|
|
|
|
# unavailable in any way. If you cannot be sure of this, take the scenic
|
|
|
|
# route (clone repo1, push to repo2).
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
if gitolite query-rc -q DEFAULT_ROLE_PERMS
|
|
|
|
then
|
|
|
|
gitolite query-rc DEFAULT_ROLE_PERMS > gl-perms
|
|
|
|
fi
|
|
|
|
|
|
|
|
ln -sf `gitolite query-rc GL_ADMIN_BASE`/hooks/common/* hooks
|
|
|
|
|
|
|
|
# record where you came from
|
|
|
|
echo "$from" > gl-forked-from
|
|
|
|
|
|
|
|
# trigger post_create
|
POST_CREATE efficiency... (please read below if you care)
The POST_CREATE trigger is called when
* a user creates a new "wild" repo,
* a user uses the "perms" command, and
* a user uses the "fork" command.
The trigger calls 3 programs (see rc file):
post-compile/update-git-configs
post-compile/update-gitweb-access-list
post-compile/update-git-daemon-access-list
(They are also called by the POST_COMPILE trigger, by the way.)
However, the 3 programs shown are a bit wasteful -- they run through
*all* the repos when really only *one* repo has been affected.
This patch
* passes the repo name to the 3 programs (duh!)
* adds the optimisation to the first of the 3 programs listed above
(the one dealing with 'git config').
For the other two programs (gitweb and git-daemon), you have 3 choices:
* if you don't have too many repos, ignore the problem.
* take out the 2nd and 3rd lines from the POST_CREATE list in the rc
file, so they don't run.
Then run 'gitolite trigger POST_COMPILE' from cron at regular
intervals. (Note that is POST_COMPILE not POST_CREATE!) However,
this means that gitweb and daemon permissions won't be current
immediately after someone adds a new repo or sets perms etc.; they
get updated only on the next cron run.
* patch the programs to add this optimisation (and send me the
patches). The optimisation would check if arg-1 ($1 in shell,
$ARGV[0] in perl) is 'POST_CREATE', and if it is, take the *next*
argument as a repo name that may have changed.
2012-04-22 17:55:54 +02:00
|
|
|
gitolite trigger POST_CREATE $to $GL_USER
|