A very popular workflow for use with git is described in http://nvie.com/posts/a-successful-git-branching-model/
Basically, what you are most successful doing is to have a development environment that is on a long-running branch, which can be the trunk if you wish or can be a separate branch, in this document one named 'develop'.
Issue branches and development branches would be branched off from this, developed and tested, and then merged back when the author believes they are stable. Then if whatever testing you require in development to qualify it to go to the next test level passes, you tag and build that and deploy it into the test environment.
When you are getting close to a release, you would branch from the running development branch for a release branch, which then is only touched to improve its stability for release. This makes it a dead-end branch, but a great place to apply hot-fixes later.
And if you are in one of those places that wants the trunk to be the most recent version deployed to production, then whenever something has passed all testing and is deployed to production, you merge it onto the trunk. This is option; in my opinion it is unnecessary overhead and complexity, but it is a Management Demand you run into quite often.