Someone changed a file name and its content in a way that git was unable to detect that it was the same file.
They also didn't use git mv
, so when I got the pull request I saw a new file being added and an old file being deleted, which makes it impracticable for reviewing.
Being a nice guy I pulled their code and tried to do a late git mv
, so I'd be able to add a commit to their pull request and see things beautifully on Github review page, but that didn't work.
Is there a way to do a posthumous rename of a file?
Git doesn't track file identity: there's nothing in the repository that says that file bar
in revision n was renamed/copied/moved from file foo
in revision (n-1). Doing git mv
is the same as doing plain mv
followed by git add
on the new name and git rm
on the old. The repository just stores a snapshot of the directory tree at each commit, and it's up to the tools examining the repository to make decisions about how the files in different commits relate to each other.
When you're looking at the revision history and git says a file was moved or renamed, it's determining that locally, as a guess based on the similarity of the old and new files' contents. Many git commands support a -M
option that lets you specify the similarity threshold for deciding that a delete and an add in the same commit should be regarded as a rename. The default threshold is 50%.
If you want git to treat the change as a rename by default, without having to specify a lower -M
threshold every time you examine the repository, you can split the change into two commits: one to change the contents while keeping the name, and one to rename the file while keeping the contents unchanged (or at least, less than 50% changed).
Doing this "posthumously" will, of course, require resetting the branch head to before the old commit, replacing it with the two new commits, force-pushing, and contacting anyone who might have pulled the original version to let them know you've changed history. (This is no different from making any other kind of change to a commit that's been published to others.)