Git Version Control – Decent Git Branching Model for Products Accompanying Third-Party Versions

branchinggitversion control

Note: My question is focused in my specific problem (which involves Liferay) but I hope it can be useful for anyone who needs to maintain various versions of a same project on git.

I work on a company which writes a lot of plugins for Liferay Portal. These plugins (portlets, themes etc.) are usually reusable and, of course, should be updated for new versions of the portal.

However, it is usual to have to migrate, let us say, a portlet to a new version of Liferay and to maintain its previous version. Also, frequently we have to create very specific customizations for some clients, which does not make sense to be added to the "main version".

These requisites complicate our work but, fortunately, we can assume some simplifications. For example, the plugins are frequently updated by only one programmer at a time. It is very rare to have two or more features being added to a plugin at the same time.

Now, we are migrating to Gitorious. We are trying to conceive a branching model for such a scenario.

My model

What I proposed was:

  1. Each plugin would have its own repository in Gitorious inside a project. For example, a portlet for displaying kittens would have a kittens-portlet repository inside the liferay-portlets project.
  2. When creating a new plugin, create it at a branch named according to the Liferay version (for example, lf5.2).
  3. Each time a update is made on the plugin, the update is approved and deployed in production, tag the plugin with a version (for example, lf5.2v1, lf5.2v2 etc.)*
  4. Every time a plugin should be ported to a new version of Liferay, we branch the most recent version (creating, for example, the branch lf6.0).
  5. Once in production, the head of the new branch will receive a tag such as lf6.0v1.
  6. Every time we have to customize a plugin in a client-specific way, we create a branch with the name of the client (for example, we would create a branch lf5.2clientcorp for our client "ClientCorp Inc.")

This is an unusual model: it would have no master and a lot of not-merging branches. This is how I suppose a repository with such model would look like:

How I suppose my branches would work.

A friend found this system rather complex and error-prone. He suggested the excellent and popular Vincent Driessen model, which I found still harder to manage and discipline-demander. It is great (and tested!) of course but seems too complex to our situation.

My friend's model

Then he suggested another model: we would have a repository for each plugin in a Liferay version (so we would start creating a kittens-lf5.2-portlet and then a kittens-lf6.0-portlet), each one with a master branch and a develop branch. The master would be always ready for deployment. (Or it could be the other way around, master and stable, as suggested by Steve Losh).

This is very simple, but I did not like this system:

  1. it could result in an awful lot of repositories in a project, making Gitorious hard to browse.
  2. The name of the directory of the project is relevant. If someone clone the repository to a kittens-lf6.0-portlet dir and generate the WAR with ant (as usual), the WAR name will be kittens-lf6.0-portlet as well. Old versions of this portlet (named kittens-portlet for example) would be considered as different (and probably missing) portlets in a upgraded portal. A bit of care can avoid it but I would prefer to avoid it.
  3. The different versions of the same plugin would be maintained apart. I break my heart 🙁
  4. kittens-lf6.0-portlet is a ugly name for a repository, I think.

I suspect the two last points – which are the two more subjective ones, too – are the main reason for my unwillingness. Nonetheless, all four objections stand.

OTOH, my own proposal seems strange to myself and I wonder if there is hidden bugs on it. OT3rdH git is so powerful and flexible that I think I should feel no shame on exploring its possibilities.

So, I ask:

  1. What would be the best model? My proposal? My friend's model? The now traditional Vincent Driessen system?
  2. What other branching model would you suggest?
  3. If you think my model is bad, why do you think so? I would love to learn what are the drawbacks and blind spots.

* Actually, I would prefer to tag the commit with a version such as v1 but apparently a tag in git is not scoped in the branch – that is, I could not have a 1 v1 tag in lf5.2 and another one in lf6.0 – so I have to name the branch. Is it correct BTW?

Best Answer

If I read this properly branches are basically a one-shot deviation from your main line of development, never meant to be merged back into the main line and advances in the main line never get applied to these branches. The only deviation would be that bug fixes appropriate to the version the branch was based on need to be applied to the branch.

The answer now pivots on your day to day workflow, the number of developers working on any one branch or number of changes are red herrings. I see your primary need as wanting to know what branches get a bug fix update from a main branch change and for this I think that the combined repository with branches will be more efficient since it's all in one place. Were there never any need for cross pollination then separate repositories would enforce that, but that scenario doesn't match the reality of your project as I understand it.

The Driessen model would work well if your project needed to merge branches back into the main line of development, but you do not need that. Even so I think that there is merit in maintaining an InDevelopment and StableRelease concept if you're working on a product that's live.

So to summarize I think that your project would work well with your branching model plus a dash of Driessen for your main line. Your mileage may vary; I've always worked with a "pending release " branch that turns into a "live" branch and a separate "next release" that all require cross pollination of fixes and changes at various points so my perception may be biased.