[Simon Tatham, 2025-03-05]
- Introduction
- How to interact with a bare git repo
- Why don’t I use a git forge?
- Should I start using a git forge instead?
Introduction
I’ve written quite a lot of free software in my life. Most of
it was from scratch: projects I started myself. So I get to
choose where to host them – or rather, I have to choose
where to host them.
These days, all my projects are held in Git. And mostly, I put
them in ‘bare’ git repositories on my personal website.
I don’t use any git ‘forge’ system layered on top of Git, like
Gitlab or Github, which automatically makes a bug tracking
database for each project, and provides a convenient button for
a user to open a merge request / pull request. I just use plain
Git. People can ‘git clone
’ my code, and there’s a
web-based browsing interface (the basic gitweb
) for
looking around without having to clone it at all. But that’s all
the automated facilities you get.
Occasionally this confuses people, so I thought I should write
something about it.
Purposes of this article
Sometimes people just can’t work out how to send me patches at
all. Or they can think of several ways, and aren’t sure which is
best. So one purpose of this article is to be a public statement
of my own preferences, which I can link to when people ask that
question.
But it’s also a bit of a musing about why I don’t use
a ‘forge’ style system like Gitlab or Github. People sometimes
ask me that too – “why don’t you do what everyone else does?” or
words to that effect.
How to interact with a bare git repo
People who are used to git forges look for a ‘pull request’
button. When they don’t find it, they sometimes get confused.
If you can’t find a button on a website to submit a patch, how
do you send your patch to the maintainer?
You send the author an email. And in the email, you put one of
these things:
- A URL to your own clone of the repository, containing your
patches on top of the ‘upstream’ code. - The actual patches, in some form of email attachment.
Either of these works. For option 2 there are multiple ways to
do it in detail, and all of those work too.
It doesn’t have to be by email, either. Any method of sending
this data to the maintainer is fine. For example, I’m on
Mastodon – so you could send me a repository URL via Mastodon if
you really wanted to (provided you didn’t mind my responses
being very short). Or you could send patches via any other
communications medium that you and the maintainer are both on,
if it lets you attach files to messages.
What do I prefer in particular?
But some people don’t just want to know any way to
send patches. They want to know which is the best way,
or at least the way I prefer.
So here’s my own list, in descending order: most preferred at
the top, least at the bottom.
BEST: URL of a git repository + branch name
This is my absolute favourite way to receive patches.
If there’s anywhere on the Internet you can put a clone of my
git repository with some extra patches, then the best thing is
to do that, and send me an email saying something like
I have some patches to [project] to [make some change]. You
can find them in the branch called [whatever] here: [URL]
The URL can be anything that’s convenient, as long as it’s
either something I can give to git clone
, or a
human-readable web page containing something I can give
to git clone
. It can be anything from a git forge
page (just because I don’t host my code on Github
doesn’t mean you can’t put your patched version there for me to
look at) to a static site where you’ve uploaded a repository and
run git update-server-info
.
When you get right down to it, this is exactly what the
formalised ‘pull request’ or ‘merge request’ in a git forge
system is. That’s why you start by forking (i.e.
cloning) the target repository and put your changes in a branch
of your fork. A PR communicates to the maintainer: “Hey, see
this repo over here, this branch in particular? It has changes
I’d like you to take.” The formal PR button in a forge is a way
to do that with one click, but a short email with all the same
information is just as good.
Why I like it: This is my favourite way to receive
patches because the patches themselves don’t go through my
email. This saves space for me in the long term (I keep all my
email), and it saves me messing about with moving attachments
around (I read email on a different machine from the one I
develop on). All I need is to paste the URL from the email into
my git command line, and bing, I’ve got the patches in a form I
can look at, review, and maybe merge.
Also, if I make review comments and you want to update the
patches, it saves space again if you don’t have to send
a full set of updated patch files, but instead, push a modified
version of your branch and just send another email saying
OK, I’ve addressed those review comments. New patches are in
the same place as before.
An incremental git bundle
Git bundles don’t seem to be very widely known. I think that’s
a shame, because they’re awesome.
The simplest kind of git bundle – a full bundle – is a
whole git repository, wrapped up into a single file. It contains
a
16 Comments
ndegruchy
This is what I love about Fossil[1]. You get all of those extra tools (wiki, chat, forums, bug tracker) in the server that is also in the binary that you use to manage the repo.
So, if you want to serve it, just `fossil server file.fossil` or serve a whole directory of them. Or, if you want, you can just `fossil ui` and muck around yourself, locally. The server supports SSH and HTTPS interactions for cloning and pushing.
All by the same people who make SQLite, Pikchr, and more.
[1]: https://fossil-scm.org
AndrewDucker
For some context, Simon is the maintainer of PuTTY, as well as various other cool bits of software.
MaxBarraclough
This reminds me of Drew DeVault's advocacy for the traditional email-driven git workflow. [0][1] (Drew is the creator of SourceHut, an email-oriented git forge.)
I think his (Simon's) objection to git send-email emails could be addressed with better tooling, or better use of them. It's 'just' a matter of exporting the emails into a single mailbox file, right? (I'm not experienced with git's email-driven features.)
It seems to work smoothly for the Linux kernel folks; clearly it doesn't have to be clunky.
> because git format-patch doesn’t mention what commit the patches do apply against, I’m more likely to encounter a conflict in the first place when trying to apply them.
This is what the –base flag is for. [2]
[0] https://git-send-email.io/
[1] https://git-am.io/
[2] https://git-scm.com/docs/git-format-patch#Documentation/git-…
fsdkfdsf
[flagged]
IshKebab
> Sometimes people just can’t work out how to send me patches at all.
Yeah indeed. I have written but not submitted patches to a project (OpenSBI) because it made the submission process super complicated, requiring signing up to a mailing list, learning how to set up git send-email.
I don't see how he can think creating a GitHub account (which almost everyone already has) is a big barrier when he freely admits his process is incomprehensible.
I don't buy the GitHub locks you in either. It's pretty easy to copy issues and releases elsewhere if it really comes to it. Or use Gitlab or Codeberg if you must.
https://docs.codeberg.org/advanced/migrating-repos/
Any of those are far better than random mailing lists, bugzilla, and emailed patch files.
Putty is great but please don't listen to this.
etaweb
> In particular, your project automatically gets a bug tracker – and you don’t get a choice about what bug tracker to use, or what it looks like. If you use Gitlab, you’re using the Gitlab bug tracker. The same goes for the pull request / merge request system.
With Forgejo (Codeberg) you can toggle features such as pull requests, issues, etc.
You can also configure any external issue tracker or wiki apparently, though I've never tried it, because those included with the forge are good enough for me.
adastra22
The way he prefers patches to him being sent (git repo URL + branch name) is basically what a forge does. Why make it more complicated for your users?
throw94040
》The simplest kind of git bundle – a full bundle – is a whole git repository, wrapped up into a single file.
Git repo can have executable code! Git hooks are shell commands stored in dir ".git/hooks" executed on events such as merge, commit… That is not duplicated by git clone, I am not sure about bundles. But I would be VERY careful to accept something like compressed git repo from anyone!
zem
as someone who finds the whole forge interface a massive improvement in git collaboration workflow I was fully prepared to find the author's arguments against a lightweight self hosted forge unconvincing. but the "need to create an account" is an extremely valid drawback, and one I do not have a good answer to.
aard
I very much support this sentiment! If we want a decentralized internet, we need to stop relying on large companies to manage everything for us. Git was designed to be a p2p system, but we very quickly centralized it with forges like Github. It is very discouraging. Most of the internet is like this now–managed by a handful of very powerful organizations. There is no end to the problems this will cause.
wahern
> People can ‘git clone’ my code, and there’s a web-based browsing interface (the basic gitweb) for looking around without having to clone it at all.
I host my own public Git repositories, but statically–read-only, no HTML views. I don't want to run any specialized server-side code, whether dynamic or preprocessed, as that's a security vector and system administration maintenance headache I don't want to deal with. You can host a Git repository as a set of static files using any web server, without any special configuration. Just clone a bare repo into an existing visible directory. `git update-server-info` generates the necessary index files for `git clone https://…` to work transparently. I add a post-receive hook to my read-write Git repositories that does `cd /path/to/mirror.git && git fetch && git –bare update-server-info` to keep the public repo updated.
In theory something like gitweb could be implemented purely client-side, using JavaScript or WASM to fetch the Git indices and packs on-demand and generate the HTML views. Some day I'd like to give that a try if someone doesn't beat me to it. You could even serve it as index.html from the Git repository directory, so the browser app and the Git clone URL are identical.
paulddraper
I was expecting the justification to be a stodgy get of my lawn rant.
But the author does a very good and reasonable job of explaining it.
It didn't convince me to do the same thing, but I can't help but nod along to the even-handed pros and cons that he lays out.
rlpb
> Multiple files to herd. When I get an email with five patch attachments, I have five files to copy around instead of one, with long awkward names.
That’s not correct. You can write the email to an mbox file (your MUA lets you do that, right?) and then use `git am` to pull it all into git.
> Why I don’t like it: because the patch series is split into multiple emails, they arrive in my inbox in a random order, and then I have to save them one by one to files, and manually sort those files back into the right order by their subject lines.
The patch series arrives threaded, so your MUA should be able to display them in order. Export them to an mbox file, and then use `git am` again.
There might be ways that someone can send you email in this way and for the patches to be broken such that `git am` won’t work, of course. I take no issue with that part of the argument.
agf
Gotta plug the Portable Puzzle Collection, by the same author as this post: https://www.chiark.greenend.org.uk/~sgtatham/puzzles/
oneplane
I wonder if (especially after finishing the bottom part of the article) a mailing list type of interaction, but with Git, is exactly the sort of "in the open" version that is described as a potential improvement.
I'm not sure to what degree that natively allows for integration between Git and an MTA but it would still have most of the desired aspects.
ajross
The security analysis in this piece is awful. Basically, author uses git because they don't trust "forges", then proceeds to discuss how a direct attack against the repository history is very hard but "not impossible"[1], while failing to recognize that the by-far-most-robust protection against such an attack is to push it to MORE repositories and MORE clones hosted by MORE entities and not keeping it secret on… your own piece of random hardware you probably got from Amazon.
The rest of it is reasonable advice as far as it goes. Learn how to replicate patches between raw repositories as a good practice, as you'll want to be able to do that anyway. Don't lean too hard on the GitHub abstraction of a "Pull Request" as that won't match what kernel people want, etc…
[1] Technically true, but in practice a ridiculous whopper.