You don’t need GitHub

Like most programmers, I use git for version control. I’ve been using it since college, where we were introduced to it for working on shared projects as well as a consistent way to turn our code in.

There were a lot of things I didn’t get about git when I first started using it. If I needed to do anything besides simply add commits to a single branch in a linear fashion and push them to a remote, I got confused quickly. I would try to consult a guide or StackOverflow post, typing in commands I didn’t understand and usually I made a mess of things. I remember I would end up force-pushing to remote a lot, which I understood was a no-no, but at the time, the repositories I was working with were mine alone, so it didn’t really matter.

Now that I’ve used it for work and actually had to contend with things like stashes and branches and remotes over & over again, I feel like I’ve got a more stable handle on git than I used to. At the very least, I can do what I need to for work pretty reliably, and I know how to get myself out of the sticky spots well enough.

There’s one really interesting thing about git I didn’t understand until recently. When you push to a remote repository, such as those hosted on GitHub, there’s really nothing privileged about it compared to any other repository. The only difference is that it’s what’s called a “bare” repository, which means it doesn’t actually keep a working tree (the instantiation of a repo’s files on a given filesystem).

The upshot of this is that you can actually push & pull repositories from any machine you can SSH to that has git installed. So you don’t need to use a separate hosting service to store your code, especially if you’re mainly pushing it to pull it down onto another machine you have access to.

For example, I use git to deploy my website. When I wrote that post, I would always push my repository to tildegit, then log into the Ctrl-C server and pull it back down. Since learning this little tidbit, I ended up reworking my setup so that when I do a git push, it actually goes to tildegit and the ctrl-c server directly, so no additional pulling is necessary.

To make this work, I had to do two things. The first was to add an additional url to the origin remote:

git remote set-url --add --push origin ctrl-c:public_html

If you use this command, replace ctrl-c:public_html with your own hostname and repo path. In my case, I have the ctrl-c hostname configured to connect to the Ctrl-C server in my ~/.ssh/config file, and public_html is the directory the actual repository resides in, relative to my home directory on the Ctrl-C server.

The second thing was to update the config of the repository on the Ctrl-C server:

git config receive.denycurrentbranch updateInstead

Above, I mentioned that remote repositories on hosting services are “bare”, that is, they have no working tree. If you have a normal repository with a working tree, and you push an update to the branch it currently has checked out, it would normally deny your update. When you set this setting, it will update the repository instead.

If you use this approach to deploy websites or other files, it’s best to avoid making changes in the remote repository if you can. Also, there are more sophisticated ways to do this kind of thing, so don’t take this as expert advice. But at the very least, it’s a cool trick that suits my needs for deploying a personal site quite well.

Do you use git? Do you feel like you grasp it pretty well? Have you ever discovered a neat trick that helps your workflow? Have you tried managing git repositories in a similar way before? Let me know your thoughts at my Ctrl-C email: gome ​@ ​