> This was terrible at the time and it remains terrible now.

I strongly disagree. This branching model didn't came out of the blue. This branching model is a direct mapping between regular run-of-the-mill release processes for applications intended to be delivered and installed by the general public, and how Git implements branches.

Let's actually look at the git flow workflow branching model and see what it does. There are:

* a develop branch. Where commits/pull requests are continuously integrated as part of the everyday development work. Is this complex? No.

* feature branches. Where developers present their changes as part of pull requests prior to merging them onto the development branch. Is this complex? No. Software development platforms such as github and gitlab even support creating them automatically as part of the normal ticket creation workflow, and even support triggering dedicated pipeline workflows.

* Release branches. These are used to pick a specific state of the development branch to prepare it to be releasable to the public, and prevent it from receiving additional features. This involves things like bumping up version numbers, update changelogs and docs, flip up feature flags, and more importantly trigger pipeline workflows to generate production-ready installers. These installers are then subjected to build verification tests, manual tests, deployment tests, and Product managers use them to evaluate what users will receive. Is this complex? No.

* bugfix branches. What happens if a bug is found in a release candidate? You push a fix, of course. You push it directly into the release branch and afterwards create another release candidate version to be subjected to BVTs and manual tests. You also need to fix the bug in the development branch. Is this complex? No.

* The prod branch. Once your release candidates are finalized, you cut a release. This can mean tweaking version numbers and docs again, but the goal is to persist the exact version that was released to the public. Also, if an important bug is found in production, such as a crash, you're going to have to prepare a patch release shipping only a fix for it. This branch is used to fork a new release candidate, tweak stuff like version numbers, changelogs, docs, get the fix in, run regression tests, have Product Managers double-check that the bug is fixed, and release a new version. Is this complex? No.

I followed this exact branching model for all non-web projects I worked on for a timespan that goes over a decade.

Here's the fun part: I followed it before I even knew this page existed. Why? Because this is what you eventually end up converging to if you are a professional doing professional work with a professional team to deliver a production ready version of a product built by professionals.

Why is that? Because real world requirements emerge. You learn the hard way that you cannot pause continuous integration when preparing a release, and thus you need release candidate branches to not block other developers. You learn the hard way that you need to do additional work over a release candidate in order to get it ready for production. You learn the hard way that after you release a version of your app then eventually you will need to scramble to release another version to ship a critical bugfix. You learn the hard way that you need to work in multiple releases in parallel. You learn the hard way that sometimes a release is scrapped because the Product Manager changes their mind and instead of shipping a hotfix we ship additional features. Etc etc etc.

Now, there are things in this branching model that might not be ideal. For example, merging release branches back into a single prod/master/mainline branch is convenient as a way to ensure the stable release is front and center in a git repo, but it doesn't work if you need to have multiple releases for multiple versions. In the last few years the teams I worked on ended up not merging release branches anywhere, and just kept them dangling out of the development branch. This helps manage the complexity of a major release bump where you need to continue maintaining both the new and old release versions, and possibly even ship minor/patch versions of the old release.