The Source Control Hosting Landscape
GitHub has been the the most popular site for hosting open source software projects since 2008. It took the lead when SourceForge was slow to embrace newly-popular git source control system. GitHub is rivaled by Bitbucket, thriving on an enterprise-friendly pricing model and integration with other Atlassian tools. However, GitHub’s model of charging for privacy rather than headcount makes it a dominant open source social platform.
GitLab is a new competitor emerging over the past couple of years, drawing significant community attention. Unlike the alternatives above, GitLab itself is a open source under the MIT license. You can install it locally on your own hardware, making it attractive for businesses who won’t host their code in the cloud. GitLab’s revenue comes mainly through selling an enterprise version, with security features and HA support.
Aside from giving away or selling packages to be installed locally, GitLab also hosts a SaaS offering like GitHub and Bitbucket. Unlike its competitors, GitLab.com is completely free for public and private repos, with unlimited users. GitLab’s model assumes the real money is in on-prem software, and so they use SaaS to market their on-prem package.
A GitHub Alternative?
I’ve been really intrigued by GitLab over the past few months. In addition to being open source, they’re also active in the community and in releasing new features. Mention GitLab on Reddit or Hacker News, and the CEO will usually appear to within the hour to answer any questions.
I like GitLab’s choices of color schemes. It’s easier to review pull requests with a darker theme than with GitHub or Bitbucket’s black-on-white style. GitLab has an integrated CI build system, a Docker container registry, and there always seems to be something new on the way.
At the same time, I’ve just grown a bit wary of GitHub recently. A couple of years ago their founder was forced out due to claims of sexual harassment. Since then the company has struggled with public image issues in the opposite direction. They’ve threatened to shut down repositories containing offensive language, and become embroiled in controversy over diversity. Perhaps most importantly, they’ve faced internal morale issues as they struggle to become an enterprise vendor.
At the end of the day, none of this means you can’t host personal side projects on GitHub. However, it has been enough for me to explore how green the grass is on the other side. I like what I’ve found enough to stay there.
However, there certainly are advantages to hosting open source projects on GitHub. Many developers publish repos as “portfolio” items, for resume purposes. Some developers are looking for contributors to join their efforts. GitHub has a much larger userbase than anyone else, and so the “network effect” strongly helps with both goals.
Best of Both Worlds?
Fortunately, it is possible to retain GitHub’s network benefits while using GitLab as your primary host. With minimal effort, you can use GitLab as your repository’s primary host while also hosting a mirror on GitHub.
On the “New Project” page, GitLab already has an option for importing an existing GitHub repo. Whether you’re importing an old GitHub project, or creating a brand new project and pushing it to GitLab and GitHub both, there are two approaches that you might take:
Option 1: Create Separate Named Remotes
If you would like to encourage public contributions to your project, both from GitLab and GitHub, then you’ll want to create separate named remotes for each. If GitLab is your primary host, then you would add a remote for GitHub like this:
git remote add github https://github.com/user/repo.git
Now, you can interact with GitLab or GitHub specifically. You know that “origin” name, that 99% of git users type without thinking about it? Well, that refers to your primary host, GitLab. This new “github” remote name refers to GitHub (and you’re free to use any other name you like instead, it’s only for human-readability).
To push changes to either repository, use:
git push origin <branch> (GitLab)
git push github <branch> (GitHub)
You would pull down changes in similar fashion:
git pull origin <branch> (GitLab)
git pull github <branch> (GitHub)
As you do work on your GitLab primary host, you would just periodically update the GitHub mirror by pushing the “master” branch there. Conversely, if someone in the community submits a pull request to your GitHub mirror, then the workflow would look like:
- Review and merge the pull request on GitHub
- Pull “master” into your local workspace
- Push “master” to GitLab
This is definitely a bit more manual shuffling than you would have with a single remote. However, it gives you maximum flexibility, and after a time or two it becomes automatic.
Option 2: Overload Origin with Both Remotes
Not every project seeks out public contributions. Many of the projects on my GitHub account are basically “porfolio” items, there for resume purposes, and I specifically do NOT want pull requests. If your project is a one-developer affair, then you can take a much simpler route to a GitHub mirror:
git remote set-url –add origin https://github.com/user/repo.git
You don’t see this trick everyday, but in git the relationship between a remote name and remote URL is not necessarily one-to-one! Git will quite happily map a remote name to multiple repository URL’s. Here, we’re overloading the default “origin” name to reference both GitLab and GitHub. So the normal…
git push origin <branch>
git pull origin <branch>
… will push to (or pull from) both your primary GitLab host and your GitHub mirror!
This solution may be a little TOO clever for large team situations, but for projects on which you’re the sole developer it is probably the most convenient way to go.