It's a bit of a case of the tail wagging the dog when you find yourself coding in a certain style to please a version control tool.
All content in git is exclusively addressed by its hash - there's no UUID for files or directories like bzr has. The only concept of history is in the parent-references in the commit objects. So tracking bits of code from commit to commit, between file moves etc, happens purely heuristically, without any support in the storage format.
Given that it works like that, I'm impressed every day that that works at all, and also how fast it is. You can make git-blame work extra hard at finding the renames/moves with extra switches (see http://jfire.io/blog/2012/03/07/code-archaeology-with-git/ - I almost automatically add "-wCCC" now), and it's still surprisingly snappy.
But as noted in the comments to the OP, merging when one branch renamed a tree and the other added files under the old tree name, probably still needs bzr's rename-support.
Downside: It doesn't know what a rename is in your history and detects it at the point of use (that is, when you 'use' your history - e.g. when doing git log).
Upside: You can adjust what it thinks a rename is when you need to without changing anything, and if it gets better at detecting renames, you can benefit from that without having to rewrite history.
Depends on your language, I guess. Changing a Java class name typically involves renaming a file. So if you're doing a refactor, where renaming a class may only be one of several changes you're making 'in the flow', you have to consciously pause after renaming that class and commit.
The best thing we have now is to centralise large binaries and to use specialised binary-diffing tools for handling their changes. As discussed in Lobsters[1], that's more or less how Facebook has handled this particular problem[2].
[1] https://lobste.rs/s/tekiod/unorthodocs_abandon_your_dvcs_and...
[2] http://mercurial.selenic.com/wiki/ScaleMercurial#Concern:_La...