diff options
Diffstat (limited to '')
-rwxr-xr-x | src/triggers/partial-copy | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/triggers/partial-copy b/src/triggers/partial-copy new file mode 100755 index 0000000..79b4d48 --- /dev/null +++ b/src/triggers/partial-copy @@ -0,0 +1,69 @@ +#!/bin/sh + +# this is a wee bit expensive in terms of forks etc., compared to doing it in +# perl, but I wanted to show how *easy* it actually is now. And really, +# you'll only notice if you access this repo like a hundred times a minute or +# something so don't sweat it. + +# given a repo and a user, check if option('partialCopyOf') is set, and if so, +# fetch all allowed branches from there. + +die() { echo "$@" >&2; exit 1; } + +# make sure we're being called from the pre_git trigger +[ "$1" = "PRE_GIT" ] || die I must be called from PRE_GIT, not "$1" +shift + +repo=$1 +user=$2 +main=`git config --file $GL_REPO_BASE/$repo.git/config --get gitolite.partialCopyOf`; +[ -z "$main" ] && exit 0 + +# "we", "our repo" => the partial copy +# "main", "pco" => the one which we are a "partial copy of" + +cd $GL_REPO_BASE/$main.git + +for ref in `git for-each-ref refs/heads '--format=%(refname)'` +do + cd $GL_REPO_BASE/$repo.git + + gitolite access -q $repo $user R $ref && + git fetch -f $GL_REPO_BASE/$main.git $ref:$ref +done + +export GL_BYPASS_ACCESS_CHECKS=1 + +# remove all refs not in main or accessible +cd $GL_REPO_BASE/$repo.git + +for ref in `git for-each-ref refs/heads refs/tags '--format=%(refname)'` +do + cd $GL_REPO_BASE/$main.git + + if git show-ref --verify --quiet $ref && + gitolite access -q $repo $user R $ref ; then + # ref is present in main and accessible in repo + continue + fi + + git push -f $GL_REPO_BASE/$repo.git :$ref || die "FATAL: failed to delete $ref" +done + +# remove all tags no longer reachable +cd $GL_REPO_BASE/$repo.git + +for ref in `git for-each-ref refs/tags '--format=%(refname)'` +do + SHA=`git rev-list -1 $ref` + for branch in `git for-each-ref refs/heads '--format=%(refname)'` + do + if [ "`git merge-base $SHA $branch`" = "$SHA" ]; then + # tag is reachable in current branch, continue higher loop + continue 2 + fi + done + git push -f $GL_REPO_BASE/$repo.git :$ref || die "FATAL: failed to delete $ref" +done + +exit 0 |