Git Workflow with User Acceptance and Staging Environments
My favourite workflow is the development-less "branch per feature" workflow from Adam Dymitruk (http://dymitruk.com/blog/2012/02/05/branch-per-feature/). It has these branches:


Exactly one master in an unbroken line from day 0 up to the version of your app that is currently in production.
Many feature-... branches.
One (or if you are so inclined more) qa branch.


The gory details can be found on Adam's site, but in short:


Every branch goes off of master.
All branches that are in active testing are merged into qa.
qa only ever contains merge commits (i.e. feature branches merged on top of each other, starting from master), never direct manipulations.
Whenever a feature branch gets new commits, and you want those in qa, you rebuild qa from scratch.
Whenever you want to deploy a bunch of features, you create a qa from all of them, test to your heart's content, and then simply rename that branch to the new master (which, as it started out from the old master, will be a direct, unbroken line of merge commits from day 0). Then, all feature branches are rebased on that.
One fundamentally important part for this workflow is to enable the git rerere cache feature, and distribute that cache between all developers. Hence, every merge conflict needs to be resolved only once, globally.


It's trivial to have more than one qa branch at a time to test different subsets of features; in your case, you could have qa (with everything nearly close to finished, i.e., compiles without error), qa-acceptance, qa-staging or whatever you like.

In my experience, there is always a relatively large main, ongoing qa branch (recreated from the master and features regularly), and when some features are picked for release, the will be a temporary smaller qa-.... 

It is trivial to add and remove individual features from the set of qa or release-candidate branches on the fly, as those are recreated constantly and only ephemeral.

You will find a lot of people very much objecting to git rebase, but if one wraps their mind around the fact that this is just a tool like any other, it will be fine. You need good tooling for this of course, but this is not complicated to program yourself; the actual git commands are all pretty simple and self-explanatory.

We have extended the workflow (or rather our tooling) to even allow arbitrary sub-features (i.e., feature branches going off of another feature branch, not master), so multiple branches can go off of a common ancestor which is not yet in production; works like a charm. But you can get pretty far without this.