Open Source Without GitHub
Author: Alexander Avery
Posted: Fri | Aug 26, 2022
computer-scienceFor better or for worse, GitHub has become a ubiquitous part of open source software. In this post, I’m going to talk about how to break away from GitHub, and federalize open source.
The convenience of one platform
It’s impossible to deny that one of the reasons GitHub is so popular is likely because many features are packaged together. Forking projects, publishing personal repos, contributing changes, and tracking issues are all included on the platform. To break away from GitHub, I’ve personally had to give up some of this perceived convenience. My projects, hosted on a personal Gitea server, have issue tracking, pull requests, and forks. But, of course, no one would want to create yet another online account on my site to contribute changes.
Even if everyone hosted a personal Git server, Gitea isn’t the only option.
How can we manage to share code across disparate platforms or domains?
Though Git platforms may not be compatible, they all have a common interface: git
.
Decentralized Git is just Git
The trick is, Git has always been decentralized. As expected, Git has dozens of seldom known features that facilitate this. In the Git man page, in the HIGH-LEVEL COMMANDS section alone, I am willing to bet there is a ‘porcelain’ command you have never used or heard of. There are also low level ‘plumbing’ commands that are orthogonal and suited for things like scripting or building custom ‘porcelain’ commands.
As I dive into learning ’lesser known’ commands, I want to share with you git-request-pull
.
GitHub and other git platforms have successfully branded these terms to where I mistook this as a feature for creating ‘pull requests’ from git
.
It does indeed create a request to pull code, but has stark differences from what I and many others have learned from such Git hosting sites.
The command git-request-pull
is actually a very faithful Unix utility, here is its synopsis and description from the man page.
GIT-REQUEST-PULL(1) Git Manual GIT-REQUEST-PULL(1)
NAME
git-request-pull - Generates a summary of pending changes
SYNOPSIS
git request-pull [-p] <start> <url> [<end>]
DESCRIPTION
Generate a request asking your upstream project to pull changes into
their tree. The request, printed to the standard output, begins with
the branch description, summarizes the changes and indicates from where
they can be pulled.
The upstream project is expected to have the commit named by <start>
and the output asks it to integrate the changes you made since that
commit, up to the commit named by <end>, by visiting the repository
named by <url>.
When invoked as described, it writes a human-readable summary of changes to stdout. The output includes a log of commit messages, and the URI these changes can be pulled from.
Example time
‘Linus’ wants to share his changes to my server
Let’s say that Linus, on the domain https://git.ko.xz
, wants to post changes to the neon-harvest master branch.
First, Linus pulls the repo and makes changes locally in his branch named updated-footer
.
Once complete, he is unable to simply git push
them back up, however, he can push to git.ko.xz/linus/neon-harvest
updated-footer
.
To get these changes reviewed, Linus can simply email me, including the output from git request-pull
:
# begin the email with subject and recipient
echo 'Subject: Updated footer for neon-harvest theme' > pull-request.eml
echo -e 'To: Alexander Avery <alex.avery@beetbox.io>\n' >> pull-request.eml
# add the request-pull text to the email
git request-pull master \
https://git.ko.xz/linus/neon-harvest updated-footer >> pull-request.eml
# send the email
msmtp -t < pull-request.eml
Here is what we would expect pull-request.eml to look like:
Subject: Updated footer for neon-harvest theme
To: Alexander Avery <alex.avery@beetbox.io>
The following changes since commit 749a0b7c5ebb4df764f2b41632f4b7bc79561b2a:
smaller code font-size (2022-07-12 21:25:23 -0400)
are available in the Git repository at:
https://git.ko.xz/linus/neon-harvest updated-footer
for you to fetch changes up to 005ad4ad23028c4ff4dce6240d0163b7c01bf4ed:
modified footer (2022-08-24 22:08:10 -0400)
----------------------------------------------------------------
Linus (2):
modified scss
modified footer
assets/sass/main.scss | 6 +++---
layouts/_default/single.html | 19 +++++++++++--------
2 files changed, 14 insertions(+), 11 deletions(-)
That is all a contributor needs to do to get his or her changes to the ‘original maintainer’.
Time for me to incorporate the changes
Upon reading this nicely formatted email, I know the URI and branch from which to fetch changes. To consider and merge the changes, I can do something like the following:
# add the server provided by Linus as a remote
git remote add linus https://git.ko.xz/linus/neon-harvest
# fetch remote changes from Linus into a local branch called 'uf'
git fetch linus updated-footer:uf
# checkout the branch, run tests, decide if I want to merge or update
git checkout uf
# switch to master branch and merge in changes
# --rebase, --squash or whatever you prefer
git checkout master && git merge uf
# remove the new remote unless I expect Linus to be a regular contributor
The other missing features (they are hiding in other programs)
Earlier, we discussed other features that these Git platforms tie together, such as issue tracking. These could also be handled by email, perhaps by a dedicated mailbox that copies issues to your preferred issue tracking.
The ‘social’ parts of GitHub and similar platforms are missing too, but we gain freedom of choice.
Just because GitHub handles all its communication on the platform, we don’t have to!
The output of git-request-pull
is not tied to SMTP, so we can get creative.
Requests can be sent via IRC, XMPP, Matrix, Mastodon, or anything, not just email.
Once we give up having pull requests integrated into our repos, we are given the power to receive requests from anywhere we choose.
Text really is the universal interface.
It’s also more Unix Philosophy friendly, a Git server doesn’t really need to be anything more than a Git server.
If you are running your own, it can be as full-featured or as lightweight as you want.
I will always suggest mastering the fundamentals, and git
is just one example of a sharp tool that, which most people only utilize for about 6 commands.
The Git iceberg runs cold and deep. If this interests you, you may want to check out:
- githooks(5)
- giteveryday(7)
- git porcelain commands
- git plumbing commands
Next: I Love Errors
Previous: Ruby Footguns
>> Home