Remember the 'D' in DVCS

2015-03-29 18:03

BerliOS, Gitorious, and now Google Code were all free source code hosting facilities that have succumbed to lack of funding, acquisition, or just changing corporate priorities. However it’s justified, this leaves individual developers and organizations scrambling to find an alternative within a few months’ time. Projects abandoned by their creators may never be migrated at all.

In 2015 the first alternative that comes to mind is probably Github, the wildly sucessful product arguably responsible git’s ubiquity. My code lived there for five years before I made the decision to leave. A free Github account can host unlimited public repositories, but if you want any private space to yourself it will cost you. A few dollars here and there don’t matter as much to me now as it did when I was a student, but I’m already paying my registrar ($10), DNS provider ($30), VPS host ($115), and certificate authority ($9) every year. $165 a year for all of that is a great deal, since I host this site, my email, XMPP, Mumble, and even a Quake server on this VPS and don’t mind a few administrative hours here and there. The price of a “Small” GitHub plan would add $120 to my yearly bill, nearly doubling it just so I can put some code in front of people on a web page, and all for a measly 10 private repositories. No thanks.

VCS exclusivity is another issue. This probably isn’t surprising considering ‘Git’ is right in the name, but what if I want to work with a Subversion or Mercurial repository? I won’t be doing it on GitHub. Atlassian’s Bitbucket has the edge in both of these cases, since they support Git and Mercurial and offer free personal private repositories, only charging for additional users, but they still leave you subject to Someone Else’s Platform. I don’t ever want to be unable to work or deploy “because GitHub is down”.

If GitHub, Bitbucket, SourceForge, and the rest are out, what can I replace them with? The obvious first choices are the web UIs built into the VCSs themselves, like Gitweb and hgweb, but they are pretty barren feature-wise and are totally separate environments from each other. SCM-Manager was nice for a few months, but it’s only good for viewing and pushing code since it’s just a thin interface around Gitweb and friends. In comparison, Github offers project wikis, issue trackers, pull requests, gists, and easy forking. The solution was staring me in the face at work every day in the form of Phabricator, a platform spun off from Facebook as open source.

Hosting Phabricator is not much more involved than hosting any other PHP web application. I usually create an IPv6-only FreeBSD Jail for an application like this then proxy_pass to it from nginx running in another jail. Phabricator wants to run its own sshd, though, so I had to give it an IPv4 address too:

jls -j phabricator
  1. JID IP Address Hostname Path
  2. 4 phabricator /usr/jails/phabricator

Phabricator and its command-line interface Arcanist are available as packages from devel/phabricator and devel/arcanist, respectively, but I don’t use them. At the time of this writing in the package version is seven months old. Phabricator is one of those obnoxious modern applications that doesn’t believe in 20th century things like “releases”. You’ll clone master and like it. Upgrading is inspecting the commit log online then crossing your fingers and praying ‘pull’ puts you in a good place. The FreeBSD packages are briefly useful for automatically installing Phabricator’s dependencies. I install it once, make a copy of the phd startup script, pkg delete php5-phabricator php5-arcanist to clean up $PATH, and get on with my bleeding edge life. The Installation Guide had me covered after that.

I put Phabricator’s sshd on port 222, then a few PF rules on the hosting machine take care of redirecting tcp:222 traffic and allowing it to pass through the firewall. $ext_if is the IPv4-only connection from my ISP, $6_if the IPv6-only tunnel endpoint from Hurricane Electric, and $int_if is a dual-stacked local network.

  1. phabricator_4 = ""
  2. phabricator_6 = "fdf0:5bcf:1335:1:1::9"
  3. {...}
  4. rdr inet proto tcp from any to $ext_if port 222 -> $phabricator_4 port 222
  5. rdr inet6 proto tcp from any to $6_if port 222 -> $phabricator_6 port 222
  6. rdr inet proto tcp from any to $int_if port 222 -> $phabricator_4 port 222
  7. rdr inet6 proto tcp from any to $int_if port 222 -> $phabricator_6 port 222
  8. {...}
  9. pass in on $ext_if proto tcp from any to any port 222
  10. pass in on $6_if proto tcp from any to any port 222

The downside to leaving GitHub is the same as leaving any other monopoly platform. When the majority of developers and projects revolve around one service, being elsewhere can doom you to irrelevancy or even shine a negative light on your project. These days having a project on SourceForge is like being that guy who still uses a address. The GitHub monoculture era will be remembered as “that time we all centralized DVCS”. Throw another remote on that repo! Even Mercurial can get in on the action with hg-git, an extension that seamlessly supports git paths on any Mercurial repo. Now I can keep my private repos private, host my own code, and still enjoy the social features of the dominant platform.

For example, look at my old graphical dish-pointing program DishHelper. Its canonical home is rDH in my local Phabricator installation, and there is a git mirror at okeeblow/DishHelper on GitHub.

  1. [paths]
  2. default = ssh://
  3. github = git+ssh://
hg push github
  1. pushing to git+ssh://
  2. exporting hg objects to git
  3. converting revision 21709792a9a51d92e6c48138e7f941d1be2a3a20
  4. searching for changes
  5. 1 commits found
  6. adding objects
  7. added 1 commits with 1 trees and 1 blobs
  8. updating reference github::refs/heads/master => GIT:286c1fda