git无法检测到重命名


git fails to detect renaming

一个分支(refactoringBranch)进行了完整的目录重组。文件被乱动,但内容被保留了下来。

我试图合并:江户十一〔一〕号

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

一个例子是:

1
2
3
4
5
6
7
8
9
10
# 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之外进行的。我做了以下工作:

  • 创建了源自masterrefactoringBranch
  • refactoringBranch中删除了修改后的结构,这意味着我在其他目录中进行了修改,只需复制粘贴到我的Git存储库中。
  • 添加并提交所有内容,然后尝试合并。
  • 这是我的工作流程:

    1
    2
    3
    4
    5
    6
    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步骤上。因为如果重命名检测在这里是正确的,我会假设合并会毫无瑕疵。


    OS X支持大小写,但不敏感。Git?是?区分大小写。如果您更改了文件名,而唯一的更改是大小写更改,请将文件重命名为原来的格式,然后使用git mv重命名。


    重命名检测:

    我的最佳猜测是,由于候选对象数量非常多,重命名检测失败。Git源代码在某些地方有点难以遵循,但似乎在重命名检测算法的特定搜索步骤中使用了一些硬编码限制(参见diffcore-rename.c)以及要查看的最大对数的可配置限制(配置键diff.renameLimitmerge.renameLimit。这可能会使检测失败,即使您已将配置的限制设置为适当的高。可配置限制本身被限制在范围[132767]。

    也许您可以通过执行重组步骤来解决这个问题:先使用git mv移动文件,而不进行任何内容更改,以匹配新布局,在新分支上提交该布局,然后将其替换为最终版本,该版本只应进行内容更改,不应重命名。可以更可靠地检测到没有内容更改的重命名。只有当您所做的重组相当简单时,这才是可行的,而且我不确定它是否能解决重命名检测失败的问题。

    或者,您可以使用一些简单的文件分组将更改拆分为单独的提交,这样在每个提交中可以检测重命名的候选项就更少了。

    合并:

    不幸的是,通过将新的分支建立在master之上,您向git提供了有关合并的错误信息。不管是否正确检测到重命名,当新创建的分支与master合并时,它将覆盖master中的所有内容,因为从git的角度来看,master中没有未包含在新分支中的更改。


    git commit --dry-run -a代替git status,它能更好地检测重命名。


    您可以考虑使用git mv代替:https://www.kernel.org/pub/software/scm/git/docs/git-mv.html

    以我的经验来看,它更可靠。


    每当我不得不重命名/移动文件而忘记明确地告诉Git我使用的

    1
    git add . -A

    自动检测移动的文件