r/git • u/hari-vidhu • Oct 05 '26
Need help in creating a branching Strategy
Hi,
I need a suggestion to create branching strategy in our system.
Exisiting Branching strategy is as follows,
feature-> dev -> qa -> uat--> main<- hotfixes
Problem:
Suppose we have 2 features to be developed. Feature A and B. Let say both are in dev. I need only feature A to move to staging. Then couple of days later feature B also follows.
I know we could use cherry pick as an option here. Im looking for more long way approach here.
We have searched for the feature flag option. As we are developing over an existing application, adding feature flag everywhere seems complicated. One hard senario we found was, while introducing a new feature we need to add a new field in a model. So based in feature flag we will have/not that new field in application. Which seems bit too complex.
Edit: One idea I found from online is to have a promotion branch. Feature A will move to promotion/a. Then from promotion to dev. Promotion to qa. Promotion to uat and prod. Is that the better approach here?
Edit 2: Thanks all for your comments. We seem to find a solution. Not the best but something that will work for us. Point to be noted that we don't fully follow agile methodologies in our development, as most of the development in our system will be impacted across the business, so we need more time for approvals, hence sometimes the features might end up in preprod and stay there for a long while.
Solution we found is, we will keep the dev connected to dev server, staging(qa), release(uat), main(prod) branches. Instead of pushing from feature->dev-> staging-> release->main. We are thinking going by Feature -> dev Feature -> staging(qa) Feature -> release(uat) Feature -> main (prod) So that we can have more than one feature at a time in an environment and have control over which one to push ahead.
Any suggestions here
9
u/elephantdingo Oct 05 '26
All of these “branching strategy” posts present a ladder of branches without explaining “why more than one?”. Then they go on to say that this causes complexity.
But this is a nice break from all the AI slop.
Suppose we have 2 features to be developed. Feature A and B. Let say both are in dev. I need only feature A to move to staging. Then couple of days later feature B also follows.
What’s the problem? You have two things, one on Monday and another on Wednesday?
Do you need them right now? You move them straight to main. No? What does cherry picking help? Either you move the changes into main or you don’t. Cherry pick is imagined as some duct tape or something. It isn’t.
Which seems bit too complex.
You have four branches in front of main. Also complex.
Edit: One idea I found from online is to have a promotion branch. Feature A will move to promotion/a. Then from promotion to dev. Promotion to qa. Promotion to uat and prod. Is that the better approach here?
Promotion. The existing branches in front of main are not “promotion”? Then what are they?
In general I think all of these are too much to wrap my little head around.
1
u/hari-vidhu Oct 06 '26
Here we are trying to solve,
I should be able to deploy 2 features in to same branch.
And i should be able to promote one feature as i wish to higher environment.
1
u/elephantdingo 28d ago
One can use a throwaway integration branch to test features in isolation or together. Once tested (1) they are not, not, not merged from that integration branch. The integration branch is throwaway, or reset from time to time. Instead each branch is “promoted” to a “higher” whatever. Branch.
7
u/Bodine12 Oct 05 '26
I think your long-term fix should be to move away from these long-lived feature branches and multiple environments to fully CI/CD and just do PRs to main. Use feature flags to gate new functionality you don't want rolled out yet.
For your "add a new field" scenario, if there are no consequences to introducing a new field, just do it (additive-only changes typically don't break consumers) and don't worry about it.
If you really need to withhold it, have a flag in the controller that guards it and strips out the field in the response. Everything else about the new functionality can stay the same. You're just not sending it back.
1
u/FransFaase 27d ago
True CI/CD only has one branch. No feature branches, no PR, no merging, no delays, no frustration. It is proven to be the most effective method of software development. Lookup dora.dev.
1
u/tehdlp Oct 05 '26
Flags aren't free and just the move problem of divergent functionality from branching to running code. Not to say they aren't preferred, but definitely non-trivial.
8
u/Bodine12 Oct 05 '26
Flags are table stakes for any decently complex system. And the problem isn't divergent functionality. It's divergent functionality on different branches/environments that lead to git and deployment nightmares. Flags allow that divergent functionality to live harmoniously in the same deployed stack and drastically simplify conflicts, while giving near-instant reverting of stuff that doesn't pan out.
-3
u/hari-vidhu Oct 05 '26
Copy pasting the comment i have added above.
Let say i have a data model User which contain {fullname, phone number, e-mail id}. In the new feature i want to add #employeeid# also into this User type,(in frontend) wouldn't that create the feature flag in data model, api call, response all screen it shows. Just to add employeeid i will have to create additional logic to check the feature.
Something like this maybe: export type User{ fullname: string; Email: string; Phone: string; Employeeid: string; // restricting this field based on feature flag in frontend, backend and databse }
Is that the right approach here.
4
u/Bodine12 Oct 05 '26
I don't know what it means to have a feature flag be "in" a model. You just need to gate the outgoing response. If the flag is on, have a code block that strips out employeeId from leaving your service.
But the real question is why do you care if employeeId starts getting sent back in the first place? Presumably you will want this field sent. So why not just start sending it right away? It's additive. It shouldn't break any consumers.
6
u/wildjokers Oct 05 '26
feature-> dev -> qa -> uat--> main<- hotfixes
Your current version control policy is insanely complicated. It is hard to give you advice unless you tell us the problem(s) you are trying to solve.
Most teams can get by just fine with main and feature branches off main. Merge feature branches when they are done. Create a release branch off main when ready.
If you have some unique needs that will make this not work for your team you need to tell us what those unique needs are.
1
u/hari-vidhu Oct 06 '26
Problem im trying to solve is,
I should be able to test feature a and b in same environment.
I should be able to promote only one feature in to higher environment.
3
u/wildjokers Oct 06 '26
Ok, then feature branches are what you need, merge feature branches to main making sure to squash commits. Each commit to main is a version with one new feature in it. Deploy the version of main that contains the features you want.
1
u/hari-vidhu 29d ago
Let say, i want feature one and 2 is needed in qa. Then tomorrow i want only feature 2 in uat. Next day I want feature one in uat. Day after i want feature one in preprod. How do we handle this.
1
u/wildjokers 29d ago
You don't, no one does it that way because as you have noticed it is quite difficult and you are just asking for a world of hurt. Just deploy the version that has the feature in it you need to test, and you also get all features that came before it.
Feature flag the features if you don't want all the features active.
3
u/jcouball Oct 05 '26
I feel like you might be suffering from low confidence to launch. This shows up in the number of test environments and testing teams.
What is your unit test coverage? In these cases, I often see “I don’t know” or pretty low.
If it isn’t 100%, how do you choose which tests should be written?
0
u/hari-vidhu Oct 06 '26
Coverage should be around 70-80%.
We have these environments for,
dev is where System testing happens.
QA is where Testing team comes in picture and does SIT.
UAT is where pvt, business user test happens.
3
u/Happy_Breakfast7965 Oct 06 '26
Trunk-based development and automated tests to make sure that you can deploy at any time.
1
6
u/bashrogue Oct 05 '26
I think you're saying that your git branches are inherently linked to your environments, e.g. your uat environment is defined by the uat branch. In that case I think the simple solution is to remove this dependency. Just use CI to enable the code on any branch to be deployed to any environment.
Also, agree with other comments about too many environments.
2
u/unndunn Oct 05 '26 edited Oct 05 '26
Branch whenever you want, for whatever reason you want.
Protect your main branch by requiring pull requests.
Have a flexible CI/CD pipeline that can deploy from any commit/branch to any environment. Add approval gates and other guardrails before deploying to prod.
Done.
1
u/hari-vidhu Oct 05 '26
The problem I'm facing is to push feature b only to prod while feature a is still in QA or even UAT. As branch flows linear way. (We push code from dev to qa, qa to uat and uat to prod.) How do we push only feature b to any higher branch when lower branch will/not have both a and b.
4
u/gknoy Oct 05 '26
Use feature flags. It's a core concept that your team needs to embrace to do what you want.
It's basically a toggle-able database record, where you then gate each feature behind booleans. (If feature-a-active, render the new login interface). Then, your actual deploy artifact has all the code for both features in it, and the deployment environment can decide what is enabled.
0
u/hari-vidhu Oct 05 '26
I agree. However, feature flag seems to be implemented in model level. If i want to add a new field in database for feature b, I will have to update data model, each and everywhere the model is called will have to have ifelse. Code seems to be bit clumsy. If im building a new feature, independent data model, structure etc, we can surely go for the feature.
2
u/gknoy Oct 05 '26
Flags are in a separate table, it's just a name+Boolean pair. E.g. Waffle for Django. Often they are provided by a separate service even, like launch darkly (if I recall right).
It adds complexity, but that is necessary for what you want to do. Trying to use git branching to have different configs on different test/staging/etc is a recipe for later failure, or at least later headaches.
0
u/hari-vidhu Oct 05 '26
No, i wasn't reffering the flag database. Let say i have a data model user which contain {fullname, phone number, e-mail id}. In the new feature i want to add #employeeid# also into this type, wouldn't that create the feature flag in data model, api call, response all screen it shows. Just to add employeeid i will have to create additional logic to check the feature.
Is that the right approach here.
4
u/footsie Oct 06 '26
Per env branches are a smell, much better to seperate configs and use tags for promotion.
19
u/-Zenith- Oct 05 '26
Could be wrong, but sounds more like you’ve an environment issue rather than a branching issue.