In a nutshell:
1. All developers push to the remote master
2. Acceptance testing is done against the master
3. Once accepted, the release is tagged
4. The release is exported to production
with `git archive` or `git checkout-index -a`
For larger teams you might need fine-grained control, but it works great for our small team.