Review: GitLab rocks version control

Thanks to a solid foundation and delightful extras, this open source VCS is a serious contender

At a Glance

If you’ve spent any time evaluating software version-control systems, you have undoubtedly looked at GitHub Enterprise and Bitbucket Server, two big names that offer both on-premises installs and a SaaS option. You also should have run into GitLab, an open source project backed by the company of the same name. GitLab is available in a free community edition, paid enterprise and hosted editions, and a free SaaS offering that includes the enterprise features. Though less of a household name, GitLab is a compelling alternative to its more popular rivals.

Running on top of a built-in Git server, GitLab gives you a full-featured UI for managing users, projects, and code, and it even includes a built-in continuous integration solution. Best of all are GitLab’s many thoughtful usability features that make life easier for the busy developer. Despite some speed or performance issues you may run into with large installations, GitLab is not only a solid choice for managing code on-premises, but one that users will love.

User management

As a company grows, managing users can become a living nightmare. GitLab has some nice features that simplify user management. For authentication, you get a ton of options. Beyond creating a new username and password for each user, you can piggyback on external OAuth providers like GitHub and Twitter for authentication and account creation. Once users are in the system, you can assign them to groups or give them permission to create their own groups. For each group a user belongs to, they can have one of five different roles, ranging from read-only to full administrative access. One nice feature here is the ability to automatically expire group membership, which makes it easy to deal with temporary contractors or summer interns.

gitlab permissions

GitLab lets you easily configure group permissions and membership expiration in one place. 

GitLab also supports more enterprise-oriented authentication options, including LDAP, SAML, and, with Enterprise Edition, Kerberos integrations. In addition, Enterprise Edition supports multiple, simultaneous LDAP providers and the ability to configure GitLab group membership to synchronize with LDAP groups.

Other great user management features include optional or requisite two-factor authentication, as well as the ability to impersonate users as an admin and to impose per-user project limits. When it comes to the login page, GitLab Community Edition provides little in the way of customization, whereas Enterprise Edition at least allows you to configure logos. That said, GitLab provides a solid foundation for user management without overwhelming administrators, ensuring a smooth onboarding process.

Issue and project management

GitLab includes a lightweight issue system to help keep track of work that needs to be done. When creating an issue, you can easily assign it to a user, specify a due date, or add arbitrary, user-configurable labels. In the Enterprise Edition you can also specify a point weight, which is a way of indicating the relative difficulty or amount of work needed to close the issue. It’s also easy to add issues to milestones, which are user-defined groups of issues with an optional due date. Milestones are commonly employed to group issues into sprints or product releases, but they are totally flexible.

Milestones provide a nice look into how much work has been done, how much work remains, and who is working on what, closely modeling the workflow of writing code to address issues. Sometimes a more generic view is needed in order to see where particular issues sit in the development cycle. That’s where Boards come in. Boards are configurable, Kanban-style lists of issues that represent different stages in a product pipeline.

For example, you might have lists representing a backlog, issues that are ready to be worked on, issues in progress, issues that are ready to be tested by QA, and completed issues. Then you can easily move issues from one list to the next as work progresses. Boards in GitLab are driven by labels, which means you can create any sort of linear flow you want. Once you’ve configured the lists you want on your Board and have dragged issues to the list they belong, you can filter on assigned user or milestone to get a better idea of where subsets of the issues stand.

Once the work has been done to satisfy an issue and a developer is ready to incorporate that work into the main branch, they’ll create a merge request, which is like a pull request in GitHub. Similar to issues, you can assign a user and due date to a merge request. From there, several events will often happen in parallel. The assignee will receive a notification of the new merge request, indicating that they should review it.

Line-by-line commenting and conversations are supported for the merge request, allowing feedback to be easily shared and discussed. A killer feature that GitLab built into merge requests is the ability to track unresolved discussions. This makes it easy to incorporate feedback and not lose track of remaining work to be done, even when merge requests undergo several rounds of reviews.

gitlab merge

The ability to track unresolved discussions is one of GitLab’s nice extras. Jumping to the next unresolved discussion provides a streamlined approach to incorporating merge request feedback.

Parallel to these reviews, you’ll often also have continuous integration (CI) running against the proposed changes so that you can be sure they’re not going to break anything once you merge them. GitLab includes its own CI service (more on it below) and provides integrations with Atlassian’s Bamboo CI in the Community Edition, but only the Enterprise Edition integrates with Jenkins. Feedback from your CI build can be piped right back into GitLab, keeping reviewers posted on the state of the build.

Sometimes CI builds take a long time to run, especially when you’re executing an end-to-end test suite. For this reason, GitLab includes a small but impactful feature that lets a reviewer automatically merge a merge request if the build succeeds. It may not seem like a big deal, but it will matter to anyone who knows the pain of having to neurotically check in on build progress for important features or bug fixes.

To keep track of all the work each user has to do, GitLab provides a global to-do list driven by assignments and mentions. Instead of simply sending notifications, GitLab assumes that any assignment or mention is a request for action and therefore provides you with a list of actionable items. Upon signing into GitLab, you simply click the bell icon to see all of your to-dos. You can browse all of them at once or filter on specific projects, types, or actions.

For example, if you’re doing double duty as a project manager and developer, you might start your day by filtering on all of the merge requests assigned to you. After merging them or adding line-by-line comments, you’ll mark those to-dos as done, then filter on mentions to see a list of places where someone mentioned you in an issue or merge request. After responding to those comments or requests, you might then filter on issues assigned to you and finally get to writing some code.

InfoWorld Scorecard
Usability (20%)
Features (20%)
Security (20%)
Installation/setup (15%)
Management (15%)
Value (10%)
Overall Score (100%)
GitLab Enterprise Edition 8.13 9 9 8 8 8 8 8.4

Above and beyond Git

On top of the code manipulation, task planning, and project management capabilities, GitLab includes two features that sit downstream of the code: GitLab CI and GitLab Pages.

GitLab CI is a set of continuous integration features available within both GitLab Community Edition and Enterprise Edition. GitLab CI builds are defined within project repositories as a YAML file, and they can be run on demand or in response to events like opening a merge request. When the build is triggered, the work will be performed on a GitLab runner, which requires additional infrastructure you’ll have to set up.

The runner performs the build steps you’ve defined using a particular execution strategy. This could be as simple as executing the build in a shell on the runner. Or, leaps and bounds better, you could run your build in a Docker container on the runner, ensuring a clean and reproducible environment for each build. If you want to push flexibility and service density even further, you could farm out your builds to a Kubernetes cluster. When a build is complete, you can download artifacts or trigger other builds. String together several builds to create a pipeline, and you’re on your way to continuous delivery and continuous deployment.

GitLab Pages is an Enterprise Edition feature in which the GitLab instance hosts static content in the form of a website generated directly from a repository. It’s similar to GitHub Pages and Bitbucket Pages, but GitLab stands out in its flexibility. The repository can simply consist of static assets, or it can be driven by any of a number of static site generators (whereas competitors typically present a single option). Jekyll, Hugo, and Middleman are among the handful that are supported. Once the project is set up and hosted, you can take it a step further by configuring custom DNS entries and TLS to ensure secure access. One downside to GitLab pages is that it depends on GitLab CI for builds, so you’ll have to set up runners to make it work.

Setup and maintenance

Spinning up an instance of GitLab on premises or in the public cloud is a relatively painless process. The basic omnibus installation, which runs all of the services on a single box, can be done via APT or Debian repositories on Linux machines. A few commands later, you’ll have Chef provisioning the box for you. It takes a little more than the two minutes GitLab claims on its website, but not by much. I was able to get a GitLab instance up and running from scratch on AWS using airplane Wi-Fi in 10 minutes, where a majority of that time was waiting for the AWS console to load, so I could provision a new box and assign the right security groups. Further configuration is straightforward, too. Swapping out the email provider turned out to be a breeze, as was configuring the web application to use my SSL certificate and ensuring any HTTP traffic was redirected to HTTPS.

The instance will be up and running, but a bit of a ghost town: no users, groups, or repositories. If you’re working with LDAP, this is where you’d import users and groups, but you can also create user accounts as an admin or have each person create their own account. If you’re coming fresh to your first version-control system, you can continue by creating new repositories and pushing to them, but a large group of new GitLab users will already have code hosted somewhere. To ease the transition, GitLab has an import feature that can pull in code and metadata from GitHub, Bitbucket, Google Code, and many others.

When importing from GitHub, I was happily surprised to find that, in addition to the code and full commit history, GitLab copied over issues, pull requests, and even wikis. Beyond a one-time repository import, GitLab offers full repository mirroring in the Enterprise Edition. Mirroring is one way only, from the upstream repository to GitLab, which means that this feature isn’t going to let you take advantage of any GitLab features that involve changing the code. However, if you have a vanilla Git instance hosted somewhere, you might use repository mirroring to view the code, manage issues, and kick off continuous integration builds.

Depending on your availability or scaling needs, you’ll want to modify your GitLab installation. You may be able to get away with regular backups of the single-server omnibus package, which won’t give you high availability or scalability, but at the very least will ensure you can get all your data back if the server gets hosed. For more stringent HA and scaling requirements, you may want to go with an active/passive approach, where you have a second server ready to take over at any time should the active server go down. If you need a totally robust solution, you can split out the application dependencies, configure each one to be highly available, and set up multiple active instances running the GitLab Rails server. The robust solution comes at the cost of complexity and time to set up, so make sure you evaluate your HA/scaling needs before going down this road.

In the past, GitLab has had some issues with performance, particularly as it relates to merge requests on busy systems. The company remediated some of those performance issues early this year, but for the sake of monitoring everything, I’d suggest turning on the InfluxDB metrics and Grafana dashboard that comes with the installation but isn’t enabled by default. It’s easy to set up InfluxDB and Grafana, but you won’t be thrilled about configuring the Grafana dashboard. You don’t have to put together a set of charts from scratch, but importing them is a chore. First you clone a GitLab repository of default dashboards, then you import each one individually via the Grafana UI. It’s well-documented and straightforward, but tedious.

At a Glance
  • With strong core functionality and a plethora of nice-to-haves, GitLab is a compelling platform despite some performance issues.


    • Clear road map and rapid development cycle
    • Small, impactful features that address real user needs
    • Built-in continuous integration tooling
    • Ability to contribute bug fixes and features


    • Speed can be an issue in larger repositories
    • Setting up the management dashboard is tedious
1 2 Page 1
Page 1 of 2
How to choose a low-code development platform