Git 检测不到重命名

一个分支(refactoringBranch)有一个完整的目录重构。文件被混乱地移动,但内容被保留。

我试过合并: Git merge —— no-ff-Xrename- 阈值 = 15-XPaties- 忽略-空間改變重整分支

Git 状态显示大约一半的文件重命名识别。但是在项目中的10000个文件中,有一半没有被识别为已移动。

一个例子是:

# 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

有什么建议吗?


史前时期

重构是在 git 之外进行的,我做了以下工作:

  1. master上创建了 refactoringBranch
  2. refactoringBranch中删除了已更改的结构,这意味着我在其他目录中做了更改,只是将它们复制粘贴到我的 git 存储库中。
  3. 添加并提交所有内容,然后尝试合并。

这就是我的工作流程:

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

问题可能出现在 git add . -A步骤上。 因为如果重命名检测是正确的,我会假设合并会完美无缺。

52301 次浏览

Whenever I had to rename/move files and forgot to tell GIT explicitly about it I used

git add . -A

which auto-detects files that were moved around

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.

Instead of git status, try git commit --dry-run -a, it detects renames better.

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.

You could consider using git mv instead: https://www.kernel.org/pub/software/scm/git/docs/git-mv.html

It has been much more reliable in my experience.

Here is a perfect way to allow git know you rename a file.

git mv old-file-name.ts new-file-name.ts

Then git will pick up those changes.

Enjoy.

I just faced a similar issue, in my case the renaming was changed by another commit and an attempt to re-change it to another one failed on my Git for Windows, until I realised that there's a corresponding git config for it. In my system, git config listed one configuration as core.ignorecase=true.

Disabling it by setting it back to false using git config core.ignorecase false worked out for me. It's worth a quick check and try to see if this is causing the case detection failure in git. This has been tried on git version 2.33.0.windows.2.