【问题标题】:git added by them renaming conflict - git recognises the same files in the renamed directory as new files他们添加的 git 重命名冲突 - git 将重命名目录中的相同文件识别为新文件
【发布时间】:2017-06-08 06:16:44
【问题描述】:

我重命名了一个目录并将其合并到我的主分支中,当合并另一个分支时,git 将重命名目录中的相同文件识别为新文件。

在合并到另一个分支时,该目录中的相同文件出现“由他们添加”的合并冲突:

added by them: theirDir/same_file_name.xxx

我已重命名他们分支中的目录以匹配并继续获得“由他们添加”冲突。

当我尝试结帐时 --ours 我得到了

$ git checkout dir/same_file_name.xxx --ours

error: path 'dir/same_file_name.xxx' does not have our version

此时实际删除该文件,合并完成后删除该文件。

我该如何解决这个冲突?

--- m ----\ ------------  m1 --------------- mx ------- *!*
     \     \            /   \                /         /  
      \     dir-rename-/     file_revisions-/         /
       \                                             /
        f2 ---------- file added by them conflict --/

在合并冲突之前发生了来自多个分支的多个文件修订。

【问题讨论】:

  • 除了重命名目录之外,目录中的文件是否有变化?
  • 不,正在合并的分支中的文件尚未更改。自从目录被重命名后,其中一些文件可能已经发生了变化。
  • 我对哪个文件在什么时候在哪里有点困惑......你的意思是你退出合并,重命名目录并将其提交到他们的分支,然后再次尝试合并?
  • 根据您的描述我无法重现:一个带有 master + 两个分支的 repo;重命名分支 1 上的目录,对 'dir' 中的文件进行一些更改,然后合并到 master;在分支 2 上,对不在 'dir' 中的文件进行更改,然后合并到 master。
  • 每个差异都从两个提示提交的合并基础开始。要查找合并基,请使用git merge-base --all <tip1> <tip2>,例如git merge-base --all master branch。如果这会打印多个合并基础提交,则下一步取决于您选择的合并策略,但通常您只会得到一个提交 ID。然后您可以git diff -M <base> <tip1> 并重复<tip2> 以查看 Git 会看到什么。请注意,您可以在git diffgit merge 中调整-M 重命名检测阈值。

标签: git merge rename git-merge renaming


【解决方案1】:

不要使用msysgit 1.9.5,试试latest Git for Windows

Since Git 2.18, git status 在检测重命名(文件和文件夹)方面做得更好


借助 Git 2.33(2021 年第三季度),它将更进一步,管理基于内容的重命名检测目录重命名检测。

但仅适用于新的合并策略ORT ("Ostensibly Recursive's Twin")

参见Elijah Newren (newren)commit 3585d0ecommit a492d53commit 806f832(2021 年 6 月 30 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit d3b88be,2021 年 7 月 16 日)

merge-recursive: 处理 rename-to-self 案例

报告人:Anders Kaseorg
签字人:Elijah Newren

目录重命名检测可能导致传递重命名,例如如果历史的两个不同方面各做一半:

A/file -> B/file
B/     -> C/

然后目录重命名检测传递重命名给我们

A/file -> C/file

但是,当 C/ == A/ 时,请注意这给了我们

A/file -> A/file.

合并递归假设任何重命名 D -> E 都会有 D != E
虽然这几乎总是正确的,但上述情况并非如此。
所以我们不能做诸如删除重命名源之类的事情,我们不能假设路径 E 中存在的文件意味着重命名/添加冲突,我们必须小心输出中的最终阶段。

这种变化感觉有点骇人听闻。
我花了很多时间才找到,并且考虑到合并递归的设计导致它尝试用每个组合的特殊代码枚举边缘和角落案例的所有组合,我担心如果我们可以的话,其他地方还需要其他类似的修复想出正确的特殊测试用例。
也许审计会排除它,但我没有精力。
merge-recursive 应该死,而且由于它无论如何都在退出,因此修复这个特定的错误必须足够好。


Git 2.35(2022 年第一季度)纠正了 ort 合并策略中的一个极端情况错误。

参见Elijah Newren (newren)commit d30126c(2021 年 12 月 28 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 2c54104,2022 年 1 月 10 日)

merge-ort:通过重整化和重命名/删除冲突修复错误

报告人:Ralf Thielow
签字人:Elijah Newren
审核人:Derrick Stolee

自从commit a492d53 (merge-ort: 确保我们查阅 df_conflict 和 path_conflicts, 2021-06-30, Git v2.33.0-rc0 -- mergebatch #5 中列出) ("merge-ort: 确保我们咨询df_conflictpath_conflicts", 2021-06-30),当重新规范化处于活动状态并且文件涉及重命名/删除冲突但文件未修改(重新规范化之前或之后)时,merge-ort 正在运行断言失败。

在那次提交之前(或者如果断言被编译出来),merge-ort 会错误合并,忽略重命名/删除冲突,只删除文件。

去掉断言,适当地修复代码,在代码中留下一些好的cmets,并为这种情况添加一个测试用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-10
    • 2011-04-24
    • 2012-10-29
    • 1970-01-01
    • 2011-12-07
    • 2016-04-15
    • 2015-08-15
    相关资源
    最近更新 更多