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

时间:2018-06-01 19:23:18

标签: git git-merge-conflict

在命令行上运行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

然后我在我的本地有2个文件:js/main.js&amp; js/main.js~%commit-hash%

如何让git为我提供冲突标记而不是新文件?

&安培;谁能解释为什么会发生这种情况?

  • 注意:为了示例,%commit-hash%只是实际提交哈希的占位符。

1 个答案:

答案 0 :(得分:3)

TL; DR

尝试使用-X find-renames=<value>进行不同的重命名检测。或者,如果这不起作用或者您不喜欢该方法,请在必要时从索引中存储的多个阶段中提取所有文件,然后使用git merge-file创建冲突&# 34;手工&#34;。

这是高级别冲突:由于多个不同文件而发生的冲突,而不是单个文件中发生的冲突

Git告诉你究竟是什么问题:

  

javascript/main.js->js/main.js ...

中重命名HEAD

因此,当将当前或HEAD提交与您和他们开始的公共合并基础进行比较时,Git发现花了javascript/main.js并重命名了该文件到js/main.js

  在 js/main.js

中添加了

... hash

无论他们是谁,他们都会在javascript/main.js中留下javascript/main.js个文件,但随后会创建一个名为js/main.js文件。

因为只有一个文件名为js/main.js,所以Git必须做一些特别的事情。它无法将您的 js/main.js(您从javascript/main.js重命名)转换为js/main.js 放入其中新创建但js/main.jsjs/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 {1}}并且Git没有意识到这一点,并认为他们创建了一个与原始js/main.js无关的全新javascript/main.js

如果问题是Git错误地检测到了两个重命名,您可以尝试调整-X find-renames=<value>设置(在旧版本的Git中命名为-X rename-threshold=<value>)。将数字降低使得Git更愿意将明显不同的文件视为“#34;同样的&#34;文件。使数字更高,使得Git不太愿意将这些文件视为&#34;相同的&#34;,如果你将它设置为100%,那么文件&#39;内容必须完全匹配。

如果是这种情况并且这个过程进展顺利,你可能会得到你想要的东西,而不需要任何进一步的棘手的位。如果没有,那么:

手动完成

如果Git是正确的,并且js/main.js真的 重新命名,而js/main.js确实 是新的,则可能不建议将其合并文件。但是,可以使用git merge-file执行此操作,该javascript/main.js适用于工作树中的普通文件。首先,您需要将所有三个文件都放入工作树中:

  • 合并基础版本,最初在合并基础提交中命名为--ours(无论其哈希ID是什么)。
  • 当前提交中名为HEAD的{​​{1}}或js/main.js版本。
  • --theirs版本,在提交时也称为js/main.js

这三个版本中的两个已经在您的工作树中使用,使用Git宣布的两个名称。

索引中还应该有每个文件的副本:合并基础作为第1阶段条目存在,--oursHEAD版本作为第2阶段条目存在,并且--theirs版本作为第3阶段条目存在。这意味着您可以使用git showgit checkout-index来获取每个。 (事实上​​,您可以使用git checkout-idnex --stage=all将所有这些文件作为临时文件同时使用,但我没有对此进行过实验。)由于您仍然需要的是基本版本,您可以使用:< / p>

git show :1:js/main.js > main.js.base
例如

(假设是一个Unix风格的shell)。

在工作树中拥有所有三个文件后,您可以运行:

git merge-file <head-version> <base-version> <their-version>

<head-version>中生成文件的冲突标记版本。假设到目前为止您已显示的名称,并将第1阶段文件写入js/main.js.base,那将是:

git merge-file js/main.js js/main.js.base js/main.js.~<hash>