Git合并时添加新文件而不是冲突标记 - CONFLICT(重命名/添加)

3
当我在命令行上运行git merge origin master时,我没有得到通常的冲突标记<<<<<<,而是冲突的文件被复制到了我的本地环境中。这可能与文件夹名称被更改有关。例如:
git fetch origin master && git merge origin master
CONFLICT (rename/add): Rename javascript/main.js->js/main.js in HEAD. js/main.js added in %commit-hash%
Adding as js/main.js~%commit-hash% instead

我本地有两个文件:js/main.jsjs/main.js~%commit-hash%

如何让git给我冲突标记而不是一个新文件?

& 有人能解释一下为什么会发生这种情况吗?

  • 注意: %commit-hash% 只是一个示例占位符,实际上是提交哈希码。
1个回答

4

TL;DR

尝试使用-X find-renames=<value>以获得不同的重命名检测。或者,如果这种方法行不通或您不喜欢该方法,则必要时从索引中提取所有多个阶段存储的文件,然后使用git merge-file手动创建冲突。

长篇大论

这是一个高级别的冲突:由于多个不同文件更改名称而发生的冲突,而不是在单个文件内发生的冲突。

Git已经告诉你问题所在:

HEAD中重命名javascript/main.js -> js/main.js...

因此,在比较当前或HEAD提交与您和他们都开始的公共合并基础时,Git发现javascript/main.js重命名为js/main.js

hash中添加了js/main.js

他们(无论是谁)将文件javascript/main.js保留在javascript/main.js中,但然后创建了一个新的文件,名为js/main.js

由于只能有一个名为js/main.js的文件,因此Git必须进行一些特殊处理。它无法将重命名自javascript/main.jsjs/main.js放入js/main.js中,并将他们新创建但不同的js/main.js放入js/main.js中。因此,它已将其js/main.js放入js/main.js~hash中。

如何使git给我冲突标记而不是新文件?

也许您可以轻松地做到这一点,也可能不行。

首先,您必须决定Git对情况的分析是否正确。是否将javascript/main.js重命名为js/main.js?他们做了什么:他们是否保留了原始的javascript/main.js并添加了一个新的不同的js/main.js,还是他们实际上重命名了他们的javascript/main.js,只是Git没有意识到这一点,并认为他们创建了一个与原始的javascript/main.js无关的全新的js/main.js

如果问题是Git错误地检测到了这两个重命名,您可以尝试调整“-X find-renames = ”设置(在早期版本的Git中称为“-X rename-threshold = ”)。将数字降低会使Git更愿意将显然不同的文件视为“相同”的文件。将数字提高会使Git不太愿意将这些文件视为“相同”,甚至到了百分之百匹配的程度。
如果所有这些都是正确的,并且此过程顺利进行,您可能会得到想要的结果,并且不需要进一步的棘手部分。如果不是,则:
手动操作
如果Git是正确的,并且您的`js/main.js`确实被重命名,而他们的`js/main.js`确实是新的,那么合并文件可能是不明智的。但是,您可以使用`git merge-file`来完成此操作,它可以与工作树中的普通文件一起使用。首先,您需要将三个文件全部置于工作树中:
基础合并版本,最初在合并基础提交中命名为`javascript/main.js`(无论其哈希ID是什么)。
--ours或HEAD版本,在当前提交中命名为`js/main.js`。
–theirs版本,在其提交中也被命名为`js/main.js`。
这三个版本中的其中两个已经可用于您的工作树,使用Git宣布的两个名称。
您的索引中也应该有每个文件的副本:合并基础是一个stage-1条目,--ours或HEAD版本是一个stage-2条目,--theirs版本是一个stage-3条目。这意味着您可以使用`git show`或`git checkout-index`来访问每个版本。(实际上,您可能可以使用`git checkout-index --stage=all`来将所有这些临时文件全部获取,但我没有尝试过这个功能。)既然您仍需要基础版本,因此您可以使用:
git show :1:js/main.js > main.js.base

例如(假设您正在使用类Unix的shell)。
一旦您在工作树中拥有这三个文件,您就可以运行:
```bash git add file1.txt file2.txt file3.txt ```
这将把文件添加到Git暂存区。
git merge-file <head-version> <base-version> <their-version>

<head-version> 中生成一个带有冲突标记的文件版本。假设您到目前为止显示的文件名,并将第一阶段文件编写到 js/main.js.base 中,操作如下:
git merge-file js/main.js js/main.js.base js/main.js.~<hash>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接