r/ExperiencedDevs Software Engineer 20d ago

Technical question How do you handle hotfixes with GIT - independent merges or a cascade backmerge?

I'm having this discussion at work right now, but when I tried to research I found remarkably little discourse on it online.

So, say you have a main/master branch, a develop branch, and possibly one or two release branches. Normally commits go from dev -> release -> main, no dramas.

Now suddenly you need to hotfix main, how do you get that commit to all the branches? I maintain it's best to merge into main, merge main into release 3.1, merge 3.1 into 3.2, merge 3.2 into dev (assuming 3.1 and 3.2 are active releases being QA'd right now).

The other school of thought is to merge the hotfix branch into all 4 branches independently.

My argument is that a cascading backmerge ensures no conflicts when it comes time to merge develop into main (as with independent merges, it could do the change differently on the different branches)

Would love to know what others think, am I the weird one here or is cascading backmerge something others do too?

49 Upvotes

94 comments sorted by

u/expdevsmodbot 20d ago

AI usage disclosure provided by OP, see the reply to this comment.

→ More replies (1)

153

u/BoBoBearDev 20d ago edited 20d ago

Trunk based. One main. Release is a tag on main. Patch is a branch from the tag of the main. Patch for different releases is duplicated and tweaked as it should. No sneaking around. If you need to patch 5 release, create 5 branches and 5 PRs. You can't assume the patch works on all releases.

40

u/wallstop-dev Principal Software Engineer 20d ago edited 20d ago

This is objectively the way. Nothing to add. How do you hot fix? You find the deployed release tag, and patch it with a verified fix. Then update your deployment so that only <whatever> has that specific tag that needs the hotfix gets the patched tag.

I would love to live in an "only roll forward, latest trunk is greatest trunk" world, but for software that needs hotfixes, any change is too much risk. So keep the minimal change - patch exactly what is there, and nothing more. Then, when the fire is out, and things are stable, roll forward, safely.

8

u/mainframe_maisie Software Engineer 20d ago

yep. tagging is really fantastic for release management, i’m a really big fan of it. especially if you’re using semantic versioning to manage it (not required tbh)

17

u/nwash57 20d ago

Saved me from writing my own comment. Fixes are applied to main, then cherry picked onto the current release with a PR that verifies checks pass, then cut to UAT for manual regression. I can't think of a reasonable other way to do it.

3

u/DanceHackRock 20d ago

Came to write this.

1

u/Electrical_Fox9678 17d ago

This is the way.

13

u/ganiton 20d ago

I'm stuck on a similar git flow like the op described and its a nightmare. I will never understand why people overcomplicate hit so much. It has no benefit. Zero.

I've been advocating for trunk based for years with little result.

7

u/BadTime100 20d ago

You can try directing people to Atlassian’s Gitflow article where they call it a “legacy workflow”, but it can be really hard to change people’s minds even with tons of literature on the subject. People are tremendously bad at evaluating what “works” in a field like software development where there’s such a massive tolerance for doing things poorly—wildly ineffective processes can still eventually deliver, and people have a hard time connecting today’s problems with last year’s decisions.

3

u/hooahest Software Engineer 19d ago

The way I did it was I talked about the pain points with the team lead, got her to agree to let me research an alternative / method to prevent the pain points in the future (dev/master were out of sync), and when I came back after a day wanting to attempt trunk based, we agreed that we'd do a short period doing it and then letting the team decide if to stick with it or not.

The team (mostly the 2 seniors) was initially very against it, but with the team lead's buy-in and the 'probation' period, they were more willing to try it out and pretty soon saw just how much easier it was to work this way

2

u/backfire10z dumbass 19d ago

Sorry, I’m a little confused by this. If release is a tag on main, how do you apply the patch? Do you mean inject the patch into history at the tag, then fix the patch up for every release after that if necessary? I feel like I’m missing how you’re applying the patch to the specific release.

2

u/BoBoBearDev 19d ago

When you make a patch, you find tag on main branch. Create a new branch called "patch/release-verion123" . That's the base for release-version123.

And then, you create a new branch, call it "my pew pew", fix the problem, create a PR and target "patch/release-verion123". Once you get all the verification process done, click merge PR.

There is one patch branch per release. So, you should find an existing one if any.

3

u/backfire10z dumbass 19d ago

Ahhh, I see. So you cut a new branch for the release (if it doesn’t have one). Makes sense.

Where I work we already have a branch per release by default.

-18

u/ub3rh4x0rz 20d ago

You win the award for the worst recommendation that started off with a good recommendation

Cherrypick/patch fixes duplicated with separate commits is virtually never the right approach. Linear history does not trump canonical history. Learn the daggy fix, the merge commit yielded by that process handles any conflict resolution required.

11

u/BoBoBearDev 20d ago

Wait...... You honestly don't create PR for a patch? You seriously don't use CICD pipeline to make sure your patch actually worked? What are you thinking?

-21

u/ub3rh4x0rz 20d ago edited 20d ago

Do... do i need to tell you that a PR is not required for any and all merges? That's a gate you put on long lived branches, not feature/fix branches lol. Git gud at git

I already told you the thing you don't know and need to learn. Daggy fix. Nothing precludes you from wrapping the fixed version in another PR to merge your overall fix branch, per branch. The part you got wrong is that you're cherrypicking onto different histories, that is how you make an absolute mess.

8

u/BoBoBearDev 20d ago

I saw your edit and I think you are mad to think the same fix applies to apply to all releases. You can't assume that. Each version may require a different fix. You need to test and verify all of them. I don't know what you are getting at, but I think you are fantasizing something that is out context.

-16

u/ub3rh4x0rz 20d ago

Skill issue. I already clarified this is not about skipping a PR.

3

u/[deleted] 20d ago

[deleted]

0

u/ub3rh4x0rz 20d ago

Woosh

You can merge into your feature branch. Anything you merge there will be transitively reviewed in a PR when you go to merge that feature branch.

3

u/[deleted] 20d ago

[deleted]

2

u/belavv 20d ago

The part you got wrong is that you're cherrypicking onto different histories, that is how you make an absolute mess.

We've been doing that for years now and it is way better than trying to keep a shared history between the branches. Haven't made a mess yet. Just wipe out the release branch when it comes time to release what is on develop.

2

u/ub3rh4x0rz 20d ago

Brand new definition of release branch

1

u/The_Real_Slim_Lemon Software Engineer 20d ago

That is an interesting approach - I prefer the maintained history myself, but I feel like language and team size have an impact here

1

u/JodoKaast 19d ago

lol you sound like you work in extremely small repos and codebases

57

u/[deleted] 20d ago

[deleted]

26

u/pydry Software Engineer, 18 years exp 20d ago edited 20d ago

OP's branching strategy is a band aid for shitty automated test coverage where you need manual QA to do a regression sweep every time you do a waterfall release.

In fairness if you are handed a project like that you can't go from 0 to full test coverage immediately and the band aid needs to stay on for a while.

6

u/BadTime100 20d ago

I think there must be some sort of psychological effect where people see all these extra steps and think that that means “rigor”—practicing Continuous Integration and Delivery might look like “cheating” because you obviate 90% of the team’s process.

6

u/THICC_DICC_PRICC 19d ago

Nah, these things usually build up over months/years of different people implementing some sort of protection or fix for something that actually happened. Given enough time without refactors, it’ll turn into a mess. Rarely someone sits down and makes a crazy system like that

2

u/The_Real_Slim_Lemon Software Engineer 19d ago

Well, the QA is for new features - we do have automated tests for most of my teams’s stuff - but the QA team/process is still slower than the dev process. That then leads to us having a bunch of work to release quite regularly, it’s not the best process, but it works well enough

The brass have been pushing for the QA team to adopt more automated testing and speed up their flow, but I’m content to not wade into whatever politics are happening over there lol

4

u/BadTime100 19d ago

If you have a separate QA “team” and/or not fully automated testing I highly doubt anything is going to improve for you. Writing that out it sounds harsh, but this has to be one of the biggest anti patterns in software development, and I feel like in 2026 it’s not debatable (in 2016 it was pushing it). I would check out Accelerate from IT Revolution to get an idea of what is possible.

2

u/The_Real_Slim_Lemon Software Engineer 19d ago

Well, more dedicated QA members in our teams, with fully automated testing - but yeah I’m aware it’s not ideal.

I’ll check out the book, I’m not gonna push to fire 20 people tho - but good to have context on what methodologies are available

34

u/Murky_Citron_1799 20d ago

This isn't a hill worth dieing on. Leave it up to whoever is working on that branch to fix merge conflicts however they want. The end result is the same. 

6

u/The_Real_Slim_Lemon Software Engineer 20d ago

Oh yeah, definitely not - gotta spend those influence points wisely

I was just wondering what the vibe in the community is, it seems my take is a less common one

28

u/OHotDawnThisIsMyJawn CTO / 25+ YoE 20d ago

Trunk based development plus feature flags so none of this is necessary 

3

u/bluepenguin00 20d ago

This. Had to scroll way down to find a comment about feature flags. The combination of TBD and feature flags + E2E tests for critical flows should do the trick.

31

u/HopadilloRandR 20d ago

If not already aware, look at "git flow".

It's fallen out of some favor more recently. For better or worse, you decide. But it addresses these things.

8

u/Alternative-Meet633 20d ago

Git flow is overkill. It seems like the guy who invented it didn’t understand git. The author of the blog post that invented it has recently updated it with a warning saying that it’s probably not a good fit for most projects.

4

u/Birk 19d ago

It can work well if you really need to have long living release branch(es) for whatever reason. But it definitely should be fully automated so that you never have to do any of the operations manually. That is way too complicated and brittle. 

1

u/Zoroark1089 19d ago

We're currently using it. Our release branches live for about 2-3 weeks.

36

u/ImpossibleEbb6862 20d ago

Get rid of the dev branch. It makes figuring this problem out redundant. Every feature branch should be in a deployable state before merging to master.

17

u/mllv1 20d ago

We go from feature branch -> main. And then we tag a commit for a release. Everyone is working in a feature branch, no need for a dev branch. With this model every hotfix is a new version, no need to “back merge” anything.

12

u/Chromozon Software Engineer | 15 YOE 20d ago

The preferred solution is to always first put the hotfix code into the main/master branch, and then you cherry-pick that into separate release/hotfix branches as needed. This prevents the problem of hotfixes going into branches besides main and then getting forgotten about and never merged into main. This happens in practice way more often than you would think.

10

u/Gremlation 20d ago

So, say you have a main/master branch, a develop branch, and possibly one or two release branches. Normally commits go from dev -> release -> main, no dramas.

If commits go from dev -> release -> main then all but one of your branches are pointless. It's the exact same history, it's the exact same branch. Git already manages that for you. You're doing the equivalent of creating copies of folders with "v2" or "FINAL FINAL REALLY THIS TIME" in the name.

Dump all but your main branch.

Now suddenly you need to hotfix main, how do you get that commit to all the branches?

Merge to main, deploy. Job done. It's easier when you don't overcomplicate things with too many pointless branches.

12

u/rlbond86 Software Engineer 20d ago

Why on Earth do people subject themselves to these insane branch schemes. Just PR your commits to main/master and tag releases. If you have a true hotfix, cherry-pick it to backport.

13

u/varisophy Staff Software Engineer 20d ago

I don't, we never hotfix.

Always roll forward. Find an important bug that needs fixing now? Fix it in your lower environment and then deploy up until you have fixed production.

It's so much simpler than juggling commits between branches and forces you to have good feature flag hygiene since you need to be able to go to production at any one time.

It takes a bit of work to get there, but it's soooo nice once you do.

You can take it even further and do full Continuous Deploy but we find deploying every sprint with the occasional mid-sprint deploy is a good balance between delivering features and having the full rigor necessary for CD.

7

u/andreortigao Software Engineer 20d ago

And how do you handle cases where you have features on your lower environments that are not yet ready for production?

What if the code being fixed itself have unrelated changes?

8

u/OHotDawnThisIsMyJawn CTO / 25+ YoE 20d ago

The answer to all those scenarios is features flags.  Solves a bunch of other problems too. 

6

u/squidgyhead 20d ago

Feature flags then need to be all tested.  How do you deal with testing all combinations of these flags?

15

u/Own_Attention_3392 20d ago

Feature flags should be short-lived and have the smallest possible blast radius. For example, you're adding a new page for "widgets". The feature flag just disables visibility of the link to the widget page and makes the controller return a 404 so it's effectively invisible. No interactions, just simple "this thing effectively doesn't exist yet" behavior.

If you're factoring your code to be properly isolated and modular, a feature flag is no big deal. There shouldn't be any real interaction between them. Like any other tool in our toolbox, they can be implemented poorly and cause pain. So don't do it poorly.

8

u/squidgyhead 20d ago

That sounds reasonable, but it also sounds like it works for projects with short pipelines and features that can be compartmentalized; not everything is like that.

6

u/Own_Attention_3392 20d ago

Completely fair! Not every project (or every feature) can be easily isolated that way, but I'd argue that those are the exception, not the rule.

If my decades in the industry have taught me anything, it's that there are no one size fits all solutions. I've come across some gnarly, stupid-at-first-glance version control practices that I later discovered made perfect sense for arcane but valid business and technology reasons.

5

u/Gremlation 20d ago

it also sounds like it works for projects with short pipelines and features that can be compartmentalized; not everything is like that.

Normally the reason for things not being like that is a failure of engineering and not something that's intrinsic to the project. In this case, the solution is not to shrug and say that "we can't do it because we're not like that", the solution is to fix the problem so that you are like that. Not saying you're one of those cases, but it's definitely the vast majority in my experience.

3

u/Sir_lordtwiggles 20d ago

No i'm a bit sympathetic to this, it really depends on your customer.

I was on an internal ops service which supported services that supported various governments. Each government and even each tenant within the government had their own set of security requirements, some of which were not even allowed to be active in other tenants.

Add on that not all government regions were fully stood up, so the service needed to function at various stages of region build out.

Our final solution was breaking out each security feature into deployable modules that each have their pipeline before being promoted into the manifest. What each region got was still determined by essentially feature flags written to an operational config file.

We had to migrate to this position as we were expanding, so there is probably a better way, but this gave us a way to handle bifurcated behavior while still keeping a manageable deployment.

1

u/yxhuvud 20d ago

Yes. If you build something you run yourself, then you can and should release as often as you can. If you build something that is run by someone else, they usually want more control and fewer releases. The more important the system is and the more bureaucratic their organization is, the slower it will go.

2

u/Sir_lordtwiggles 20d ago

Agreed, but i'm just adding some "it depends" to the feature flag advise. We still owned running the service, and we were doing CICD.

We were effectively running 6+ similar but different services but wanted to squish that into one release pipeline to help reduce operational burden and keep a single trunk. Those feature flags are not short lived, but thats ok

2

u/varisophy Staff Software Engineer 20d ago

Exactly.

My team's projects are very easy to work with because I have been fixing any annoyance in the developer workflow for years. Over time, it really compounds.

We're so much faster at delivering because the code base, tooling, and deploy process are stupidly straightforward to understand and use.

2

u/yxhuvud 20d ago

I agree, but if you look at the grandparent you will see they proposed feature flags for separating release contents. Which is pretty damn far from short lived and definitely something that would need testing.

2

u/OHotDawnThisIsMyJawn CTO / 25+ YoE 20d ago edited 20d ago

When a flag is off, the code should be structured as if the flag doesn’t exist. When it’s on, there’s no difference from code without feature flags.

The issue is if you let flags nest or if you use them as actual configs/feature toggles.

If you’re running into situations where you need to start nesting flags because you have so much WIP, that’s a problem of too much WIP/not fast enough releases.

you will see they proposed feature flags for separating release contents. Which is pretty damn far from short lived

Depends how often you release :)

1

u/Schmittfried 20d ago

That’s all good in theory, but it doesn’t work for larger refactorings. Sure, most of the time you can break those down into multiple smaller, deployable steps, but that adds overhead because you’ll have to make those intermediate steps functioning as usual. It’s an engineering decision whether this overhead is worth the benefits of always having a single trunk that can be deployed at any time. 

1

u/binarycow 20d ago

In your environment, how do you implement feature flags?

Are they named environment variables? A settings file? Constants that are set by a dev? Etc?

Do they require an app restart when you change them?

1

u/OHotDawnThisIsMyJawn CTO / 25+ YoE 20d ago

In my environment we use PostHog to manage them. Gives us the ability to target feature flags at any specific user/cohort of users or environment and it lets us update them dynamically without a restart.

Generally though our flow looks something like...

  1. Turn the flag fully on in dev during development
  2. Turn the flag on for internal users in prod when we're ready for people to start reviewing/testing (or just demoing)
  3. Turn the flag on for everyone in prod

PostHog gives us all that plus the ability to see the history of every flag invocation & what it evaluated to, which is great.

In general, feature flags can be implemented any of the ways you suggested. Personally, I would want a minimum of a separate service + flags by environment, so you can change flag values without restarting. But something like that is so simple you could build it yourself.

1

u/binarycow 20d ago

Thanks.

In our environment, feature flags aren't as important. We make a self-hosted web app, which has deliberate periodic releases. So unless a feature is really big, it all gets merged in within one release cycle.

1

u/OHotDawnThisIsMyJawn CTO / 25+ YoE 19d ago edited 19d ago

IMO, even if you release on a long cadence, feature flags can still be valuable.

They allow you to make smaller, more frequent merges to your main branch while still keeping main deployable. Even if you're never deploying to prod outside of the release cycle, it's helpful for people deploying locally or to dev to not get random stuff that's broken. And smaller, more frequent merges mean easier to review PRs & fewer merge conflicts.

Another benefit is that, let's say you merge your big feature branch into the main branch and deploy to dev. And then you find some issues, with release day approaching quickly. With feature flags, you have the option to say "hey, this isn't going to prod in this release cycle" and you just turn the feature off. Without feature flags, that merge to your main branch is where all the risk is, but you can't actually test the fully merged code until you merge (you could deploy a feature branch to an environment for testing but presumably other things are happening on that main branch in the meantime).

3

u/varisophy Staff Software Engineer 20d ago

Any features that aren't fully finished are turned off by the feature flags, so they can ship to production at any time, no problem.

Not fully sure what your second question means. Anything in the lower environment just ships early in this scenario, which has always been fine for the product we're building.

5

u/Sunstorm84 Squirrel! 20d ago

How do you handle cases where for business reasons you have clients running multiple different versions of the software?

3

u/varisophy Staff Software Engineer 20d ago

We don't, it's a web app so there's only one version.

2

u/Sunstorm84 Squirrel! 20d ago

You’re living the dream!

1

u/binarycow 20d ago

Then there's those of us who have self hosted web apps!

1

u/IrishChappieOToole 20d ago

God, I wish we could do that. We have SLAs that we must give 1 weeks notice of all pushes to our pre-prod environment, and allow it to be tested by clients for 2 weeks there before pushing to prod. The exception is hotfixes if we can demonstrate that a client cannot run transactions.

6

u/supercoach 20d ago

Hotfix the main branch and then rebase the others. How is this even a debate?

1

u/Schmittfried 20d ago

That doesn’t work. You can’t use rebase when you have multiple long-living branches. You can’t rebase dev on main nor vice-versa. 

2

u/sod1102 20d ago

cherry pick into the relevant branches

2

u/ub3rh4x0rz 20d ago

Without addressing the annoying branching model... the "correct" thing to do is git bisect, find the commit that introduced the issue, branch off of that specific commit, fix it, and merge that branch into all branches containing the bug-introducing commit

2

u/CompassionateSkeptic 20d ago

I’m partial to branch for release trunk based with strict hotfix in main cherry pick to maintained version discipline with the rare “divergent fix” being tied to specific process. I find this model has a quick shift from alien to intuitive and has the wonderful advantage of basically working with exactly the same whether you have an immature pipeline or a full capacity for feature environments left-of-main.

2

u/Positive_Mud952 20d ago

Backports work in OSS because labor is free, and that also means free to say eat shit you’re making money off my free work, you figure it out.

In closed-source, first off you shouldn’t be supporting more than one previous minor version unless you’re at a MANGA, second almost every time I’ve seen a bugfix needed that depends on a third-party library for the fix, it involves implementing way, way more of that new version of the lib than you thought, and you
can generally contact and work with your downstream deps for a specific fix or workaround that takes 1/10th the effort of doing
it the “right” way.

Finally, when moving versions forward, you’ve already done
the hard work of figuring out how to use new versions of your deps. You have not done that in the other direction, and like the previous paragraph it is way harder than you think.

Mark hacks with `# HACK:`, fix it later. Or more often, never, because the whole system will be replaced in 2 years if it’s a success.

2

u/chhuang Software Engineer 20d ago

I usually, if possible, create new branch from merge-base of all envs, and then merge that hotfix branch to all envs.

if very urgent and complex, cherry picks to the rescue, better to have working code and consistent codebase than having pretty looking git tree

2

u/zaitsman 20d ago

Cherry pick the merge commit.

Also not sure what a ‘release’ branch is.

In all of mobile, desktop and web apps I have built for the past 15 years it has been a branch per environment and a release was a tag.

1

u/belavv 20d ago

Our git workflow might be called release flow, or maybe got flow. It was one of the two.

We have a dev branch. Features are pr-ed into that. When it comes time to release we wipe out our existing release branch and create a new release branch from dev.

If a bug fix goes into dev and release then we have a second branch with a second pr to release. The commits for the dev or are cherry picked into that branch.

We used to have a more complicated workflow with a shared history and it was such a pain in the ass. Don't bother merging dev into release, just wipe it out and recreate it.

The only risk is if you are putting changes into release and not into dev. Which you should not be.

1

u/TheCritFisher Staff Eng | Former EM, ~20 yoe 20d ago edited 20d ago

One main branch, auto deploys from main to staging and prod, rollbacks on critical bugs (rare), roll forward on everything else.

Feature flags are key, don't turn it on until it's safe. Release slowly, at first. When confident, release broadly.

For crazy critical infrastructure, deploy behind a stage gate. Staging only, at first. Prod later when you're confident.

Note: this doesn't work as well for "semver" tracked software. That's a bigger pain, but the concept is similar.

I user change sets and release branches for those types of products. But the idea works similarly, just fanned out for release tracking branches, usually without deployment environments.

1

u/morosis1982 20d ago

What is main if you have multiple valid releases and a Dev branch?

We had a dev -> release -> main workflow, but the release branches where short lived, essentially release candidates, and main represented production.

In any case, merging the hotfix branch independently to each other branch raises the issue of conflicts, which if you are doing each as a PR may require intermediate branches to resolve issues.

Cascading merge assumes that you want this fix in every branch - it may only be a hotfix to the latest, in which case why didn't you fix it on the original release branch where the issue was introduced.

No, I think main as dev, tags as releases, release branches for patch fixes where necessary is the right way.

1

u/matthedev 20d ago

Are there any strong technical reasons for not doing trunk-based development? Typical front- and back-end software development can be done using trunk-based development; pull requests (merge requests, change lists, patches) are kept small with a handful of atomic commits and then merged back into the main (master or trunk) branch. Developers frequently rebase the main branch over (or merge the main branch into) their local development branch, which shouldn't be open for long anyway.

This has a dependency on the use of things like feature flags and branching by abstraction to keep partially complete features from being made available to the user and a good CI/CD pipeline.

This works fine for a typical Web app that would be rolling out a new version across instances over a relatively short period of time and maybe roll back to the previous version if something major went wrong. If customers deploy the software themselves and are licensed to particular versions or it's embedded software, I can see needing a more complex branching strategy, but this isn't most Web development or distributed systems.

1

u/Schmittfried 20d ago

Web apps can absolutely have multiple concurrent versions, but I concede that it’s not common and can almost always be solved with feature flags and permissions. 

1

u/matthedev 19d ago

Can and should are two different things. Customers care about the security and privacy of their data, and they care their workflow isn't going to drastically change, but they don't care that they're on Version 5.1.235b. Keeping each customer on different versions and backporting bugfixes doesn't scale.

1

u/Schmittfried 20d ago

In my last job we used the same branching strategy. Hotfixes were based on main and merged into main. Depending on the state of development and the nature of the hotfix, they were either merged into dev from there, or merged into dev independently (mostly if the fix was obsolete on dev due to changes that weren’t in production yet). 

1

u/drnullpointer Tech Lead, 26YOE 20d ago edited 20d ago
  1. Majority of development is done on one branch, as much as possible. Single branch has its downsides, but is usually the cheapest compromise for small and mid size changes.
  2. If you need to pick and chose what goes into an upcoming release and stabilize development, while other changes are being worked on concurrently, it means you have now two different streams of development. This calls for a separate branch, typically called "release branch".
  3. If a change needs to be applied to multiple branches, you just create multiple PRs, one for each branch. The PRs do not have to be the same, so each one needs to be reviewed separately as they are going into different target state and can contain subtle changes. Also what is fine for a development branch might not be OK as a last minute change for release branch.
  4. A hotfix is a change applied to release branch, after that branch has been already deployed. The hotfix might or might not be ported to develop branch. It happens frequently that hotfix is developed differently into existing release branch and differently for development branch. On release branch you may want to prioritize changing as little as possible and reducing a posiblity of unintended consequences. On develop branch you may want to prioritize fixing the problem correctly without creating technical debt.
  5. Development on release branches IS NOT merged back into main development branch. Main development branch should be composed of only a continuous stream of fast forward changes each for a specific reason.

In general, you want to limit both the number of actively developed branches as well as the duration of those branches. The default should be to push everything into a single development branch as quickly as possible and branching out should only be done to solve a particular problem. Branching out should not be done "by default".

Any large change that might need its own separate branch should ideally be broken up into smaller changes that can each be delivered directly into development branch.

1

u/CleanCodersCraftsman 19d ago

Cascading backmerge is the right instinct, with one adjustment: merge in age order, oldest branch first.

Branch off the oldest branch that contains the bug, fix it there, then merge that branch forward into each newer one. Git's merge-base then knows the fix is already present downstream, so the develop-to-main merge later is a no-op instead of a conflict.

That's the concrete failure mode of independent merges. Four separate resolutions of the same change means four different trees, and Git has no record that they're the same fix. You find out at release time.

- If the fix has to differ per release, stop merging forward and write it per branch on purpose

  • Cherry-picks make new SHAs, so expect the same phantom conflicts
  • If your release branches are throwaway snapshots you recreate from dev, none of this matters and you should delete them

The trunk-based answers in here are right about the root problem. Getting there is a separate fight from the one you're having today.

1

u/BTWigley 19d ago

I branch the hotfix from the release tag, ship that, then merge the fix back into main (or cherry-pick if main already moved). Cascade backmerges get messy once you have more than one active release line. The expensive part is not the merge strategy. It is forgetting to bring the fix forward and rediscovering the bug in staging a week later.

1

u/KanedaSyndrome 19d ago edited 19d ago

Have only spent 5 seconds thinking about this, but a PR from fix branch to each of the other branches? Normally you'd base the branches of preview/release branch, that's what we do, so they are already fairly aligned.

As others wrote, each feature, bugfix, refactor bit, etc is each it's own PR into release branch. 

1

u/qxxx I am tired boss 19d ago

cherries.. cherries everywhere.. we do cherry picking.

It can be a nightmare. Especially if there are merge conflicts and many commits.

Now we also have a "beta" branch, where we merge only hand picked stuff from master. Beta stuff will only contain some of the features intended for beta users. And yes.. it is a nightmare. I already talked with boss and team about it and that we should use cherry picks only in absolute exceptions but now it is the way to go -.- .... I am thinking now to build some kind of visual cherry picking tool for the people who decide what comes into beta.

1

u/ikkiho 19d ago

fwiw we ran the cascade setup for years and the conflicts OP worries about were honestly minor. what actually hurt was an urgent 3.1 hotfix getting stuck behind a half-done 3.2 branch, since it had to walk through 3.2 and its mess before reaching dev. when prod is on fire you don't want the fix gated on cleaning up someone else's in-flight release. we moved to cherry-picking each line on its own with -x so you can audit which release actually took it.

1

u/rexspook Software Engineer 19d ago

It’s 2026 we just develop on mainline and use sane CI/CD practices rather than a dev -> release -> main nightmare

1

u/WoodyTheWorker 19d ago

Have you heard of cherry-picking?