Self Hosting Git Repositories with Stagit
An alternative to hosting your source code on forges like Github is use your own server. This commonly involves running git as a daemon and deploying a web interface such as gitea, gitlab, cgit, or sourcehut. These projects essentially serve web applications that interface with the git server.
However, if you’re not hosting large, established projects with frequent contributors, these options are probably overkill. Another option I came across recently is stagit. Unlike the aforementioned projects, stagit does not serve dynamic web content; it’s a C program that traverses git repositories using libgit2 and writes data to HTML files as it reads it. It doesn’t run constantly and listen for filesystem changes, but is instead invoked manually or as a git hook.
A quick tour of Stagit
The index page sits atop a collection of repositories. It displays the name, description, owner, and last commit date of each repository with a link to each.
The log page is the default page that you arrive at when you visit a repository from the index page. It shows the same information you would see running
git log in a repository on the master branch.
A listing of all files on the latest commit of the master branch, alongside filesizes and file modes. It didn’t occur to me before seeing this that git has account for file permissions.
A list of all branches and tags pushed to the server. You can see them listed out here, but you can’t actually browse anything other than master.
In order to display other branches, Stagit would need to write a ton of additional pages, and it’s very likely that other branches would very rarely be used.
Instead, if you want to view repository history related to other refs, you’re expected to just clone it and look locally.
I think it’s an excellent tradeoff.
The README file, if present, is readable in text form on a dedicated page. It’s probably the first thing you want to read, so it definitely deserves the real estate.
The license, if present, is important enough to get its own dedicated page. It’s crucial to highlight this information so that visitors intending to leverage code from the repository know the terms.
Running the Program
Stagit consists of two commands:
stagit-index,which produces an index page that points to all your repositories, and
stagit, which builds HTML pages for a single repository.
Using them works as follows: you first run
stagit-index passing in all of your git repositories as command line arguments, and then run
stagit separately for each individual repository. There’s a shell script in the stagit repo that will do both of these for you.
This will create the HTML pages that describe the current state of all repositories, but it won’t update them for you when the repositories change. For this, you use git’s server-side post-receive hook to update HTML pages for the index and the repository receiving the commit. Stagit provides another sample script that you can tweak and use for this as well.
I’m maintaining a fork of stagit that I use for my personal git server.
Update: I’ve since moved off my VPS and no longer run the git server.
Below is an overview of the features I added in.
Changes to READMEs
The first thing I customized was to have repositories open straight to the README from the index page. If there is no README, it opens the log page just like upstream.
I also leaned on md4c to parse markdown into HTML instead of plaintext because I think it’s useful to be able to display screenshots and links.
Syntax Highlighting on Files with Customized Colors
Instead of just writing out plaintext file contents, I changed stagit to use chroma to output HTML with syntax highlighting. To support this use, I upstreamed a small enhancement to the chroma repository that allows you to use linkable lines in HTML output.
Finally, I changed Stagit’s light and dark themes to match the themes I use on my blog.
Stagit’s HTML pages appear to be designed with careful thought as to what someone viewing a repository would be interested in quickly learning. The commit log, README, files, license, and repository URL are never more than a click away, and the interface is free from clutter.
The source code is very clear and readable. I was able to understand and modify it without significant C experience and the codebase was a pleasure to work with.
Definitely give Stagit a try if you’re interested. You may want to read through the documentation’s list of pros and cons to make sure it fits your needs.