Handling file renames in Git

For git mv the manual page says

The index is updated after successful completion, […]

So, at first, you have to update the index on your own (by using git add mobile.css). However git status will still show two different files:

$ git status
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       new file:   mobile.css
#
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       deleted:    iphone.css
#

You can get a different output by running git commit --dry-run -a, which results in what you expect:

Tanascius@H181 /d/temp/blo (master)
$ git commit --dry-run -a
# On branch master
warning: LF will be replaced by CRLF in index.html
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   index.html
#       renamed:    iphone.css -> mobile.css
#

I can’t tell you exactly why we see these differences between git status and git commit --dry-run -a, but here is a hint from Linus:

git really doesn’t even care about the whole “rename detection” internally, and any commits you have done with renames are totally independent of the heuristics we then use to show the renames.

A dry-run uses the real renaming mechanisms, while a git status probably doesn’t.

Leave a Comment