The point of a branch is to label concurrent development.
There's nothing about a branch that says it must be "test code" or "pre-release" code, but your perspective is common: Everyone wants blue/green or to fully distinguish between "live code" and "test code" because they think the problem isn't theirs to solve: That their manager doesn't give them enough time, or their predecessor didn't like clean code like you do, or that's just what test databases are for.
Infrastructure that really supports branching is uncommon because it's difficult and it requires very careful consideration with regards to the entire architecture. Some examples of systems that actually use branching correctly:
* Implement random 0.5%, 1%, 5% etc traffic diverted to test branches * Front-end web service selects branch from URL or cookie * Backend service compares 5% live queries against test database and compares results
If your system doesn't have something like this, you're really missing out: Really big applications (the kind that span multiple continents) don't have an "atomic operation" to their deploy, and you shouldn't try to pretend that they do. That's how we got IPv6.
You aren't possibly breaking live code
You making lots of changes to code other people might be changing, causing conflicts
You don't need to either go back and remove the old branches after the deployment or leave them in to clutter the code.
You don't have to worry as much about overlooking some portion of the codebase using the old code (if you change the API enough to make it incompatible), since you can literally remove old APIs and cause compile errors or easily detectable runtime errors.
You can change data structures with conversion scripts where it's not feasible to overlap functionality (whether those be code constructs, or disk/DB format).