2012-05-08-gitolite-quick-and-dirty-mirror.html (7211B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <!-- Sep 03, 2024 --> 5 <meta charset="utf-8" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1" /> 7 <title>Gitolite quick and dirty mirror</title> 8 <meta name="author" content="Vincent Demeester" /> 9 <meta name="generator" content="Org Mode" /> 10 <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> 11 <meta name='viewport' content='width=device-width, initial-scale=1'> 12 <link rel='stylesheet' href='/css/new.css' type='text/css'/> 13 <link rel='stylesheet' href='/css/syntax.css' type='text/css'/> 14 <link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' /> 15 </head> 16 <body> 17 <main id="content" class="content"> 18 <header> 19 <h1 class="title">Gitolite quick and dirty mirror</h1> 20 </header><section id="outline-container-Introduction" class="outline-2"> 21 <h2 id="Introduction">Introduction</h2> 22 <div class="outline-text-2" id="text-Introduction"> 23 <p> 24 I’m running a gitolite <span class="underline">instance</span> on my personal server to manage my repositories 25 (personnal, private or public) ; and I am quickly going to share with you how I setup a 26 <span class="underline">quick and dirty</span> mirror feature. 27 </p> 28 29 <p> 30 First, I am using <b><b>gitolite 3</b></b>. The mirroring we are going to setup is not the 31 <span class="underline">supported</span> <a href="http://sitaramc.github.com/gitolite/mirroring.html">mirroring <b>built-in</b></a>. We are going to implement a simplier way to set mirror 32 thing : 33 </p> 34 35 <ol class="org-ol"> 36 <li>Write a custom gitolite command ; the idea is to be able to write <code>git-config</code> stuff.</li> 37 <li>Write a hook that take a specific <code>git-config</code> (let say <code>mirror.url</code>) and do a simple 38 mirroring.</li> 39 </ol> 40 </div> 41 </section> 42 <section id="outline-container-Gitolite%20commands" class="outline-2"> 43 <h2 id="Gitolite%20commands">Gitolite commands</h2> 44 <div class="outline-text-2" id="text-Gitolite%20commands"> 45 <p> 46 Gitolite 3 has been rewritten to be more flexible : <a href="http://sitaramc.github.com/gitolite/g3why.html">Why a completely new version</a>. The 47 rewrite made it really easy to extend gitolite. <del>I’ve fork <a href="https://github.com/vdemeester/gitolite">gitolite</a> on github</del> I’ve 48 created a <a href="http://github.com/vdemeester/vdemeester-gitolite-local-code">repository git</a> to easily add commands to my gitolite instance via <span class="underline">local 49 code</span>. The gitolite command I wrote is a quick and dirty script in shell to add <code>git 50 config</code>. The source should speek for itself ; It <span class="underline">should</span> include some way to check if the 51 given config is not already present in the <code>gitolite-admin</code> configuration file — and so 52 might be rewritten in <code>Perl</code>. 53 </p> 54 55 <p> 56 The command is <code>write-git-config</code> because a <code>git-config</code> command already exists 57 in the built-in commands. 58 </p> 59 60 <div class="org-src-container"> 61 <pre class="src src-bash">#!/bin/sh 62 63 # Usage: ssh git@host write-git-config <repo> <key> <value> 64 # 65 # Set git-config value for user-created ("wild") repo. 66 67 die() { echo "$@" >&2; exit 1; } 68 usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; } 69 [ -z "$1" ] && [ -z "$2" ] && [ -z "$3" ] && usage 70 [ "$1" = "-h" ] && usage 71 [ -z "$GL_USER" ] && die GL_USER not set 72 73 # ---------------------------------------------------------------------- 74 repo=$1; shift 75 key=$1; shift 76 value=$1; shift 77 78 # this shell script takes arguments that are completely under the user's 79 # control, so make sure you quote those suckers! 80 81 if gitolite query-rc -q WRITER_CAN_UPDATE_DESC 82 then 83 gitolite access -q "$repo" $GL_USER W any || die You are not authorised 84 else 85 gitolite creator "$repo" $GL_USER || die You are not authorised 86 fi 87 88 # if it passes, $repo is a valid repo name so it is known to contain only sane 89 # characters. This is because 'gitolite creator' return true only if there 90 # *is* a repo of that name and it has a gl-creator file that contains the same 91 # text as $GL_USER. 92 93 configfile=`gitolite query-rc GL_REPO_BASE`/"$repo".git/config 94 95 git config --file "$configfile" "$key" "$value" 96 </pre> 97 </div> 98 </div> 99 </section> 100 <section id="outline-container-Gitolite%20hooks" class="outline-2"> 101 <h2 id="Gitolite%20hooks">Gitolite hooks</h2> 102 <div class="outline-text-2" id="text-Gitolite%20hooks"> 103 <p> 104 The next step is to write a quick <code>post-receive</code> hook that check if there is a 105 certain <code>git-config</code> entry and run <code>git push --mirror</code>. The file is in 106 <code>$HOME/.gitolite/hooks/common/post-receive</code> ; you could add a better system to 107 hooks (to be able to add “dynamic” hooks, …). 108 </p> 109 110 <div class="org-src-container"> 111 <pre class="src src-bash"> 112 #!/bin/sh 113 114 # Simple gitolite mirroring 115 116 # flush STDIN coming from git, because gitolite's own post-receive.mirrorpush 117 # script does the same thing 118 [ -t 0 ] || cat >/dev/null 119 120 [ -z "$GL_REPO" ] && die GL_REPO not set 121 122 target=`git config --get mirror.url` 123 [ -z "$target" ] && exit 0 124 125 # Support a REPO variable for wildcard mirrors 126 gl_repo_escaped=$(echo $GL_REPO | sed 's/\//\\\//g') 127 target=$(echo $target | sed -e "s/REPO/$gl_repo_escaped/g") 128 129 # Do the mirror push 130 git push --mirror $target 131 </pre> 132 </div> 133 134 <p> 135 The next, and final step is to run `gitolite compile` to update links to hooks 136 for every repositories. 137 </p> 138 </div> 139 </section> 140 <section id="outline-container-For%20real" class="outline-2"> 141 <h2 id="For%20real">For real</h2> 142 <div class="outline-text-2" id="text-For%20real"> 143 <p> 144 And finaly, this is the final step you’ll do. 145 </p> 146 147 <div class="org-src-container"> 148 <pre class="src src-bash">$ ssh git@host write-git-config vincent/vcsh-home mirror.url git@github.com:vdemeester/vcsh-home.git 149 $ git push 150 Counting objects: 5, done. 151 Delta compression using up to 2 threads. 152 Compressing objects: 100% (3/3), done. 153 Writing objects: 100% (3/3), 294 bytes, done. 154 Total 3 (delta 2), reused 0 (delta 0) 155 remote: To git@github.com:vdemeester/vcsh-home.git 156 remote: 65681a8..701c990 master -> master 157 To git@host:vincent/vcsh-home.git 158 65681a8..701c990 master -> master 159 </pre> 160 </div> 161 162 163 <p> 164 And that should be it ! 165 </p> 166 167 <p> 168 <span class="underline">Update 2012/10/04</span> : Moved from gitolite fork to <span class="underline">gitolite local code</span> 169 repository. 170 </p> 171 </div> 172 </section> 173 </main> 174 <footer id="postamble" class="status"> 175 <footer> 176 <small><a href="/" rel="history">Index</a> • <a href="/sitemap.html">Sitemap</a> • <a href="https://dl.sbr.pm/">Files</a></small><br/> 177 <small class='questions'>Questions, comments ? Please use my <a href="https://lists.sr.ht/~vdemeester/public-inbox">public inbox</a> by sending a plain-text email to <a href="mailto:~vdemeester/public-inbox@lists.sr.ht">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/> 178 <small class='copyright'> 179 Content and design by Vincent Demeester 180 (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) 181 </small><br /> 182 </footer> 183 </footer> 184 </body> 185 </html>