Skip to content

Instantly share code, notes, and snippets.

@mbbx6spp
Last active October 22, 2024 13:13
Show Gist options
  • Save mbbx6spp/70fd2d6bf113b87c2719 to your computer and use it in GitHub Desktop.
Save mbbx6spp/70fd2d6bf113b87c2719 to your computer and use it in GitHub Desktop.
Gerrit vs Github for code review and codebase management

Gerrit vs Github: for code review and codebase management

Sure, Github wins on the UI. Hands down. But, despite my initial annoyance with Gerrit when I first started using it almost a year ago, I am now a convert. Fully. Let me tell you why.

Note: This is an opinionated (on purpose) piece. I assume your preferences are like mine on certain ideas, such as:

  • Fast-forward submits to the target branch are better than allowing merge commits to the target branch. The reason I personally prefer this is that, even if a non-conflicting merge to the target branch is possible, the fact that the review/pull request is not up to date with the latest on the target branch means feature branch test suite runs in the CI pipeline reporting on the review/PR may not be accurate. Another minor point is that forced merge commits are annoying as fuck (opinion) and clutter up Git log histories unnecessarily and I prefer clean histories.
  • Atomic/related changes all in one commit is something worth striving for. Having your developers think about the granularity of their commits in terms of relatedness, cohesiveness, and deployment units makes the changes more manageable. This is my claim and the only evidence I have of it is the difference I have witnessed on teams that went from 1..N commits per feature branch to 1 commit per feature branch. The difference I saw was an awareness one. Developers started to think about viability of deployment of that one unit of change to each of the environments. That wasn't the case before we made the change to one commit per feature branch policy. You can enforce this using Github even, but it's not provided by the Github interface.
  • Being able to publish a review in draft form without prefixing with "WIP" or other general convention (which is totally possible and scriptable in Github; I know I have done it previously) simply makes querying and permission/visibility of those reviews/PRs easier to manage and filter out/in when necessary. Perhaps a minor point.
  • Limiting permissions can provide some merits to helping manage releases and codebase repositories more consistently via automated builds/CI/CD setups.

If you disagree with the above opinions then you will likely not agree with some or more of the following which is why I think Gerrit is better as an overall solution:

  • Gerrit's reviews can be forced to be fast-forward only or rebasable-only. Github's PRs are merge based, which - frankly - disgusts me (just a little). I talk about this above a little but I should warn you of my biases: previously I built CI/CD tooling using Github workflow and it was impossible to reason about the change in a PR now matter what hooks and checks we had on the repository per PR without a LOT of extra work on the tool developer (me). And it wasn't even full coverage of the workarounds I really wanted as a CI/CD pipeline builder. Lots of busy work for very very little value (and a nice UI, sure, I still love Github web UI, but there has to be much more to a trusted partner than a pretty face).
  • Github's PRs do not force you to think about atomic/related changes as one commit. Gerrit's reviews, by its restrictions (i.e. one commit per review), do force developers to think about this much more consciously. I think this is good. Great even.
  • Github's PRs do not track the notion of review rating except loosely in the comments (which are free form). Gerrit's reviews do track this.
  • Gerrit allows you to push draft reviews. There is no such notion in Github.
  • If you want to use the rebase and squash approach in Github (because it's the most sensible, come on) then you can't track the whole history in the pull request. This is a problem. For example, if I provide inline feedback in a pull request and the other developer makes changes based on my comments, I can't view side by side in the UI the diff between the original pull request commit and the new commit without trying to track down the SHA commitish of the original, which is not necessarily easy to find (and not shown in the Github pull request history at all).
  • On the one hand I like that git itself doesn't bake into it a permission model on the repository level, but I do like Gerrit's permission model ON TOP of git. At first I thought it was overkill and sometimes it is. However, I love the idea that in Gerrit I can make it such that only the CI user (e.g. jenkins or travis user) can create tags and push to the Gerrit remote. In this case, only on specific CI triggers are tags created. Tags can't accidentally be created by a developer and pushed to the remote. I'm a fan of consistency and operationalizing release management wherever possible so this is dear to my heart. There are other important areas where I think limiting access to certain features on the repository are useful too, this was just one example.

What Gerrit needs to improve:

  • More coverage of command line options in one place (right now there is gerrit-review and git-review, it would be great to consolidate the CLI consistently for as many of the features available as possible)
  • Better tig integration (which is on the user to update their .tigrc file and new bindings, etc.)
  • Less cluttered UI.
  • More intuitive UI (navigation, etc.)
@amoghe
Copy link

amoghe commented Sep 15, 2016

What I care about is the final change and not how you got there.

Agreed. The "how you got there" (iterations, incorporating coworkers comments as part of the review process) is held in gerrit, outside of git. Thus its important to link the commit back to the gerrit review Id so you can quickly look at how the patch evolved.

@Xanir
Copy link

Xanir commented Oct 26, 2016

This is what bugs me the most and why I dislike doing rebase & squash for my own code. I like seeing all the commits and comments that led up to the feature, I like having that history there. But when you rebase and squash with Github, that history is lost.

How is the full development thought process via the history useful? The changes committed locally are used as a way to back up the current changes so I can switch to a different branch or revert to point the code was previous working if I break something. When the change is complete the feature should be functional and that 'development' history is moot.

Here is a contrived but very real example. Say I add some code to a services file. Commit the change, locally. Decide that code is too large enough and move it into its own file. Commit that change, locally. I Realize I spelled the new file incorrectly and correct the spelling. Commit the change locally.
Without squashing these changes before initialing a pull request all these development iterations exist in the shared history, what value are they adding?

Gerrit's intent is to help keep your Git history lean, making comparing your changes easier as you only have 1 commit to compare against per feature not 'N'.

@mpastern21
Copy link

@mbbx6spp, why you saying that gerrit forces one commit per review? You can do as much commits as needed, just use same change-id in commit message, also it would make no sense when feature branch has to be shared between few developers working on same feature

@mpastern21
Copy link

mpastern21 commented Jan 8, 2018

@magiconair maybe you don't care as a reviewer (which i tend to disagree as seeing/understanding sequence of changes makes you more sophisticated reviewer), but as a good developer working on the following changes, you'd like to be able understanding what lead to certain implementation, thus history is crucial in my view

@spazmodius
Copy link

Somebody help me understand.... There is talk here of "atomic commits". But squashing every change in the development of a feature into a single commit is anything but atomic.

Atomic commits, it seems to me, would each have a single refactoring, or a single addition, or a single removal, or a single reformatting. A series of these results in a feature. How is seeing all these together in a single commit a good thing?

@krabilousse
Copy link

@spazmodius

As @magiconair said,

What I care about is the final change and not how you got there.

The point of an "atomic commit" is to have a single commit with a single "subfeature" or "change" as Gerrit calls them. Gerrit doesn't squash multiple changes together, but rather a single change's history, from the first revision to the final one. The point is to have a nice looking master branch, without messy "WIP" commits.

@noahgibbs
Copy link

One difficulty of rebase and squash is that it requires a lot more Git sophistication for each developer. That's true regardless of Gerrit or no-Gerrit. But a branch- and merge-based workflow exists to avoid that problem. And it is a real problem since quite a lot of developers aren't great at Git and don't want to be. I've been the dev supporting Git problems on large teams of developers with Gerrit, and I wound up spending a lot of time un-sticking situations where people had lost or mangled their commits. You can train them in how to un-stick their Git config (and I did,) but it winds up taking a lot of time for the cases they can't manage.

@khvMX
Copy link

khvMX commented Oct 18, 2018

The point is to have a nice looking master branch

Exactly. For that you (destroy-all-the-history-people) need to go and contribute to your UI tools (gitk/git log/younameit). It does not justify destroying history.

@milesgould
Copy link

the fact that the review/pull request is not up to date with the latest on the target branch means feature branch test suite runs in the CI pipeline reporting on the review/PR may not be accurate.

Not if you use Bors! This handles the problem with much less developer effort and more efficient use of hardware than making developers rebase all the time. It's merge-based, so perhaps unacceptable to some of you for that reason, but it greatly cuts down on the need for forced merge commits compared to GitHub's native "ensure branch is up-to-date before merging" feature. We find the merge commits Bors creates useful, anyway, because they contain the PR descriptions (which otherwise wouldn't be part of the history).

As for the main argument here: I think there's a useful middle ground between "every single change made or requested on a given feature" (a Gerrit review), and "the feature is done and can be deployed" (a Gerrit commit). In GitHub, you can use PRs for "minimal unit of deployment", and commits for "minimal unit of review/code archaeology". Mixing up the refactorings that are required to support a new feature with the new feature itself leads to unwieldy commits that are hard to make sense of later, but in a year's time you won't care that someone requested a typo fix in your first version of the docstrings. The answer is multi-commit PRs, and using git rebase --interactive to produce a sequence of clean, atomic commits for your PR. This requires some discipline, and greater-than-average Git sophistication from your developers, but so does Gerrit.

@shenpengyan
Copy link

very good article

@luismbo
Copy link

luismbo commented May 17, 2019

Thanks for writing this up! I think this comparison still holds in mid 2019 although Gerrit's UI has improved quite a bit since 2015.

@hjbolide
Copy link

Gerrit has selection based review comments rather than line based, which is a huge selling point.

@wyqydsyq
Copy link

Looking at this today it seems GH has closed the gap in a lot of places e.g.

  • There are now 3 different merge strategies for PRs
  • Basic approval voting can be done using the "reactions" on a PR, external tools can automate merging PRs and further CI based on this
  • GH has better access control now with the Teams feature

Wheras Gerrit has seemingly made little to no progress. It does still have a few advantages particularly in using custom workflows if that's necessary for your workplace, but I really doubt that's a must for most developers for whom git-flow or similar works fine. Gerrit has an entirely "new" UI, but it looks and feels like an unpolished jQuery + Bootstrap UI made in 2012 so still sucks in contrast to GH.

I think Gerrit at this point is only worth using if your team specifically needs the niche advantages in stuff like granular access control and custom workflows provided by it. Otherwise you won't really see much if any advantage to using it over GH/GL, at the expense of having a more rigid workflow and making it more difficult to onboard new devs

@luismbo
Copy link

luismbo commented Jun 26, 2019

Gerrit's interface looks fine and has improved quite a bit over the last few years. Also, it's got great keyboard shortcuts.

Not sure what you mean by rigid workflow, but you can even push commits directly, bypassing code review. (In that scenario Gerrit can even auto merge when receiving your push so that you don't need to do the rebase-and-push-again dance.)

Some of Gerrit's killer features for me are (a) the ability to see the differences between force pushed commits (this avoids having to restart the review from scratch every time there's such a change), (b) the ability to create and assign a change request with a single git push command and (c) automatic email notifications when the change owner updates the code (e.g. in response to my review).

Things I miss in Gerrit compared to GitHub: (a) markdown comments, (b) forking (for sharing branches with others without creating branches in the main repository) and (c) better listing of repositories.

Of course, whether you choose Gerrit or GitHub/Gitlab ultimately depends on your requirements and personal preferences.

@isbm
Copy link

isbm commented Jul 31, 2019

I do like Gerrit's permission model ON TOP of git

We had this model already. It is called SVN.

@s-kocher
Copy link

Gerrit allows you to push draft reviews. There is no such notion in Github.

This is not true anymore :
https://github.blog/2019-02-14-introducing-draft-pull-requests/
https://enterprise.github.com/releases/2.17.0/notes for availability in Github Enterprise

@nstetter
Copy link

@mbbx6spp
Would you mind sharing the part of your tigrc that improves integration with gerrit?

@d-nagaraj
Copy link

Gerrit allows to keep the patch private for example
git push origin HEAD:refs/for/master%private
git push origin HEAD:refs/for/master%remove-private

is there any equivalent in github?

@subashp
Copy link

subashp commented Jun 15, 2020

Thanks for all those years of wisdom. As someone who used gerrit, github & gitlab for code reviews, I am biased towards using Gerrit. Much simpler UX for code reviews. Btw does anyone has idea about gerrit over github - http://gerrithub.io/?

@charlesr1971
Copy link

I am sorry but this ‘one commit per review’ advantage is a moot point. When I am using GitHub, all I see is the updates I need to review. I don’t look at the commit references and think, “oh, my god, there is more than one commit, here. Let’s panic!”
I just calmly do my code review, moving from one change to the next.

@luismbo
Copy link

luismbo commented Apr 19, 2022

@charlesr1971 no need to panic. The point is that Gerrit's model promotes reviewing/validating each commit independently whereas GitHub promotes reviewing pull requests with multiple commits in one go. Probably a matter of personal/team preference.

@charlesr1971
Copy link

But, if we view things in terms of updates rather than commits, it really doesn’t matter whether there is one commit or a hundred.
Personally, I find Gerrit restrictive. I prefer the freedom of being able to push multiple commits. It also creates a problem, if you want to create a local ticket branch. Changes are reflected across the feature & ticket branch, until the first commit is made. In Gerrit, you should only create one commit per push, which makes it impossible to resolve this issue.

@luismbo
Copy link

luismbo commented Apr 20, 2022

You can push multiple commits in Gerrit and group them together using topics and you can enable the option to submit whole topics (i.e. the whole branch) in one go. Gerrit certainly has drawbacks but restrictiveness is definitely not one of them. It enables lots of workflows.

@mochadwi
Copy link

hmm interesting! thanks for bringing up this!

@emirkmo
Copy link

emirkmo commented Jan 23, 2023

You can push multiple commits in Gerrit and group them together using topics and you can enable the option to submit whole topics (i.e. the whole branch) in one go. Gerrit certainly has drawbacks but restrictiveness is definitely not one of them. It enables lots of workflows.

Can you explain what you mean?

let’s say I am on a roll and knock out 10 tickets, each a commit, some building on others, while others being independent.

how do I push these for review, make changes to commits down in the chain, in a sane way without constantly getting outdated base branches that I have to manually rebase with manual conflicts resolution every single time (nevermind with additional merges from my coworkers)?

Or simply, if I have commit A->B->C ready for review, how do I handle changes on A or B from review (while amending commits)?

@luismbo
Copy link

luismbo commented Jan 24, 2023

After you amend A or B, then C will be modified, yes. But you simply git push the whole branch and the change request for C will be updated accordingly. It won't lose any comments, code reviews, etc.

@BoschMihaiChezan
Copy link

Used (and still using) Gerrit almost on daily basis for about 3 years. The thing is, Gerrit was initially designed to be able to manage the complexity of building the Android Operating system and managing very complex sources. Those who have built Android from source and worked with multi-branch and manifests know what I'm talking about. But for normal and simpler sane software development Gerrit is an INSANITY to use! From a developer perspective, Gerrit bloats and complicates all processes for normal (simpler) software development. For complex developments such as Android Operating System (which might have tens of thousands of components), Gerrit is like a lifeboat, which saves the day. Managers also love Gerrit because every operation performed on the source code can be exactly tracked and manged by complex permissions, and they can generate very good metrics and insights into projects to see what the developers are actually doing on projects.

So, if you work with very complex source (which is almost impossible to manage in any other tools/service than Gerrit) or you need complex permissions on repos or you want managers to be able to accurately track and see who and how much time developers spend on reviews or various tasks and have a good insight on what is going on in source, then yes, use Gerrit, it's the perfect tools for this. If you do normal software development, and work with less components which can can be managed by tools/services such as Github or Bitbucket or Gitlab etc than go for those tools, they are saner, simpler and straight-forward to use, and the whole development process would be a lot faster.

@charlesr1971
Copy link

@BoschMihaiChezan This is interesting information. Just out of interest, why is only Android OS app that you might build tens of thousands of components for?
In Angular, as well, we often build many thousands of components.
I suggest that there are also many other languages, especially frameworks that use TypeScript, which caters for Angular & Vanilla class components systems, that might benefit from Gerrit.
I have used Gerrit before and I am in no way, a cheerleader for this Git plugin, but it was definitely commended by our lead Devs & managers.

@BoschMihaiChezan
Copy link

@charlesr1971 Defiantly not only Android OS development benefits from Gerrit but any complex project which has a complex source, including those which you have motioned. The reason why I have mentioned Android is that Gerrit was specially created by Google to be able to handle the complexities of the Android OS source, that is the initial reason for Gerrit creation. Of course, it is a general tool which can be used in many kinds of projects.

@ArthurYount
Copy link

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment