34

Learning GitFlow and I have some concerns that I don't see addressed in any of the docs/articles I've read about it.

At some point code on the develop branch needs to be deployed to a QA/staging environment and tested rigorously. So with GitFlow you cut a release branch off of develop, and then you deploy release to said staging environment.

First, just wanted to clarify something real quick: the very first time a particular project/repo goes through this process, you'll actually be forking/creating this new release branch from develop, yes? And that all other times in the future, you're simply merging develop into release, yes?

So then QA tests the release branch on the staging env, all looks good, and we're ready to deploy to prod. Do you:

  • Deploy to prod and then merge release into master? ; or
  • Merge release to master and then deploy to prod?

I ask because it seems like in the former case you would need to deploy the release branch to prod, then deploy to prod, and then merge to master. Which sounds OK, but often prod and non-prod environments are not identical and code that runs perfectly fine in staging chokes the second it fires up on prod servers. I know GitFlow supports the concepts of hotfix branches but they are reserved for minor fixes. In the case of a complicated fix that requires a rollback/backout release, we now have "dirty code" (code that breaks prod for some reason) merged into master.

And in the latter case, it might take hours or even days (especially if you need to involve IT/Ops to do prod deploys) from the time you merge and put in the prod release request in, to the time the prod deploy actually occurs. And during this time you have a master branch that says "features X, Y and Z are in prod" but they are actually not.

I'm wondering if GitFlow actually solves this somehow or what the known workarounds to either case are.

smeeb
  • 27,777
  • 57
  • 250
  • 447

6 Answers6

29

The project I work in is very chaotic, decisions change in a matter of minutes, so my strategy is to procrastinate as much as possible software configuration management decisions.

Particularly, merging into master: we only merge to master after we deployed in production and we have a confirmation e-mail that smoke tests worked fine. This way we embrace chaos by managing the risk of decision changes, rollbacks in the deploy, technical problems or whichever issue may happen.

At the beginning we merged into master before going into production, but technical issues, rollbacks, management decisions at the very last minute... caused lots of problems to us, so we changed the strategy, and it's been working fine for the last 3 years.

If, eventually, after going to production some regression is found, that's a hotfix and must be handled like that :)

Luis
  • 2,833
  • 3
  • 27
  • 41
  • 8
    The problem with this approach is that after merging to master and tagging, the post-merge tag essentially points to a different commit from the one you used to deploy. This breaks repeatable builds. – RaGe Feb 26 '18 at 07:05
  • 1
    Sorry, I didn't catch your point. Could you please elaborate? What do you mean by "post-merge tag" and what's its purpose? – Luis Feb 26 '18 at 18:20
  • 1
    Per gitflow, once you merge a release branch into master, you tag it in the master branch. [see here](https://datasift.github.io/gitflow/GitFlowMasterBranch.png). In your case your production deploy is from the last green commit (before merging) while the tag points to a different cyan commit. If you wanted to repeat the exact same deployment sometime later, deploying from the tag doesn't work because you're deploying from a different commit. – RaGe Feb 27 '18 at 00:58
  • 3
    Well, you could tag the green commit, then. I don't think it's a big deal to do that. In the end, Git doesn't care about branches, but about graphs, so we're dealing with a graph of commits. If the important thing here is to tag the changes that were deployed in production you could just tag the commit sent to production, no matter the branch. Once this is done, this commit can be merged into master and the rest of developments get master into their branches. – Luis Feb 28 '18 at 16:03
  • Could you please give some examples to problems that you had when merging to master before going into production (with the technical issues, rollbacks etc.) that are solved by merging to master only after going to production? – BornToCode Mar 07 '19 at 15:49
  • They never were technical issues, @BornToCode; sadly they always were management decisions at the very last minute :) – Luis Mar 13 '19 at 18:58
  • But how were those problems mitagated by deploying from release and not from master? – BornToCode Mar 17 '19 at 09:07
  • 1
    @BornToCode Once the code was in production, there's no way back. The issue here, by "procrastinating" decisions, is that if you postpone the merge to master as much as possible you'll keep your main branch pristine, avoiding ugly reverts or patches on your main branch. – Luis Mar 24 '19 at 18:15
12

The release branch that you create is a short lived one, similar to the feature branches that you create. Once the release is finished, you delete the branch. For example, I would create a release/0.1.0 branch, do the work, and then merge.

When deploying to production, I always take the code from the master branch, meaning that I merge the release branch into master first, before deploying.

GitFlow is more about moving forward, not back. Hence why hotfixes are used to create fixes for issues that are identified.

In terms of time taken to get into Production, that is really not a concern of GitFlow, and i don't think it will provide much help in this area. This would be an issue for you regardless of which branching strategy you use.

Gary Ewan Park
  • 17,610
  • 5
  • 42
  • 60
  • unsure this should be the answer, we're missing a justification, or pros/cons for merging before or after the release. – NicolasW Feb 15 '18 at 17:27
  • 3
    A huge advantage of merging BEFORE the deployment is that it is close to impossible to miss any bug fixes (if any) recently merged back into the master and as a result create regression incidents. For that single reason I think this is the best approach. – NicolasW Feb 16 '18 at 18:51
  • I would argue that is a huge disadvantage. Wouldn't any hotfix fixed in an older release and merged to master, then be propagated to any release candidates and develop? Otherwise, release candidates will exhibit the regression, as well. And, therefore, wouldn't be "released". You're saying that any active release iterations have to be merged to master *first*, in order to get that hotfix, correct? – kevinmm Mar 21 '22 at 18:36
8

You'll actually be forking/creating this new release branch from develop, yes?

That is correct. The first time around your only option is to create the release branch off of your main branch, and that's what you'll be deploying for QA/Staging, and later on to Production.

And that all other times in the future, you're simply merging develop into release, yes?

It depends. According to the description of the Git Flow, the release branch is a short lived one. It may branch off of develop only, and merged into master. In theory, release should be merged back into develop after your release is done, and then be removed. The only thing that you should be merging into release is hotfix. This is a nice clean article about the flow.

This varies from one team to the next. I've worked on teams that exactly follow the GitFlow description, and others that choose to just delete release and recreate it from develop as if it was the first time.

Deploy to prod and then merge release into master?; or Merge release to master and then deploy to prod?

In theory, master should always contain production-ready code, and the only way to guarantee that is that what gets deployed to production is exactly what's in the master branch. That said, we probably can't give you perfect answers of what works for your team in particular.

For example, I currently work on a team with a CI/CD pipeline that leaves us no choice but to merge before: the deployment happens automatically from master. I've seen some teams where releases are too far apart, and feel more confident deploying the release branch instead and merging afterwards. This avoids deploying a human error made during the release -> master merge (which probably includes nasty conflicts built up over time).

I believe that you should choose the solution that works best for you, as the GitFlow might not cover every possible scenario and context.

r3gularJ0hn
  • 136
  • 2
  • 10
3

Deploying from master is fine for small shops. In cases where you must support multiple versions, you should maintain and deploy from the release branch.

2

I think a reason why you deploy first and then merge is that because in your CI/CD pipelines you can do some smoke tests after deployment, and if things are unstable you can do a revert by just deploying what was in the master branch originally, since your pipeline failed, then the merge to master would not happen.

If however you merge first and then deploy, then reverting could be tricky since you would have to revert the merge... So I think it makes sense to deploy from release and if things are stable, then you merge to master.

Malush
  • 33
  • 5
2

In my previous team, the branching strategy is creating a release branch and do the final tests against release branch, and merging release branch to master before deployment.Then do a production deployment with master branch.

But my current team is using a different approach that is deploying with a release branch to production and merge release branch to master after successful prod deployment. The benefit of this method is making sure the code is working in real production environment so we can say the code has been run in production correctly and then merge the release branch to master, so everything in master is working in reality. Another advantage of this approach is easily to rollback if something wrong with the deployment as just re-deploy with master branch.

For previous approach, I have experiences on rolling back the change since the production environment is more complicated and the issue wasn't found in nonprod environment before deployment, so I needed to rebase/revert the change in master branch which means the master branch is broken already until I do the rebase/revert :(

The things I like to release on release branch and merge it back to master after prod deployment are easy rollback and making sure the code in master is correct by running the code in real production environment not only in nonprod environment.

In the end, it's still depends on which approach suits your project/team.

wei
  • 4,267
  • 2
  • 23
  • 18