Gitolite quick and dirty mirror
Published on May 08, 2012 by Vincent Demeester.
Introduction
I’m running a gitolite instance on my personal server to manage my repositories (personnal, private or public) ; and I am quickly going to share with you how I setup a quick and dirty mirror feature.
First, I am using gitolite 3. The mirroring we are going to setup is not the supported mirroring built-in. We are going to implement a simplier way to set mirror thing :
- Write a custom gitolite command ; the idea is to be able to write
git-config
stuff. - Write a hook that take a specific
git-config
(let saymirror.url
) and do a simple mirroring.
Gitolite commands
Gitolite 3 has been rewritten to be more flexible : Why a completely new version. The
rewrite made it really easy to extend gitolite. I’ve fork gitolite on github I’ve
created a repository git to easily add commands to my gitolite instance via local
code. The gitolite command I wrote is a quick and dirty script in shell to add git
config
. The source should speek for itself ; It should include some way to check if the
given config is not already present in the gitolite-admin
configuration file — and so
might be rewritten in Perl
.
The command is write-git-config
because a git-config
command already exists
in the built-in commands.
#!/bin/sh # Usage: ssh git@host write-git-config <repo> <key> <value> # # Set git-config value for user-created ("wild") repo. die() { echo "$@" >&2; exit 1; } usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } [ -z "$1" ] && [ -z "$2" ] && [ -z "$3" ] && usage [ "$1" = "-h" ] && usage [ -z "$GL_USER" ] && die GL_USER not set # ---------------------------------------------------------------------- repo=$1; shift key=$1; shift value=$1; shift # this shell script takes arguments that are completely under the user's # control, so make sure you quote those suckers! if gitolite query-rc -q WRITER_CAN_UPDATE_DESC then gitolite access -q "$repo" $GL_USER W any || die You are not authorised else gitolite creator "$repo" $GL_USER || die You are not authorised fi # if it passes, $repo is a valid repo name so it is known to contain only sane # characters. This is because 'gitolite creator' return true only if there # *is* a repo of that name and it has a gl-creator file that contains the same # text as $GL_USER. configfile=`gitolite query-rc GL_REPO_BASE`/"$repo".git/config git config --file "$configfile" "$key" "$value"
Gitolite hooks
The next step is to write a quick post-receive
hook that check if there is a
certain git-config
entry and run git push --mirror
. The file is in
$HOME/.gitolite/hooks/common/post-receive
; you could add a better system to
hooks (to be able to add “dynamic” hooks, …).
#!/bin/sh # Simple gitolite mirroring # flush STDIN coming from git, because gitolite's own post-receive.mirrorpush # script does the same thing [ -t 0 ] || cat >/dev/null [ -z "$GL_REPO" ] && die GL_REPO not set target=`git config --get mirror.url` [ -z "$target" ] && exit 0 # Support a REPO variable for wildcard mirrors gl_repo_escaped=$(echo $GL_REPO | sed 's/\//\\\//g') target=$(echo $target | sed -e "s/REPO/$gl_repo_escaped/g") # Do the mirror push git push --mirror $target
The next, and final step is to run `gitolite compile` to update links to hooks for every repositories.
For real
And finaly, this is the final step you’ll do.
$ ssh git@host write-git-config vincent/vcsh-home mirror.url git@github.com:vdemeester/vcsh-home.git $ git push Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 294 bytes, done. Total 3 (delta 2), reused 0 (delta 0) remote: To git@github.com:vdemeester/vcsh-home.git remote: 65681a8..701c990 master -> master To git@host:vincent/vcsh-home.git 65681a8..701c990 master -> master
And that should be it !
Update 2012/10/04 : Moved from gitolite fork to gitolite local code repository.