$ git init Project
$ cd Project
$ echo "function getRandomNumber () { return 3; }" > FirstName.JS
$ git add .
$ git commit -m v1
As a next step, I will rename the FirstName.JS while its contents survive intact:
$ mv FirstName.JS SecondName.JS
$ git add .
$ git commit -m v2
For the following commit I'm going to rename the file and tweak its contents:
$ mv SecondName.JS ThirdName.JS
$ echo "function getRandomNumberWithASeed (seed) { return seed * 3; }" >> ThirdName.JS
$ git add .
$ git commit -m v3
If we put in the show using the v2 commit as an argument, the command will indicate that the same file was renamed. However for the v3 commit output would different: SecondName.JS was deleted and ThirdName.JS was created. It's inconsistency I'm willing to avoid.
Why does Git think of the
v2andv3commits in different way? I suppose the matter with it Git finds the blob object which is the same as one needed for theSecondName.JS(v2) (this blob object was created for thev1commit). The opposite situation arises with thev2andv3commits (contents of their blob objects are distinguishable).How is Git able to show information about file renaming (for example, we can see it through the
showcommand)? In fact, tree objects only store file names and links to blob objects. Based on this, it's impossible to claim whether the one file was renamed or one file was deleted and a new appeared. Does Git store some meta-data for this purpose or are there its heuristics?