#!/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