Is there some way to explicitly say to git "hey, I renamed index.js to index.ts"?
No.
That's all there is to it. Git does not store changes to files. Git stores snapshots of files. You had, in snapshot X, a file named index.js
. You have, in snapshot Y, a file named index.ts
.
When comparing snapshot X to snapshot Y, you can ask Git to detect renames. The detection is based on two facts:
In snapshot X, there was a file named index.js
and in snapshot Y, that file does not exist, but a new file named index.ts
does exist; so these two names can be put into a list of candidates for rename detection.
Now that the list of candidates for rename detection is filled with all file names that vanished from the left (X) commit and appeared in the right (Y) commit, Git will compare each pair of files. If the content of those two files is sufficiently similar, Git will temporarily pair-up that pair, remembering this similarity index value. Having run through all possible pairings, Git will take the pairing that has the best similarity index, and call that file "renamed".
Whenever you have Git compare snapshots X and Y—for any commit hashes X and Y, really—you get to tell Git:
- Do, or do not, use the rename detector;
- If using the rename detector, what's the minimum similarity threshold to temporarily pair-up files?
With the git diff
command, the rename detector defaults to off before Git 2.9 and on in Git 2.9 and later. The similarity threshold value defaults to "50% similar" in all versions of Git. Use the -M
flag to turn the detector on and set the similarity threshold.
When using other Git commands, other flags and arguments may allow you to enable rename detection and set the threshold—or, in some cases, not so much. For instance, git log --follow
turns on the rename detector but limits it to one file name only and does not let you set the threshold.
The git status
command used to always enable rename detection and set the threshold to 50%. It now obeys git config
settings for enabling or disabling rename detection, but still has no way to set the threshold.
Again, this rename detection occurs when you compare the two commits. The commits themselves are just snapshots, of all of your files. Two different git diff
commands, with different rename detection setups, will show different sets of operations that result in replacing the first commit with the second one. The git diff
command does not show what someone actually did. It shows, instead, some sequence of operations that will produce the same result.