You Probably Don't Need Microsoft Github

Microsoft's Github mixes a few different services into a single package:

Apart from the "social network" element, there were ways to use plain git and self-hosted servers to do all these things before github ever came along. And they all still work.

CI/CD and issue-trackers deserve their own posts, and if you want your people to click "like" on your code I recommend posting about it on mastodon. Below we'll talk about hosting private repos, hosting public repos, and accepting contributions.

You will need:

For my web server, I'm currently using the httpd that ships with OpenBSD.

Hosting your private git repos

First, ssh onto your server, and create a bare git repo in your home directory:

        localbox $ ssh me@myserver.com

        myserver $ mkdir -p ~/git/my-private-repo.git
        myserver $ cd ~/git/my-private-repo.git
        myserver $ git init --bare
      
In this example, I put my bare my-private-repo in a ~/git/ directory. I do this because I'm going to have a few of these git repos, and I like to keep them all in one place.

Now, on your local machine; find the git repo you want to host, set a sensible remote (like origin or notgithub) to point to your server, and push:

        localbox $ cd ~/path/to/my-private-repo
        localbox $ git remote rename origin github
        Renaming remote references: 100% (4/4), done.

        localbox $ git remote add origin me@myserver.com:git/my-private-repo.git

        localbox $ git remote -v
        github    git@github.com:myname/my-private-repo.git (fetch)
        github    git@github.com:myname/my-private-repo.git (push)
        origin    me@myserver.com:git/my-private-repo.git (fetch)
        origin    me@myserver.com:git/my-private-repo.git (push)

        localbox $ git push origin HEAD
        Enumerating objects: 2, done.
        Counting objects: 100% (2/2), done.
        Writing objects: 100% (2/2), 165 bytes | 165.00 KiB/s, done.
        Total 2 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
        To ../a/
         * [new branch]      HEAD -> main
      

Now you have a private git repo served from your own server. You can clone it with git clone me@myserver.com:git/my-private-repo.git

Hosting for your public git repos

If you already have your git repo on your server, then making it public is just a matter of allowing your web server to serve it.

There are two steps for a basic server:

  1. Put a copy of the bare repo somewhere your web server can see.
  2. Run git update-server-info

Put a copy where your web-server can see

How exactly to put your bare repo somewhere your web server can see will depend on exactly which webserver you're using. Since I'm using OpenBSD's httpd, for me that meant doing something like this:

        localbox $ ssh me@myserver.com

        myserver $ mkdir -p /var/www/htdocs/git/my-public-repo.git
        myserver $ cd /var/www/htdocs/git/my-public-repo.git
        myserver $ git init --bare
        myserver $ git remote add origin ~/git/my-public-repo.git
        myserver $ git pull
      

Run git update-server-info

Just having a copy of your git repo visible on the web isn't quite enough for someone to be able to git clone it. You also need to run this magic command:

        myserver $ cd /var/www/htdocs/git/my-public-repo.git
        myserver $ git update-server-info
        myserver $ mv hooks/post-update.sample hooks/post-update

      

Now, assuming that your web-server is configured to serve files from /var/www/htdocs/, anyone in the world can clone your git repo by running git clone https://www.myserver.com/git/my-public-repo.git

For more information on the magic git update-server-info command, I recommend running man git-update-server-info and reading the "Dumb HTTP" section of the server chapter of the git book. The post-update hook just runs that command every time this repo gets updated.

Accepting Pull Requests

Now that you've made a copy of your git repo available for anyone in the world to clone, I could clone it, and make some really cool changes that I want to share with you!

        grumpybox $ cd ~/cool-projects/
        grumpybox $ git clone https://www.myserver.com/git/my-public-repo.git
        grumpybox $ cd my-public-repo
        grumpybox $ ed README.md
        $
        a
        This project is hosted on a cool indie site, and not on
        github thanks to the awesome guide at https://grumpystack.uk
        .
        w
        q
        grumpybox $ git commit -m "Credit grumpystack with our cool indie git"
      

Now if I make my copy of that git repo available on my web server, I can email you and ask that you do a git pull https://grumpystack.uk/git/my-copy-of-your-public-repo.git

That's a real "pull request". It's a request that you run git pull.

Other bits and bobs

You can go further with all this, and most of your best options are well-documented in the git book.

I particularly want to quote this page though:

Many Git projects, including Git itself, are entirely maintained over mailing lists. Git has a number of tools built into it that help make this process easier, from generating patches you can easily email to applying those patches from an email box.

It shouldn't be a surprise that git came before github, and that git development is working just fine without github. But sometimes, maybe it's worth taking the time to remember that.


1
If you're still regularly using passwords to authenticate with your ssh server, I recommend you look into using ssh keys instead.