I also encourage forking over branching. Because branches are so cheap to create in Git branches over forking needs to be done with some care. Having worked on large projects using both models I have seen the following problems when dealing with branches:
1) Namespacing
There are several different type of branches: Project branches (master, release X, etc), major features worked on by several people, small features, short term bug fixes, experimental, r+d, etc. Depending on how you draw the line you end up with branches every one works on and branches users work on. Git shows all branches by default alphabetically which means that if everyone's branches are in the same spot can be difficult at a glance to see what project branches there are. The only sane method is to have namespacing rules and it must be enforced by a server side hook (because otherwise someone will ignore it and in the best case use bmeyer_ and in the worst case start pushing up branch names like tmp tmp2 tmp3). The most common one I have seen is username/ so all my branches would go under bmeyer/. Usually non-user branches are not pre-fixes so when running git branch -r you see a sprinkling of user branches all mixed around project branches. It is not perfect as often you have release/1.0.0 so you can't just grep -v, but better than chaos.
2) Clutter and death
With branching being so cheap not only can you have hundreds of branches some users will, most will have many and a chunk can easily have dozens. A user might make a branch for every ticket he works on, but decides to never deletes them. Even with just a handful of users you can end up having a large number of remote branches which makes scanning visually for actual product branches annoying. And then there comes that day that a user leaves the company. We can call it the hit by the bus situation, but it really should be called gets on the bus situation. Suddenly you have dozens of branches that everyone will see forever that can't really be deleted without annoying work. I have experienced this a number of times even on small projects.
3) Control
With branches the project must up front dictate how the branch's will be named when they are allowed to be made, when they must be deleted, etc for all types be it release, dev, feature, hotfix, personal, exploratory, etc But with forks users have their own playpen and can do whatever they want and it doesn't hurt anyone else. Users in their own playpen where they are admin can enable hooks, allow force pushing, setup say jenkins jobs or other things that they can not do on the main shared repository by default.
4) Building changes
Back in the day the only problem I had was that managing lots of remotes for different users was a pain. Being able to cheaply access pull requests was the missing piece for me. Now just by adding the following to their repo config
[remote "pull-requests"]
url = https://bmeyer@git.server.com/scm/project/repo.git
fetch = +refs/pull-requests/:refs/remotes/pull-requests/
than they can access all pull requests that are up for review and easily try the changes locally.
Its not that you can't make feature branches work, it is just that much harder and I have never actually seen it work with a revision control system where branches are cheap like they are with git which is why I currently advocate for the fork model as the default method for development.
Pain in the ass, how do I see my own fork in Bitbucket .com ???!!!! Repo detail on right.