---
title: More git changes
packages: [ 'graphviz' ]
---

I've been getting bogged down in a lot of infrastructure stuff since the announcement that gitorious.org will be/has been made read-only. Rather than choosing another provider and going through this again in a few years' time, I've been setting up a self-hosted solution. It's taken me a while to come up with a system that I'm happy with, since I have the following goals:

 - Every repo should be clonable from a URL like `http://chriswarbo.net/git/foo.git`
 - I should be able to push to any repo via SSH
 - Nobody else should have write access (patches should be sent via git's email integration)
 - Every repo should have a basic Web interface at URLs like `http://chriswarbo.net/git/foo/`, eg. for browsing the code without cloning it
 - As much as possible should work offline
 - I shouldn't have to reorganise every project
 - There should be a separation between work in progress and "public" repos
 - Deployment should be as automatic as possible

I think I've achieved what I'm after. My current setup is the following:

```{pipe="dot -Tpng | base64 > graph.b64"}
digraph {
  WD [label="Working directory"]
  LR [label="Local repo"]
  OR [label="Online repo"]
  CW [label="chriswarbo.net/git"]
  OH [label="Online HTML"]
  WD -> LR [label="push"]
  LR -> OR [label="push"]
  OR -> CW [label="symlink"]
  OR -> OH [label="git2html"]
  OH -> CW [label="symlink"]
}
```

```{.unwrap pipe="sh | pandoc -f html -t json"}
F="graph.b64"
[[ -f "$F" ]] || {
  echo "Couldn't find git diagram '$F', aborting" 1>&2
  exit 1
}

printf '<img alt="Git setup" src="data:image/png;base64,'
cat "$F"
printf '" />'
```

 - **Working directories**
    - All the existing repos on my laptop
    - Private "work in progress" repos
    - Stay where they are, only the remote `origin` is changed to a local repo
 - **Local repos**
    - Bare clones of each working directory
    - "Pristine", as they only contain committed code
    - Remote `origin` set to online repo
    - `post-receive` hook pushes changes online
 - **Online repos**
    - Duplicates of the local repos, but on chriswarbo.net server
    - `post-receive` hook regenerates HTML
 - **Online HTML**
    - Static Web interface generated by git2html
 - **chriswarbo.net/git**
    - Contains symlinks to all online repos, of the form `foo.git/`
    - Contains symlinks to all online HTML, of the form `foo/`

As well as this, I've written a few scripts to make it easier to add new repos to this system; to regenerate all metadata/HTML/etc. for all repos; and so on. Ironically these aren't in git yet, but will be now that they've settled down.

I still need to automate the addition of READMEs to my [repos list](/projects/repos/index.html), but this looks pretty stable now :)
