I’m migrating our VCS from CVS to Git and I’m still struggling trying to best adapt our workflow to fit Git, but I still have some doubts. We don’t have a production environment, we periodically release versions and is up to our customers to deploy them on a production environment. So our workflow is a bit different from the teams out there.
We often have several versions being developed in parallel, that at some point need to be integrated with higher versions. Here's a simple example:
Now, imagine that V1.0
is finished and is being released to our customers. At this point, we need to merge this branch with V2.0
and V3.0
, that continue under development (to keep it simple, I’m not considering the cases where changes may not apply to some of the branches, e.g. a fix on a functionality that was discontinued on a later branch), which will create an history similar to this one:
With
V1.0
“closed”, we start working on V1.1
. The way we worked with CVS, we would have a branch representing the HEAD
for each version, e.g. V01_HEAD
, created a new branch from there, e.g. V01_00
, do some work, commit, switch to V01_HEAD
, merge from V01_00
, commit, tag, switch to V02_HEAD
and merge V01_HEAD
, commit, switch to V03_HEAD
and merge V02_HEAD
, commit, and so on. Afterwards, we would create V01_01
from V01_HEAD
and the cicle repeats. As you can imagine, keeping everything up to date is tricky, laborious, painful and merge conflicts are extremely frequent, because we need to keep track of all the branches under development and need to be sure we don’t forget to merge to one of the upper branches. It is also very common having the same blocks of code being changed in different branches, hence the conflicts.
The challenges increase when we sometimes have 4 or more parallel developments. The master’s branch sole purpose is to serve as a base for new versions.
We also have additional challenges. Imagine that someone is working on V1.12
and does substancial changes on several classes. Other collaborators are working on V2.5
and others on V3.0
. Until V1.12
is merged, the other versions will be basing their work on possibly deprecated code.
Does this same philosophy make any sense on Git or is it better to have less and longer running branches (e.g. V1
, V2
, V3
, etc.) and just tag the commit before merging it to higher branches?
Since this is a fresh start and Git offers so much more options when compared to CVS, I just want to be sure that the workflow we choose is not going to introduce unnecessary entropy. I need solid advices from Git/version control experts.
I hope I was clear enough explaining the problem.
Yes, the philosophy also make sense on Git. But you can also design a different structure, as you need to develop v1.x, v2.x and v3.x concurrently, you can create 3 release branches v1, v2 and v3. The version v1.0, v1.1, v1.2 etc can be marked by tag and commit message, so you can easily find them. There is a successful git branch module for your reference (as your requirement is differently from it, if you want to apply this module you must make some changes).
C1---C2------C3------------------C7
\ \ \
\ C6--C8--C10(V2) C9--C11(V3)
\ / ______________/
C4-----------C5---C12---C13 (v1)
| | |
V1.0 v1.1 v1.2
And it’s not necessary to tag the commit before merging, you can add tag for history commit by git tag –a v1.0 <commit id> -m 'message'
.