home

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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.