Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git fails to detect renaming

Tags:

git

One branch (refactoringBranch) had a complete directory restructure. Files were moved chaosly, but the content was preserved.

I tried to merge: git merge --no-ff -Xrename-threshold=15 -Xpatience -Xignore-space-change refactoringBranch

git status shows about half of files renaming recognition. But out of 10000 files in the project half wasn't recognized as moved.

One example would be:

# On branch master # Changes to be committed:  #   deleted:    404.php #   new file:   public_html/404.php     ... #   deleted:    AnotherFile.php #   new file:   public_html/AnotherFile.php     ... #   renamed:    contracts/css/view.css -> public_html/contracts/css/view.css 

Suggestions?


Prehistory

The refactoring was made outside of git. I did the following:

  1. Created the refactoringBranch originating on master.
  2. Dropped the changed structure inside the refactoringBranch, meaning I had my changes in some other dir and just copy-pasted them over my git repository.
  3. Added and committed everything and then tried to merge.

This is was my workflow:

git checkout -b refactoringBranch cp -R other/place/* ./ git add . -A git commit -a -m "blabla" git checkout master git merge --no-ff -Xrename-threshold=15 -Xpatience -Xignore-space-change refactoringBranch 

The problem arise on the git add . -A step probably. Because if rename detection was correct there, I'd assume the merge would go flawless.

like image 470
Alex Avatar asked Dec 10 '12 17:12

Alex


People also ask

How does Git detect renamed files?

Git keeps track of changes to files in the working directory of a repository by their name. When you move or rename a file, Git doesn't see that a file was moved; it sees that there's a file with a new filename, and the file with the old filename was deleted (even if the contents remain the same).

How does git rename work?

We use the git mv command in git to rename and move files. We only use the command for convenience. It does not rename or move the actual file, but rather deletes the existing file and creates a new file with a new name or in another folder.

Can I rename a branch in Git?

The git branch command lets you rename a branch. To rename a branch, run git branch -m <old> <new>. “old” is the name of the branch you want to rename and “new” is the new name for the branch.


2 Answers

OS X is case-aware, but not sensitive. Git ​is​ case-sensitive. If you changed a file name and the only change was a case change, rename the file back to the way it was, then use git mv to rename instead.

like image 154
andrhamm Avatar answered Oct 16 '22 11:10

andrhamm


Rename detection:

My best guess is that rename detection is failing due to the very large number of candidates. The git source code is a little hard to follow in places, but it does appear that there are some hard-coded limits used in particular search steps of the rename detection algorithm (see diffcore-rename.c), as well as the configurable limit on the maximum number of pairs to look at (configuration keys diff.renameLimit and merge.renameLimit). This may be making detection fail even if you have set the configured limit suitably high. The configurable limit itself is clamped to the range [1, 32767].

Perhaps you can get around this by performing a restructuring step first: move files with git mv without making any content changes, to match the new layout, commit that on a new branch, and then replace it with your final version, which should have only content changes and no renames. Renames with no content changes might be detected more reliably. That's only practical if the restructuring you've done has been fairly simple, and I'm not certain that it will solve the rename detection failures.

Alternatively, perhaps you can split the changes up into separate commits with some simple file groupings, so that there are fewer candidates for rename detection in each commit.

Merging:

Unfortunately, by basing the new branch on top of master, you are giving git incorrect information about the merge. Independent of whether renames are correctly detected or not, when the newly created branch is merged with master it will overwrite everything in master, because from git's point of view, there are no changes in master that haven't already been included in the new branch.

like image 45
John Bartholomew Avatar answered Oct 16 '22 10:10

John Bartholomew