Renaming Files
I recently had to rename a lot of files in brf-mode for submission into MELPA. These files have 10+ years of version control history I wanted to keep. In the process I realised retaining all that history in Git isn't as simple as I thought 😀I thought it was as simple as using git mv rather than filesystem mv and Git would know everything had been renamed. It turns out I was wrong and I should have known that from my knowledge of how Git works 😖
In reality, Git works by storing snapshots rather than file or directory metadata and git mv is just a convenience shortcut for typing:
$ mv <old name> <new name>
$ git rm <old name>
$ git add <new name>
That's all there is to it!
Now the "magic" happens when you git log or git blame a file and Git works out the file was renamed by diffing the contents. If files have the same contents (within a certain threshold %) it thinks a rename happened. See here in the Git SCM Book for the gory details.
A consequence of this is if you rename files and then make a whole load of changes to the contents of those files, Git will not recognise this as a rename.
Therefore it is important to make the rename in one commit and any changes to the contents in another commit.
Of course Git being Git, there is a further wrinkle. While git blame will follow renames and give you a consistent annotation by default, git log does not. git log will only show history to the last rename unless you supply the --follow argument. You really couldn't make this stuff up...
You can work around this by setting log.follow in .gitconfig.
However when I'm doing command line Git I like to have full control of what I'm doing, so instead of doing that I just tell Emacs VC to follow by default:
(setq vc-git-print-log-follow t)
Comments
Post a Comment