Git: Who cares about branches? It’s all about collaboration and code reviews

TL;DR: Using Git has made our team much better by removing barriers to collaboration and code reviews. Those are the real Git benefits, not specific features like fast branches.

Introduction

I heard about Git several times before starting 8th color, but was never convinced by the arguments that were presented to me. We started using Git from day one at 8th color, mostly because it “came with the package” – in the Ruby & Rails world, it seems that nary a developer is using SVN or even CVS.

git icon, created for the Open Icon Library

The Git icon, already branching (Photo credit: Wikipedia)

18 months later, I finally feel confident enough to recommend it (on appropriate use cases) to my peers, mainly because, in my humble opinion, Git is very loudly but often very badly advertised. Here is a quick summary of the arguments I heard and discounted, and those I think are actually valid but too often overlooked

It come down to one thing: Git is not about speed or local commits or branches, Git is all about collaboration and code reviews.

What I heard about Git

My problem with Git advertising is that what I mostly heard were two things:

  • “You can create branches very fast”
  • “Git is distributed, you can commit locally”
Visualization of the "history tree" ...

That makes it much clearer (Photo credit: Wikipedia)

Problem was, with some years of SVN experience under my belt, those points looked like what I call a solution looking for a problem. Fact is, I never had big problems creating branches using SVN/CVS – but I had my share of problems merging them. Even then: creating and merging branches were not part of my daily work.

The “commit locally” was equally flawed. I already had two states (uncommitted and committed); why did I need a third one (uncommitted, committed locally, committed remotely)? I did not work long without a connection anyway, and was used to short well defined commit already. Moreover, I was never comfortable with code sitting only on my machine, committed or not.

The problem here is that those two selling points are not benefits – they are mere features. You do not sell a product or tool on features – you sell the added value to your job. Those features are interesting, but not as such: they are interesting for what they bring to your development flow.

 

What I love

The big point about speed and easy branches (and, one should said, a sane branching model, where branches are not simply folders and conventions) is that it allows you to start using a significantly different collaboration model.

My typical SVN flow

We used the main branch (trunk) for the “long running development”. Once a release (V1.0) was scheduled, I created a tag once all features were in, and we started working on the next one (V2.0). Should a problem arise in production with the V1.0, we could then create a branch from the tag, fix any bug there, and release a V1.1 without impacting our V2.0 work (except to port any bug fix done, of course).

This worked pretty well, with almost no merges to do (the V1.1 branch was left to die, with work occurring on the main branch). Bugs had to be backported, of course, but we used to have reasonably short release cycles, which helped.

As for the various features that we were working on (in a team of 4-5 developers), I tried to find a way of splitting work that allowed most of the team relative freedom, with the rules that once the code was not making tests fail, it could be committed – even if not finished. We had our “conflict” moments, but it worked decently – and it still does – when I’m using SVN with other teams.

What Git allows: feature branches

The main benefit that Git unique feature brings is the possibility to use feature branches. By possibility, I do not mean the technical feasibility (you could theoretically make feature branches using SVN) but practical feasibility – if you are in a development team, your version control tool is, well, a tool, so it should work and allows you to create value.

Features branches are just that: they mean that each time that someone starts working on a feature or even a bug (depending of your level of orthodoxy), he/she creates a branch for that work from the main branch (typically named “master”). Several of them can be created at the same time, which will be frequent if you are making sprints – typically one per active developer, each on his own feature.

As branches are basically “free” (they are created instantly, which is logical once you understand how they are implemented), you can start working immediately, and commits can be pushed without problems – after all, you do not risk any other developers work, as you are “isolated”.

Once the feature is done and well tested, it can be merged into the master. You can then starts a new one – or use an additional step.

Removing barriers to code reviews and collaboration

The fact that each feature is on a separate branch make it much easier to do code review and generally to collaborate on code. Before merging back in the master, it is a good time and a good idea to ask for a review.

As the reviewer, you are probably busy in some code yourself. But with Git, if all your changes are committed (if they are not, there is still a way to save them temporarily), looking at a colleague code means just checking out his branch – again a very fast operation. You can then look at the code, run the tests or the code, and even commit changes if needed. Don’t forget: “If you give a patch to a man, his code will be better today. If you discuss it with him, his code (and yours!) will be better for all his life.

GitHub has actually made this process a feature named “Pull Request”, allowing for a conversation around the feature to take place in an easy way with a nice GUI.

Looking back at those Git features, the benefit is clear: it removes barrier to collaboration and code reviews, which are key to producing good software – and good developers.

From the trenches

Dodengang

Git usage, from the trenches (Photo credit: Frank Van Hevel)

Here are some recent, real life examples directly from our own three person team at 8th color.

  • We produce new branches on a daily basis, and switch between them several times a day (for example to look at a colleague’s code, then go back into our own). 
  • I did create a branch & the associated pull request for a modification of exactly two lines. This may look as overkill but even small patches deserve feedback and as it is free, why miss the opportunity?
  • It happens that the review does not arrive immediately. In most situations, you can still create a new branch for the next feature, the merge can come afterward.
  • The pull request & review process is “mandatory” (i.e. we decided that it was a good way), 

    meaning that we conduct peer review (once again: a review is not something a senior does on a junior code. It is something someone does on someone’s else code.) on a daily basis enhancing our code quality – and our team work.

  • It is the reviewer job to merge the branch into the master. This is a “one second” job (using GitHub, it is actually one click), so why emphasize it? Because it means that the reviewer become co-owner (and co-responsible) for this code. If code you reviewed and allowed into the master ends up badly, you are as much guilty as the one that wrote it.

For starters

If this has convinced you to take a look at Git, some starters advice :

  • Git works in a significantly different way than SVN or CVS. Not only that, you have to understand (at high level) the way it works, or it will come back and bite you, whether with a data loss (Git is rightly advertised as never losing any data, but possess commands or options that can actually remove some !) or just surprising situations (when switching branches with uncommitted changes, for example).
  • Take a look at a Git Flow. Git low level commands allow for a lot of different possible workflows, meaning you have to pick one and stick to it – when are you creating branches, what do they means, how are they merged, etc. The model described in the link works pretty well for hundreds of team, and is probably a good starting point for yours too.
  • Git UI is complex and inconsistent, but you need to use it. And I do not speak of any GUI here, just about the command line. A command line is a UI. Git command line UI sucks. Use it anyway.
  • Stay where you are comfortable. Git has a lot, I mean A LOT of options and commands. You do not need everything to start. Actually 7 commands can get you really far
    • Committing: add/commit: add basically add files that you changed to the next commit batch, and commit bundle them with your log message.
    • Remoting: push/pull: push send your changes to the remote server, pull get the changes from the server back to you.
    • Branching: branch/checkout/merge: branch create a new branch, checkout switch from one branch to another, merge merge the content of a branch inside the current one.
  • Use and abuse pull requests (if you are using GitHub), or ask for review before each merge. It really makes a world of difference.
  • Read aboutmerge vs rebase” if you want. No, don’t. On some mornings you can see advocates of both taking the sweet spots in Hacker News’ home page for saying exactly the opposite. Be warned: Here Be Dragons. My own advice on this subject is a cup of tea and a good spot on the sofa. Technological church wars are so fun to watch.

I hope you’ll find the journey as frustrating and the arrival as beneficial as I did. 

Français : Début de l'installation de Git

Français : Début de l’installation de Git (Photo credit: Wikipedia)

Enhanced by Zemanta




15 thoughts on “Git: Who cares about branches? It’s all about collaboration and code reviews

  1. Ozh

    As a relatively recent newcommer to Git from SVN, I do find that the killer feature that is always poorly advertised is branching. SVN branches are a joke, they are nothing better than simply copy the whole directory to another place, modify it, and if you’re unhappy overwrite with the copy and start over. I still remember the day I found out about git branching…. oh the possibilities! It’s not that they’re fast, it’s the fact they’re magically at the same place.

    Also, for starters I recommend Git Magic. Just as you explain, they put emphasis on the main basic commands and then explain some more advanced tricks. Very pleasantly written and easy to read.

    Reply
    1. Martin Post author

      Hi Ozh. I agree that git branches are awesome – but again, you are not creating branches for the sheer sake of it – you told about the possibilites, but what are you using them for?

      Reply
  2. Pingback: Git: Who care about branches? It is all about c...

  3. Earl baugh

    I have a couple questions… Can you tell me how long (on average) these branches live for? I completely understand the improvement in quality you get when programmers are working in a more collaborative fashion (and I’ve used different tools and processes at various places to achieve this). I’m trying to understand whether you’ve also fundamentally changed how “long” branches live between the Git and SVN models. Reading between the lines, I’m “assuming” that branches live for a fairly short time (compared to the 1.0/2.0 version solution you use for SVN). This would imply that you’re working in a much more agile fashion now (with Git) and still using either an iterative or waterfall model with SVN.

    Reply
    1. Martin Post author

      Hi Earl,
      You’ve nailed it – branches are nothing new, but the easyness to create, merge and delete them in Git make them a much more powerful tool. We basically use a branch for each feature, and those a living between some days and normally a week (our sprint duration). Some did stayed for longer, but those were indication of badly defined features that should have been split before.

      As a team of three people, that means several new branches per week (we delete them once merged back, to that is not a lot open at the same time).

      Reply
      1. Earl baugh

        So, how long were you running features in SVN? Was that comparable, or was that a longer process, time wise?

        And have you tried to apply this to situations where you have multiple feature branches that live much longer than a week (and with a much larger team than 3 people?)

        I’m thinking 20-30 developers, and feature branches that live for at least 3 weeks…

        Reply
        1. Martin Post author

          My SVN time was quite different (other, larger team, and other tools also). We used branch for much longer period at that time, and used them much less (the cost of creation/switch is quite different).

          Regarding the duration, the key point is not the exact duration in time, but in relation with your sprints – we use one week sprint, which is very short but a good match for us. Teams most often use two weeks sprints. Anyway, the idea is to avoid features (and so, branches) that outlive sprints. If your sprint is three week long, it should not be a problem having branches that stay alive during all that time.

          Regarding the size, I’ve not the experience, but agile practices like this one have been used in larger teams like yours. I hope they are not all working on the same project, or that the project is at least split in various parts to avoid too much conflicts.

          SVN will make it a bit more difficult than Git, but it looks possible for me (and you would not be the first : http://krkadev.blogspot.be/2011/01/subversion-and-feature-branches.html). And you could “pilot” the new system with a given team (4-8 developers), to tweak it somewhat before releasing it to the whole group of developers.

          Do not hesitate to contact me directly to keep me posted of your progress, I would be quite interested in the feedback.

          Regards,

          Martin

          Reply
  4. Vladimir

    Hi Martin! Very good article! I have just started to use branching in Git and I must say it feels much better coding this way. I have a question about branching, though:

    Let’s consider the following situation: you create a branch from master in order to develop a new feature. You start coding, but before you have something to commit, another developer from the team merges his branch.
    Finally when you are ready to push and merge your branch, you realize that his code breaks your new feature which did not exist on your branch when you started coding, which leads to a conflict.

    1) How are these conflicts resolved and what is the best way to avoid them?

    Furthermore, let’s assume that the developer was not aware of all the new methods/classes/functions you have added in your branch , but he needed them and implemented in his own way. His code is merged with the trunk before yours and you end up with 2 implementations by 2 developers for the same functionality (overlapping).

    2) How are these conflicts resolved and what is the best way to avoid them?

    Reply
    1. Martin Post author

      Hi Vladimir,
      Thanks for your kind words, I’m glad this is useful for you. As for your questions: in the first case, you normally would merge/rebase (as said in the post, I won’t enter this holy war) the master into your feature, thus incorporating all changes. Should conflicts arise, git will point them and ask you to resolve them manually (basically, you’ll find both versions inside the same file, allowing you to pick either one of them or create your own mix). Once the master has been merged successfully into your feature branch, the branch itself can (logically) be merged into the master without any problem, as it contains everything.

      Be aware that Git is really good at “auto-merging”, so this will not happen often (non conflicting changes inside the same class will be merged automatically without problems).

      The second situation is more an organisational problem for me, and one that I never faced (we split the various tasks between our team and try to avoid this kind of situation). Should it happens, the best would be to
      a) Select what is the good/best implementation of the two
      b) Have that one be merged into the master
      c) Merge the master into the other branch to resolve any conflict

      Again, the tool can probably help to find a way out, but I would avoid this kind of situation – and it is not that hard to avoid with a minimum amount of organization.

      Hope it helps,

      Martin

      Reply
      1. Vladimir

        Thank you for the reply – so conflicts are inevitable in some sense – but can be avoided with good organization and resolved relatively easily in coherent teams.
        You seem like a nice person to work with and learn from!

        Reply
  5. Vladimir

    Hi Martin,

    I have a question about branches and I was wondering if you could help me figure this out.
    My client has many features documented in separated tickets.
    I start to work on Feature 1 on Branch 1 and it goes well for a while. But before I finish it, the client says:
    stop working on Feature 1, just push in Production what you have so far and then immediately start working on Feature 2 on Branch 2.
    To satisfy the client, I merge Branch 1 with Master, but I don’t close it, because it is not fully finished.
    Then I create Branch 2 and implement Feature 2. Client approves it and I merge Branch 2 with Master.
    Then I return to work on Branch 1 where I left, but Branch 1 does not reflect the current state of the application anymore.

    So what is the move that I need to make so that Branch 1 becomes up-to-date with Master before I continue working on Branch 1?

    Can I somehow merge Master with Branch 1 to achieve that?

    Reply
    1. Martin Post author

      The short answer is yes: if you are working on a branch and that the master has evolved a lot, it is better to merge (or rebase, depending on your philosophical principle) it into your branch first. You can then fix all potential conflict in the branch, so that the merge of the branch into the master will work without any problems.

      Now, in your example, I would have stopped work on branch 1 without merging it – if your branches are real features branches, you do not want to deploy unfinished ones anyway, but this may be needed in specific cases.

      Good luck !

      Martin

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>