(yes, some IDE might have git integration, but personally I don't like my IDE messing with git, except read-only (annotate, diff))
Like I implicitly said: how to do it beyond the “simple identical content cases”?
But if the solution is for the user to explicitly order renames (i.e., this renamed Java class is a file move) then the solution is indeed simple.
I see the point that Linus was making that you may want to be able to see “function moves” and so on. But in practice I am very often interested in file moves since you can inspect the file history easily in Git—except when you hit some wall because someone renamed the file. Then you need to re-run the command with `--follow`. Contrast all of that with a function move... I almost never can summon the will to fish out the incantation (like a regex or a robust line range) which will give me the history of a function across intra- or inter-file moves and so on.
Of course, all of this assumes that moving a file is a meaningful operation. Perhaps ideally (for most languages and systems) you’d track this in far smaller chunks, so that you can track changes to a function even when it alone was moved to a different file. But things like Git aren’t interested in those kinds of semantics, and work technically at the file level, more or less, so I think it should track renames because in practice straightforward renames are super common, but often also involve other changes that thwart rename detection. Years ago Linus explained why he didn’t like storing moves (someone else has linked it), but I’m largely not sold with his reasoning—the theory of the perfect has hindered the useful, and file renames are commonly meaningful in ways more than he said.