Git 合并添加新文件而不是冲突标记 - CONFLICT (rename/add)
Git Merge Adds New File Instead of Conflict Markers - CONFLICT (rename/add)
当在命令行上 运行 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
& js/main.js~%commit-hash%
如何让 git 给我冲突标记而不是新文件?
& 谁能解释一下为什么会这样?
- 注意:为了举例,
%commit-hash%
只是实际提交哈希的占位符。
TL;DR
尝试使用 -X find-renames=<value>
获得不同的重命名检测。或者,如果那行不通或您不喜欢该方法,请在必要时从存储在索引中的多个阶段中提取所有文件,然后使用 git merge-file
来创建冲突 "by hand"。
长
这是一个高级别冲突:由于多个不同的文件更改名称而发生的冲突,而不是由于多个不同的文件而发生的冲突出现在 一个文件中 .
Git 已经告诉你具体问题是什么了:
Rename javascript/main.js->js/main.js
in HEAD
...
因此,当将当前或 HEAD
提交与您和他们开始的公共合并基础进行比较时,Git 发现 您 javascript/main.js
并将该文件重命名为 js/main.js
。
... js/main.js
added in 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.js
不同js/main.js
。所以它把他们的 js/main.js
放到了 js/main.js~<em>hash</em>
.
How can I make git give me conflict markers to work with instead of a new file?
也许你可以轻松做到这一点,也许不能。
首先,你要判断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=<value>
设置(名为 -X rename-threshold=<value>
在 Git 的旧版本中)。降低数字会使 Git 更愿意将明显不同的文件视为 "the same" 文件。使数字更高会使 Git 不太愿意将此类文件视为 "the same",如果将其设置为 100%,则文件内容必须完全匹配。
如果情况确实如此,并且此过程顺利进行,您可能会得到想要的东西,而不需要任何其他棘手的事情。如果没有,那么:
手工制作
如果Git是正确的,你的js/main.js
真的是重命名,而他们的js/main.js
真的是 新的,合并文件可能是不可取的。但是,您 可以 使用 git merge-file
来执行此操作,它适用于工作树中的普通文件。首先,您需要将所有三个文件都放入您的工作树中:
- 合并基础版本,最初在合并基础提交中命名为
javascript/main.js
(无论其哈希 ID 是什么)。
--ours
或 HEAD
版本,在当前提交中命名为 js/main.js
。
--theirs
版本,也被命名为 js/main.js
,但在他们的提交中。
这三个版本中的两个已经在您的工作树中可用,使用 Git 宣布的两个名称。
您的索引中还应该有每个文件的副本:合并基础作为第 1 阶段条目存在,--ours
或 HEAD
版本作为第 2 阶段存在条目,--theirs
版本作为第 3 阶段条目存在。这意味着您可以使用 git show
或 git checkout-index
来访问每个。 (事实上 ,您可能可以使用 git checkout-idnex --stage=all
将它们全部作为临时文件一次获取,但我没有试验过这个。)由于您仍然需要的是基本版本,您可以使用:
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>
当在命令行上 运行 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
& js/main.js~%commit-hash%
如何让 git 给我冲突标记而不是新文件?
& 谁能解释一下为什么会这样?
- 注意:为了举例,
%commit-hash%
只是实际提交哈希的占位符。
TL;DR
尝试使用 -X find-renames=<value>
获得不同的重命名检测。或者,如果那行不通或您不喜欢该方法,请在必要时从存储在索引中的多个阶段中提取所有文件,然后使用 git merge-file
来创建冲突 "by hand"。
长
这是一个高级别冲突:由于多个不同的文件更改名称而发生的冲突,而不是由于多个不同的文件而发生的冲突出现在 一个文件中 .
Git 已经告诉你具体问题是什么了:
Rename
javascript/main.js->js/main.js
inHEAD
...
因此,当将当前或 HEAD
提交与您和他们开始的公共合并基础进行比较时,Git 发现 您 javascript/main.js
并将该文件重命名为 js/main.js
。
...
js/main.js
added inhash
他们,无论他们是谁,在 javascript/main.js
中留下了文件 javascript/main.js
,但随后创建了一个名为 js/main.js
的 新 文件。
因为只能有一个个名为js/main.js
的文件,Git必须做一些特别的事情。它不能把你的js/main.js
(你从javascript/main.js
重命名的)放到js/main.js
和中他们的是新创建的,但与js/main.js
不同js/main.js
。所以它把他们的 js/main.js
放到了 js/main.js~<em>hash</em>
.
How can I make git give me conflict markers to work with instead of a new file?
也许你可以轻松做到这一点,也许不能。
首先,你要判断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=<value>
设置(名为 -X rename-threshold=<value>
在 Git 的旧版本中)。降低数字会使 Git 更愿意将明显不同的文件视为 "the same" 文件。使数字更高会使 Git 不太愿意将此类文件视为 "the same",如果将其设置为 100%,则文件内容必须完全匹配。
如果情况确实如此,并且此过程顺利进行,您可能会得到想要的东西,而不需要任何其他棘手的事情。如果没有,那么:
手工制作
如果Git是正确的,你的js/main.js
真的是重命名,而他们的js/main.js
真的是 新的,合并文件可能是不可取的。但是,您 可以 使用 git merge-file
来执行此操作,它适用于工作树中的普通文件。首先,您需要将所有三个文件都放入您的工作树中:
- 合并基础版本,最初在合并基础提交中命名为
javascript/main.js
(无论其哈希 ID 是什么)。 --ours
或HEAD
版本,在当前提交中命名为js/main.js
。--theirs
版本,也被命名为js/main.js
,但在他们的提交中。
这三个版本中的两个已经在您的工作树中可用,使用 Git 宣布的两个名称。
您的索引中还应该有每个文件的副本:合并基础作为第 1 阶段条目存在,--ours
或 HEAD
版本作为第 2 阶段存在条目,--theirs
版本作为第 3 阶段条目存在。这意味着您可以使用 git show
或 git checkout-index
来访问每个。 (事实上 ,您可能可以使用 git checkout-idnex --stage=all
将它们全部作为临时文件一次获取,但我没有试验过这个。)由于您仍然需要的是基本版本,您可以使用:
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>