1

I am a member of a project team with somewhat unusual (or at least from my perspective) release methodology and team dynamic. The way we have been doing releases is rolling out a single functional bundle at a time, all of which, as a rule of thumb, was done by a single developer. Developers do work on their virtually independent functional areas, that are all nonetheless part of the same deployment bundle (WAR file and its corresponding Git repo), concurrently but it is not certain or clear whose change will go in in what order. It often depends on whoever finishes and gets their stuff tested first. So Dev1 may be working on Change1 within TeamProject and Dev2 will be working on Change2 in the same application, and sometimes their changes may be interdependent (such as changing a shared API) but it is not clear when each will be rolled out to PROD.

The way we currently do Git branch management is that each change gets its own remote branch, which defacto means there is one remote branch per developer. The biggest problem I see with that is that, in order to be refreshed of your teammate's changes, you have to manually sync your branch to their branch, which is a manual and often a PIA process, excuse the term. It may be okay for the developer whose release is the very next one in line, for his branch is what the next version of the release will look like once it is rolled out (in the existing single change release setup). But it surely does not work for the developer whose release comes right after as (s)he has to build their changes on top of the first developer's changes. However, they don't want the second developer to push into the first developer's branch as to keep the change pristine and exclude everything else from that specific release. So the 2nd developer has to do the merging of the 1st developer's branch into his branch and then push his stuff into that branch on top of the 1st dev's changes. That would not be half as bad if it were clear who the 1st and who the 2nd developer is, IOW, whose changes will first be rolled out but that is a contingency, as explained above.

Now, by the nature of this post thus far, it is clear that I am not the father of this process and that I am aware of many of its inherent flaws. One notable flaw happened recently when we were promoting our changes to the TEST environment. I had been working in my dedicated branch but the version that was deployed to TEST was built out of my peer's branch (it had his changes only). I was about to push my stuff but didn't want to lose his, as I value our QAs time and wanted his and my tester to be able to work concurrently. So I synced my branch to his (cherry picked his changes into mine, after the common ancestor) so that both his and my changes were in. It worked fine. However, he wanted to push a bug fix a day later and did it out of his own branch without syncing with mine. Guess what happened: my changes were gone from the build and only his were present. Needless to say, these multiple remote branches make continuous integration (which I would like to start doing and is not presently done), difficult or virtually impossible.

Frustrated with all this, I have been working on a proposal to my team how to change this configuration. My idea is to have an INTEGRATION SHARED REMOTE BRANCH that everyone pushes their stuff into and that is something like a work-in-progress branch that anything can go in as long as it compiles and passes tests (basically passes the build). CI daily builds could be done out of this branch. Then there is a release branch to which stuff is not pushed in directly but is cherry-picked out of the WIP branch to correspond to what we want in the release. So if we think that Dev1's changes will go in the immediate next release, we cherry pick his changes in it. But the important thing is there is one UNIFIED branch for all the developers on the team that work on the same project as opposed to them working in each one's isolated silo. This way, we could actually rebase our local branches with the shared remote continuously and get our peer's changes timely as opposed to when they become part of the master (or production) when the volume of changes to be synced can make the merging process a living hell.

I would like to inquire about the pros and cons of my proposed methodology vs what the team is doing presently and is explained above. And generally, with the idea of the current release culture in mind, which perhaps is not within my powers of changing as it is affected by many members of the organization above me, what would be the most efficient and painless teamwork setup.

  • 1
    It seems if you were to name your "shared remote branch" as "integration branch" all would be well. With the integration branch assumed to never be functional, you allow continuous integration while not releasing the trunk without gatekeeper approval. – msw Jan 31 '15 at 0:21
  • yes, in fact the term integration branch was exactly what i used when i was discussing this with the teammates the other day – amphibient Jan 31 '15 at 0:23
  • Do you make changes in some kind of "sprints"? How long are these? – scriptin Jan 31 '15 at 1:57
  • i wish we did but not really – amphibient Jan 31 '15 at 2:15
4

I'd keep those feature branches (very much like what you describe now), but make sure they are feature branches, not individual developer branches... Developers work on these feature branches, develop and test their feature.

Then on top of that, like you say, have an integration branch where all changes get merged, compiled and perhaps get some day-to-day testing. Merges don't happen until the feature's developers are confident and have tested that what they developed doesn't break stuff. Beware, this doesn't mean their feature is completely done, rather that what they 'publish' is good, sound and no longer in code-flux.

Benefits:

  • merge conflicts get found and fixed early on
  • everyone can see where the code is going by looking at the integration branch Whatever is in there is considered to-be-released and not subject to large changes, exceptions notwithstanding.
  • this branch can be tested for merge-damage (i.e. 2 features don't work well together). You no longer need to wait for the feature to be merged into the release branch (on top of previous features) to find and fix these issues

In time, you might find that testers spend more time testing the integration branch and less time testing the release branch because more issues have been found during integration.

But, opposed to cherry-picking individual changes into a release branch, I'd opt for merging in each feature branch into the release branch and stabilizing that until actual release. Merging gives you the extra benefit of being able to do "git log integration..release" or "git log release..feature" and get overviews of pending changes. If you cherry-pick, git has no knowledge of what did or did not make it into the release.

Connaisseurs will find that this resembles Linux kernel development flow a bit, where linux-next serves as integration repository(/branch) where all features must have lived a while before being merged into mainline and developers work on their own local repositories (/branches).

  • but the problem with this approach is that it is hard for feature developers to refresh their local branch (and their development environment) with the ongoing changes being made by their peers. to do that, they would have to merge the changes in the integration branch into their feature branch and then rebase their local branch against that. that involves an extra step that i would like to avoid. another problem with this is that it shifts the burden of reconciling conflict upon merging to the integrator as opposed to the developer who is responsible for the conflict – amphibient Feb 2 '15 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.