禁用 Git 重命名检测
Posted
技术标签:
【中文标题】禁用 Git 重命名检测【英文标题】:Disable Git Rename Detection 【发布时间】:2011-08-26 04:13:59 【问题描述】:-
我有一个文件,
foo.txt
创建并签出分支“branch_A”
git mv foo.txt bar.txt
后跟 git add -A
然后 git commit -m "renamed foo.txt"
结账大师,git checkout master
删除 foo.txt 并提交。
现在合并分支_A,git merge branch_A
因此,我遇到了合并冲突(重命名/删除)。
CONFLICT (rename/delete): Rename foo.txt->bar.txt in branch_A and deleted in HEAD
这是有道理的,也是我所期望的。但是,我想知道 git merge 是否有办法 not 检测重命名,而是将它们视为已添加/已删除。在这种情况下,我希望 git 检测到 foo.txt 被删除并简单地添加 bar.txt。没有冲突。
我尝试过使用 -X rename-threshold,但它对我不起作用。我已经尝试过阈值 0 和 120(高于 100 的数字)。我错过了什么?
谢谢!
附:我也收到error: refusing to lose untracked file at...
错误。这是什么意思?
【问题讨论】:
error: refusing to lose untracked file at...
可能是合并bar.txt
的结果,在branch_A
中跟踪但在master
中未跟踪,假设它存在于您的工作目录中
使用 git 2.8(2016 年 3 月),您可以选择使用 git merge --no-renames
。见my answer below
使用 Git 2.18(2018 年第二季度),您可以选择 git config merge.renames false
。见my updated answer below。
【参考方案1】:
2021 年 9 月更新:
下面提到的 2016 选项现已过时,取而代之的是新的 merge strategy ORT(“表面上递归的双胞胎”),它在处理重命名检测方面做得更好。
这里值得注意的主要区别是工作树和索引的更新不是与合并算法同时完成的,而是一个单独的后处理步骤。
新的 API 被设计成可以重复合并(例如,在 rebase 或cherry-pick 期间)并且只在最后更新一次索引和工作树,而不是用每个中间结果更新它。
此外,可以在两个分支之间执行合并,这两个分支都不匹配索引或工作树,而不会破坏索引或工作树。
“ort”后端在内存中进行完整的合并,并且仅在后处理步骤中更新索引和工作副本。
从 Git 2.34(2021 年第四季度)开始,这将是默认设置。 同时:
git merge -s ort MyBranch-to-merge
^^^^^^
2016 年:
使用 git 2.8(2016 年 3 月),您将有另一个选择(作为递归合并策略的一个选项)
git merge -Srecursive -Xno-renames
见commit 44c74ec、commit 2307211、commit 63651e1(2016 年 2 月 24 日)、commit 2307211、commit 63651e1(2016 年 2 月 24 日)、commit 87892f6、commit 83837ec(2016 年 2 月 21 日)和 @987654 @、commit d2b11ec(2016 年 2 月 17 日)Felipe Gonçalves Assis (asiz
)。(由 Junio C Hamano -- gitster
-- 合并于 commit 4ce064d,2016 年 2 月 26 日)
merge-recursive
: 禁用重命名选项递归策略默认开启重命名检测。添加策略选项以禁用重命名检测,即使是精确重命名也是如此。
man git-merge
将包括:
no-renames
关闭重命名检测。 见
git diff --no-renames
。
(注意,如commit 1b47ad1 中所见,find-renames
合并策略遵循git diff
接口,使选项rename-threshold
从git 2.8 开始变得多余)
Git 2.18(2018 年第二季度)有一个附加设置:将 merge.renames
配置设置为 false,可以告诉递归合并策略不要花费周期来尝试找到重命名的路径并相应地合并它们。
参见Ben Peart (benpeart
) 的commit 6f10a09、commit 85b4603、commit a7152e9(2018 年 5 月 2 日)。(由 Junio C Hamano -- gitster
-- 合并到 commit 6e2ba77,2018 年 5 月 30 日)
merge
: 添加merge.renames
配置设置添加通过配置设置控制合并重命名检测的功能。 此设置的行为相同,默认为
diff.renames
的值,但仅适用于合并。
【讨论】:
这个在 2.9 中被删除了吗?稳定版本的 git 维护者 ppa 没有此标志 AFAICT。 @ThorSummoner 我同意。它实际上是合并策略的一个选项。我已经编辑了答案。 @VonC:我可以提供 2 个微小的编辑:在 git-merge 中添加连字符;在不重命名之前删除双连字符。应该说:“man git-merge 将包括:no-renames” @chrisinmtown 谢谢。我已经相应地编辑了答案。【参考方案2】:你可以试试:
git merge -s resolve branch_A
另外,您是否尝试过在这里查看类似的问题:
git rename/delete confusion
git divergent renaming
【讨论】:
这确实需要更多解释 基本上我已经修改了file.txt
并移动到foo
子目录,然后在历史中回溯并使用相同的file.txt
作为起点来修改它并将其移动到bar
目录。然后我尝试合并这两个分支,希望以单独的foo
和bar
版本的文件结束,并且历史可以追溯到同一源。正如@manojlds 所指出的那样使用-s resolve
效果很好,但正如利亚姆所说,它确实需要更多解释。但是非常感谢 manojlds 的回答。以上是关于禁用 Git 重命名检测的主要内容,如果未能解决你的问题,请参考以下文章
带有重命名检测的 git show 文件(相当于 git log --follow)
git 检测您的 Java 项目中的重命名/移动效果不佳 - 该怎么办?