If you save up a bunch of work, dump it on the main branch, then start a new development branch that lets you escape from the integration pain of your big merge, then trunk becomes a dumping ground that nobody wants to (or can) work on.
That seems painful but it's less painful than merge hell or deploying a change with a massive delta to production and needing to roll it back and unpick what went wrong.
Working out all kinks on an isolated branch is very hard to do. You need to integrate to hear the screams of the team you never expected your change would affect. So your choice is to integrate commit by commit on trunk, or to wad it all up into a single waterfall release from your branch to trunk, and then spend hours/days bisecting to find which commit caused the screams.
As jozzas said, feature flags enable your code to safely lurk on trunk before it's functional.
My understanding of this though is that there isn’t supposed to be a difference between “what we’re working on” and “what’s deployed”, which I think then means you don’t really do “long term” development.
I have a mono-repo with one master branch - that auto-deploys to test - and one release branch that auto-deploys to staging. I can hot-swap my staging and production environment with the click of a button.
Simple, and it allows us to deploy a hotfix of needed, and we've done some major work on master that needs to be validated first...
But,... It all depends on your context and your needs...
but you have to be so so careful when you're missing up history, when it comes to db migrations and api compatibility
I prefer having a gitops repository that describes the environment. Completely decoupled from the source code repository. If some automation directly from the source repository is required, a CI job can automatically update the gitops repository and trigger a deployment.
Separation of concerns.
Once something is ready for deployment it can be deployed, in the best case this is just clicking one button or one CLI command.
Developers shouldn't be afraid that one wrong commit can automatically just go to production.
Two possible solutions: Git tag everything that's getting deployed. Or just keep track of the commit hash that is deployed.