I'm a person who often stops (or never starts) work on projects because another related project hasn't been completed. I often think to myself "I can't work on X because I haven't finished Y yet". One such project that's been holding me back, a pretty basic requirement for some things I'd like to do, is that I don't have a satisfactory place to publish source code.
I recently solved that problem. I figured out how to serve Git repositories over so-called "dumb HTTP" and then I wrote a clone of Hiltjo Posthuma's stagit as a plugin for my static site compiler Blogofile. I'm calling that plugin blogofile_gitview. Read on to see why I'd do such a foolish thing.
Publishing and Browsing Source Code
This is really two problems: publishing code, and browsing code through a convenient web frontend. The way most people go about this is to use one of the major git repository hosts like GitHub, GitLab, or Sourcehut. I'm not a big fan of these, and ever since Microsoft purchased GitHub I've been staying away from them.
Another method, one I like more and have chosen to implement, is to self-host Git repositories using the HTTP protocol as outlined by the Git documentation. I'm currently serving read-only "dumb HTTP" repos. Not ideal, but good enough for distributing source projects with a small number of contributors (i.e. just me). This solves the first problem.
The second part of the problem, browsing code, is also fairly easy to solve. Stagit and git-arr are both programs that generate static HTML files for browsing a Git repository. Neither stagit or git-arr were quite right for me, though. Both would have required a lot of alteration to work the way I want. So I chose to re-write stagit as a Python script, a plugin (or in this case a "controller") for my static site compiler Blogofile.
Stagit and _controllers/gitview.py
Stagit uses libgit2 to interface with and handle Git repositories. It was convenient then to use pygit2, the Python bindings for libgit2, for this project. I frequently referred to stagit.c, stagit-index.c, and the pygit2 documentation while working; my script is mostly a copy of stagit.c. Translating from C libgit2 to Python pygit2 calls was not one-to-one, exactly, there were a few confusing moments, but it wasn't too difficult.
You can find my script at _controllers/gitview.py. It's relatively short and should be easy enough to read, so I won't go over it in detail here. There's a README to go with the project with information on installation and usage. Both Blogofile and stagit are available under the MIT License and so I've licensed blogofile_gitview the same.
There are significant differences between my script and stagit, of course. My script does syntax highlighting (with Pygments) and uses Mako templates to format the output HTML (both features borrowed from Blogofile). And I would say my script is much slower than stagit due to the choice of language and features.
Possible Improvements and Considerations
The script should avoid re-building files for a repository that hasn't changed. I can see an easy way to do that, so I'll implement that soon (or when it becomes a problem for me).
The script could be expanded into a full Blogofile "plugin", similar to the blogofile_blog code, though I don't think I'll ever have a reason to do that myself.
blogofile_gitview has only been tested with pretty simple repositories; it doesn't understand submodules or complex multi-parent commits. It is going to scale badly with very large repositories. And obviously there are none of the dynamic features of something like cgit or gitweb. This is to a degree intentional and by design, same as stagit.
I'm not really a programmer. I'm a tinkerer at best, a user that knows enough to get into trouble. I had no idea how Git works two weeks ago. There are probably many errors and mistakes hiding in those 400-some lines of script.
I don't think blogofile_gitview will be useful to anyone else, it's a small program written for a very specific purpose. (And is mostly a copy of somebody else's work anyway). Maybe it could be adapted for use with Pelican or one of the other Python-based site compilers.
But that's all fine. My goal was to have a place to publish source code and a convenient code browser that integrates with my website. I think I've accomplished that.
So now I can publish the rat's nest of Bourne shell scripts I have.
If you've written a response to this post then please let me know the URL:
You can also submit a "comment" webmention by pressing the button below. It may take a day or two for your comment to appear here and a copy of your comment will be stored at commentpara.de.