I've seen companies that have no form of source control, companies using backups as source control, people still using Source Safe along with a whole bunch of actual good source control solutions such as Git and SVN. But when I say what's your source control strategy I don't mean what tool are you using, I mean how are you using it.
Checking you're code into source control adds many benefits such as merging, versioning, reverting etc, but to get the most out of it you really need a strategy to define how you will use it. There is no one right way and the strategy you use ultimately depends on your team size and what you are doing.
Here are a few example strategies:
The didn't know about a strategy approach
You've got a source control solution, you're regularly checking your code in but you've never made a branch.
This is actually quite common. Everyone is developing against the same branch, you've got all the benefits of seeing who changed which piece of code, you can revert when you need to revert and when you do an update there's some help with merging.
What you don't get though is the ability to have work happening in parallel and one being released before the other. If you needed to do a release either you have to have a way of hiding the unfinished updates as the code is pushed to live or some way of reverting just those bits.
A branch for every feature
The other extreme is to have all development work happen on a new branch. When it's ready to be release the code is merged back into the trunk and then released (plus some testing along the way).
The advantages of this are your trunk is always the same as what's on live meaning emergency fix's can be made without trying to find the last release in the source control history. Developers can also work separately without stepping each other toes and can release.
However with more than one development happening at the same time, whoever merges second could have a big job on their hands. All that branching is also going to be time consuming.
Updating branches often
So you're using branches and to avoid a tricky merge are keeping the branch up to date regularly, possibly daily. Anyone who's tried to merge a feature branch after 3 months of development can testify that it doesn't always go smoothly and can take some time.
Only updating the branch at the end
You've decided to accept the large merge at the end of the project. You don't like it but figure all those small merges during the project actually add up to more time than one big one at the end. You can then also concentrated on getting the feature built without the regular merge distraction.
A tag for each release
If you've ever needed to find a previous release and only have the history to go on it can be hard. If there's no comment that says release to live you are basically guessing based on release date and last commit.
A tag is basically the same as a branch and if its part of your release plan, you've got a good way of finding each release to live.
A branch for live, a branch for dev
In this setup you have a live branch that always match's what's on the live site. There's less need for tags as commits to this branch are normally also a release to live, and because the branch is always in sync with live, emergency fix's are taken care of.
The downside with this approach is everyone is working on the dev branch, so exceptions should be made and feature branches used when it makes sense.
So there are some of the strategies I've come across, but there will be plenty more. What you do ultimately relates to what kind of work you do, how frequently you release and what kind of team size you have. But the one thing you must do with all of them is make comments on each commit. If you don't then source control becomes virtually useless.