Some thoughts on continuous integration and branching management with git

Some weeks ago I came across the subject of development workflow while working at my previous company and I wasn't really satisfied with what we had. Also I felt there was something missing and was unhappy with my own ideas of what the perfect workflow would be. So I did some research to see what people out there is doing and to form a better opinion.

It seems there are two major workflows on can follow: continuous integration and feature branching.

Continuous Integration

The basic idea with CI is to commit often and integrate with the main line often (daily at least), so to avoid conflicts.
What I like about it is that you actually resolve conflicts early (everybody hates conflicts, right?).
What I dislike is the fact that you might be pushing unfinished or unpolished code and it seems to require more planning from the developer about what he's pushing to the main line.

Feature Branching

With feature branching we create separate branches for different features and work on those branches until the feature is done.
What I like about it is that you can keep your code and commits tider and you separate unfinished code from the main branch.
What I dislike is the fact that the longer you take to integrate with the main branch the more conflicts you might have.

Alternatives?

So can't we have the best of the both worlds?

A guy called Adam Dymitruk described what for me was always the main issue with iteration based development: Taking features out is more powerful than putting them in.
So you are doing CI, you've put your features in but at the last moment you realized one feature is buggy or not complete and you want to take it out. What do you do? There you go reverting commits (in the simplest case).

After reading all these stuff I came with a list of requirements of what the perfect workflow would give me:

  1. I want to be able to keep the commit history tidy. I want to be able to sort my commits, amend it, peer review it and edit it as much as necessary so it because tidy, logical and beautiful before getting into main stream branch. I want to avoid commits that fixes commits. A commit history of a feature should appear like it was perfect from the first time instead of a succession of trial and errors.
  2. I want to be able to generate a release build with selected features at any time I want, leaving the features that I don't want out.
  3. I want to anticipate integration errors and conflicts so they are fixed early. 

Is there a way we can satisfy all these requirements?

A missing tool

I really believe there's a missing tool here. Adam Dymitruk seems to have written a script to share git conflict resolutions using git rerere. But apparently he hasn't shared it yet.
What I think this tool should do is the following:

Given a stable/production branch P, and a set of feature branches, say, FB1, FB2 and FB3, I want a system that:
  • Combines (merge) P with every branch and test it, say P + FB1, P + FB2, P + FB3.
  • Select the successful branches and try to merge them together. Say FB2 failed, so we would try to build and test P + FB1 + FB3 and make it a release candidate.
  • Should a conflict appear, notify the developers so they can fix it.
  • The conflict resolution is saved so not to happen again.
  • The process is repeated continuously.

I think there could be a tool on top of git to do such process and it seems to have many issues involved. 
I'm really looking forward to see such a tool (and might end up doing something myself).
I wonder if this would approach actually work in practice...

1 comment:

  1. Sorry to be getting back to you so late.. We ended up sharing the rerere info manually. I'll post the script or what you reed to do to write it yourself.

    ReplyDelete