Git does not track renames. Period. It also does not track uploads. Or deletes. Or different. Or patches. Or moves. Or some changes, really.
Git is based on a snapshot. Each commit records a snapshot of the entire project. It. How this snapshot became, Git does not know and does not care.
Differences, patches, add, delete, move, rename, etc. shown by various visualization tools that display them after the fact using heuristics (which is another way of saying “guessing”). Sometimes they can correctly guess what you did, and sometimes not. This does not matter, because since it is only a visualization, it is not part of the story in any way, form or form.
Most tools use some form of similarity metric and conclude that the renaming happened if two files have similarities that exceed a certain threshold. In some instruments, this threshold is configurable. In some tools, even the algorithm is customizable. (A slightly related example: git diff allows you to choose between different algorithms to display differences in files.)
Because Git does not record changes, you can add new changes to later versions of the visualization tools, which can push these changes out of older commits that were written before new tools that understand the new kinds of changes were even written. Imagine, for example, a tool that understands the syntax and semantics of your programming language. He could visualize a certain commit not as a whole bunch of files, each of which had a couple of lines, but as one change, which renames the subroutine and updates each callsite (i.e., renaming refactoring).
Renaming is actually a good example of this. For example, the rename detection heuristics and affinity indicators used by git log --follow have been improved several times. IIRC, at the beginning the renaming was not derived at all, this feature was added later. This would simply not be possible if Git recorded the changes instead of snapshots.
Jörg W Mittag
source share