2012-05-08-gitolite-quick-and-dirty-mirror.org (4427B)
1 #+title: Gitolite quick and dirty mirror 2 #+date: <2012-05-08 Tue> 3 #+filetags: gitolite git linux mirror github 4 #+setupfile: ../templates/post.org 5 6 * Introduction 7 8 I'm running a gitolite _instance_ on my personal server to manage my repositories 9 (personnal, private or public) ; and I am quickly going to share with you how I setup a 10 _quick and dirty_ mirror feature. 11 12 First, I am using **gitolite 3**. The mirroring we are going to setup is not the 13 _supported_ [[http://sitaramc.github.com/gitolite/mirroring.html][mirroring *built-in*]]. We are going to implement a simplier way to set mirror 14 thing : 15 16 1. Write a custom gitolite command ; the idea is to be able to write ~git-config~ stuff. 17 2. Write a hook that take a specific ~git-config~ (let say ~mirror.url~) and do a simple 18 mirroring. 19 20 * Gitolite commands 21 22 Gitolite 3 has been rewritten to be more flexible : [[http://sitaramc.github.com/gitolite/g3why.html][Why a completely new version]]. The 23 rewrite made it really easy to extend gitolite. +I've fork [[https://github.com/vdemeester/gitolite][gitolite]] on github+ I've 24 created a [[http://github.com/vdemeester/vdemeester-gitolite-local-code][repository git]] to easily add commands to my gitolite instance via _local 25 code_. The gitolite command I wrote is a quick and dirty script in shell to add ~git 26 config~. The source should speek for itself ; It _should_ include some way to check if the 27 given config is not already present in the ~gitolite-admin~ configuration file — and so 28 might be rewritten in ~Perl~. 29 30 The command is ~write-git-config~ because a ~git-config~ command already exists 31 in the built-in commands. 32 33 #+begin_src bash 34 #!/bin/sh 35 36 # Usage: ssh git@host write-git-config <repo> <key> <value> 37 # 38 # Set git-config value for user-created ("wild") repo. 39 40 die() { echo "$@" >&2; exit 1; } 41 usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } 42 [ -z "$1" ] && [ -z "$2" ] && [ -z "$3" ] && usage 43 [ "$1" = "-h" ] && usage 44 [ -z "$GL_USER" ] && die GL_USER not set 45 46 # ---------------------------------------------------------------------- 47 repo=$1; shift 48 key=$1; shift 49 value=$1; shift 50 51 # this shell script takes arguments that are completely under the user's 52 # control, so make sure you quote those suckers! 53 54 if gitolite query-rc -q WRITER_CAN_UPDATE_DESC 55 then 56 gitolite access -q "$repo" $GL_USER W any || die You are not authorised 57 else 58 gitolite creator "$repo" $GL_USER || die You are not authorised 59 fi 60 61 # if it passes, $repo is a valid repo name so it is known to contain only sane 62 # characters. This is because 'gitolite creator' return true only if there 63 # *is* a repo of that name and it has a gl-creator file that contains the same 64 # text as $GL_USER. 65 66 configfile=`gitolite query-rc GL_REPO_BASE`/"$repo".git/config 67 68 git config --file "$configfile" "$key" "$value" 69 #+end_src 70 71 * Gitolite hooks 72 73 The next step is to write a quick ~post-receive~ hook that check if there is a 74 certain ~git-config~ entry and run ~git push --mirror~. The file is in 75 ~$HOME/.gitolite/hooks/common/post-receive~ ; you could add a better system to 76 hooks (to be able to add "dynamic" hooks, …). 77 78 #+begin_src bash 79 80 #!/bin/sh 81 82 # Simple gitolite mirroring 83 84 # flush STDIN coming from git, because gitolite's own post-receive.mirrorpush 85 # script does the same thing 86 [ -t 0 ] || cat >/dev/null 87 88 [ -z "$GL_REPO" ] && die GL_REPO not set 89 90 target=`git config --get mirror.url` 91 [ -z "$target" ] && exit 0 92 93 # Support a REPO variable for wildcard mirrors 94 gl_repo_escaped=$(echo $GL_REPO | sed 's/\//\\\//g') 95 target=$(echo $target | sed -e "s/REPO/$gl_repo_escaped/g") 96 97 # Do the mirror push 98 git push --mirror $target 99 #+end_src 100 101 The next, and final step is to run `gitolite compile` to update links to hooks 102 for every repositories. 103 104 * For real 105 106 And finaly, this is the final step you'll do. 107 108 #+begin_src bash 109 $ ssh git@host write-git-config vincent/vcsh-home mirror.url git@github.com:vdemeester/vcsh-home.git 110 $ git push 111 Counting objects: 5, done. 112 Delta compression using up to 2 threads. 113 Compressing objects: 100% (3/3), done. 114 Writing objects: 100% (3/3), 294 bytes, done. 115 Total 3 (delta 2), reused 0 (delta 0) 116 remote: To git@github.com:vdemeester/vcsh-home.git 117 remote: 65681a8..701c990 master -> master 118 To git@host:vincent/vcsh-home.git 119 65681a8..701c990 master -> master 120 #+end_src 121 122 123 And that should be it ! 124 125 _Update 2012/10/04_ : Moved from gitolite fork to _gitolite local code_ 126 repository.