Depending on whether you're working on existing software or startups - if it's a startup where there's no software, we often work directly on master until we have something stable.
Once you have software that's deployable, for each new feature / bug fix, create a feature branch. Once your feature got enough upvotes (we use Gitlab which has a +1 / -1 feature), deploy that branch, test it, then merge into master. If you're doing a lot of small fixes / features, the amount of effort to make a branch for each is sometimes too much, so we would sometimes just do a large batch of small features in a branch instead of a branch for each.
Once you do a release, tag master with the date and time so that if something is catastrophically broken which slipped through the tests, you can switch to a previous tag.
Recommended tools, Gitlab. We're currently investigating the benefits of Upsource + Hub + YouTrack + TeamCity, it looks promising and can enforce certain workflows which is somewhat more tricky to setup with Gitlab and Jenkins.