in theory, at least how I practice it, it's like this:
I assume a stable and a development branch
stable is on production and deployable as mentioned by sandeep and marco
stable gets never merged up everything ends in it (merge down) but it never goes ups (cross merge)
development is where you merge or rebase your features in or onto. in general git pull --rebase is a good idea if you like me tend to do minor hotfixes and so on directly on development. Before merging them down to master.
I would even lock master from pushing and only allow merges. This can be tedious overhead but at least in theory things don't get f*cked up that easy.
There is the case of interdependent features with mid term lifetime which tend to have a parallel live to the development branch. we could call them "story branches" or whatever method you use. This is where it gets tricky if you got a QA team. So here's where communication really starts to be key.
What I've learnt is .... a good strategy does not replace communication and ... if your team consists of more than 5 people, who have a good and clear communications strategy about what's going on in the source code ..... block force push Gg
If you got a clear structure you can actually lock a certain branch and do a "let clean up the history" with a git rebase -i but this should be the last step after a messy development because you probably will end up doing a force push after that.
The only thing that's important is try to avoid up merges if possible. as everything you and your team has to decide how they work ... there is no silver bullet and if you can try to get everyone to the same level on git.
Besides that... to me communication beats strategy .... I would recommend that you define certain default merge strategies and maybe take a look at https://www.youtube.com/watch?v=dBSHLb1B8sw where explains some of the behaviours.
I hope this makes sense :D ....