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.js
的js/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>