* Simple but quite expressive, covering a large number of use-cases.
* Reliable - there's not much in the way of rope to hang yourself.
* It's easy to explain to people new to git or software development.
It certainly works well for small teams, but I'm not sure how far it would scale - probably quite well as long as there are not too many deviations.
Also as a starting point for development with git it's hard to fault. As you become more familiar/confident you can start to add more complex commands ( rebasing history, etc.) and build quite a sophisticated workflow.
UPDATE: As to the why branch just use continuous integration debate, well continuous integration works just fine as long as your window to deployment is short (hours or a small number of days). With anything that takes a little longer or involves database migrations then branching in some form is still required. So rather than being an either/or situation they really just overlap in practice and one does not preclude the other.
This generally means that a git-flow 'develop' is less stable than a gitworkflows(7) 'master', so it's more common to be working on a new feature and find bugs that were there when you started. That's disruptive to development and its unpleasant to users that would really like the latest stuff that you think is actually ready for them to use.
Thus any decision to merge a topic branch comes with the pressure that any bugs introduced in the merge (possibly through indirect semantic conflicts with other work) will disrupt any developer starting new work between the merge and the time a fix is provided.
In contrast, merging to 'next' in gitworkflows(7) comes with relatively less pressure because bugs there only affect integration and eager users, but not new development. Furthermore, merges to 'master' come with knowledge that the feature has already been playing nicely in 'next', which contains everything in 'master' as well as some other new features.
I wrote a more extensive comparison in http://mail-archive.com/search?l=mid&q=87zjx4x417.fsf@mcs.an...
With gitworkflows(7), new topic branches start from 'master', merge to 'next' when thought to be complete, may receive additional patches while there (remerging to 'next'), and may fail to "graduate" to 'master' (either being discarded by reverting in 'next', or just not selected for this release). When complete, the topic branch is merged to 'master'. 'next' is periodically discarded (usually after a release). This means that the sometimes messy and occasionally broken state in 'next' does not remain in the history and is not used for new development, and some parts of 'next' will not be part of the permanent history. With gitworkflows(7), the history that eventually makes it to 'master' is only complete and fully-tested features (demonstrably so, because it has been in 'next' already). Gitworkflows(7) gives you cleaner history, a more stable 'master', and makes releasing less disruptive.
The main benefit of Nvies Branching Model is that it reduces anxiety.
Since you keep both fixes and features on separate branches, you minimize the anxiety of "can I do this now?" and "wouldn't this also break that". Instead, you just push and push and merge and worry later. You can work on several bugs for several clients - at the same time. Zero anxiety about fixing one thing for one client that breaks another thing for another client.
The golden rule is simply that you don't merge to master (or, for that matter, to a release-x branch) what isn't well tested to be good on a feature-x or hotfix-x branch.
So using that thing I currently build[0], I can just push-to-deploy whatever I'm working on without being afraid that I break clients who have automatic updates enabled. With this strategy, it's up to the clients: If they subscribe to a development or feature branch, it's understood that things could break. I simply have to be careful what touches master and that's it. (And in most cases, clients only subscribe to other branches in a support context, anyways.)
Finally - Yes, there is a certain overhead, but you can use git-flow[1] on the command line to keep that down to a minimum.
[0] http://mangrove.valanx.org [caution: WIP]
I find that because releasing is handwaved away, people find their own way which often sounds like "this is ready, I've pushed to Iteration 16" instead of "this is ready, please pull."
That post could really be fixed by deleting the "develop" branch.
Using a script set such as git-flow really helps manage this without worrying too much.
My only concern about using git-flow was that it was only really suitable on one repo; it doesn't really automate the transmission of the various branches to other repos. But then hubflow[1] sorts that one out.
Transferring that knowledge is time-intensive and expensive.
Scripts don't solve that problem because it isn't a technical problem; it's a social one.
If everyone feels responsible for being able to move stuff from develop to master, then the quality of the stuff sitting in the various develops goes up, and then you find you just don't need develop anymore.
In nvie's system, you just create a release branch from develop and then merge it back into master and develop when done. There's no other skill other than basic git-fu to do that. You can keep develop up to date with any changes from release branch periodically.
The real complication with releasing is release management. But that's nothing to do with branches or even basic use of git, but one of engineering process in general. There's definitely no magic bullet for that.
The real complication is developers that think "releasing" is somehow different than "development".
When it's in master, then it's released.
Whether you call that branch something else, or you use something other than a branch to indicate what is released, is completely irrelevant.
The fiction that "develop" is some future point for master causes huge delays at best for large projects. In reality, "develop" is the hope or belief in some magic moment when the software is "good enough", and since it's someone else's job to decide whether it's "good enough", the buck is passed.
Whatever your problems are they have nothing to do with this particular git branching model. I suspect you have an issue within the culture you are a part of and no git branching model can fix that.
I can tell you that's not the way we do it where I work. Develop is basically the staging area right before you make a release branch (for final QA before deployment).
Random feature branches do not get merged into develop by the developers, when we're going to do a release we decided which of the feature branches to pull in and add to the release. Only the few developers who actually prepare the releases merge things into develop.
Its strongly tempting to "change one little thing" outside the model. Yes yes I know "git flow hotfix" blah blah blah its only a dozen command lines or whatever. But sometimes its so tempting just to checkout master, fix one character, and push it.
The problem isn't so much dumb little typo-fixes that should have been caught in "release" testing, if not feature or develop, or keeping "real" huge changes in the git-flow, but those annoying border cases where both could be argued to be wrong or right.
One solution is to go hard core fundamentalist and demand everything go with the git-flow never outside the process, although that will "waste" some time.
Not so much, although it wastes someone's time.
Someone has to be the release manager, and git-flow gives them only one tool: To reject the release by pushing back.
If they eliminate the develop branch and merge the features directly into the release branch (whenever they attempt to perform a release) then if something goes wrong, they can simply drop one of the features and re-build their branch.
I think that sounds exciting and strongly encourage my competitors to try it. (no, seriously though, don't do it...)