Git合并移动的文件

时间:2015-10-21 21:48:12

标签: git github

我分叉了一个仓库并更改了文件A.现在,上游仓库中的文件A已移至子目录。我正在尝试将上游仓库合并到我的前叉。

Git认为文件A在其原始位置被删除,并且在新的子目录中创建了一个新文件(这也可能是因为他们将文件向上游移动的方式)。

我希望在新位置修改此文件,尽可能减少影响,w.r.t提交历史记录和内容。任何人都可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:8)

Git总是通过比较所讨论的两棵树(或者一棵树和索引,对于不包含git merge本身的情况)来检测重命名"事后" (Linus Torvalds认为这是一项功能;例如,请参阅this SO question。)

在任何情况下,git merge将运行git的内部差异,启用合并检测并且默认相似性索引为50%,除非您另外配置它​​。 1 同样,git diff有一些默认值也是可配置的。如果您在合并库和上游之间手动运行git diff --find-renames -M50%,那么您可能会很好(但请参阅有关配置的脚注1)。

如果git 没有检测到重命名,则可能需要调整重命名检测阈值和/或增加git应考虑的文件数。其中第一个是rename-threshold选项中的-X值(rename-threshold首次出现在git 1.7.4中)。有关详细信息,请参阅the documentation

1 您可以将merge.renameLimit设置为重命名检测方面要考虑的文件数。如果未设置,则当前默认值为1000个文件(但默认值随时间而变化)。另外,如果你没有设置它,merge会使用diff.renameLimit,所以你可以只设置其中的第二个,并且diff和merge都使用这两个值。

文件重命名检测的工作方式有点复杂,但很容易通过示例进行描述。假设git将提交12345与提交67890进行比较,而在12345中则存在路径名为AB/CD的文件;但在67890中有路径名B/gronkB/CD。这意味着路径A已消失,但新路径B/gronk已出现。然后Git会记住这些路径(最多重命名限制值),并将12345:A的内容与67890:B/gronk的内容进行比较。如果文件与#34;足够相似",git将声明12345:A已重命名为67890:B/gronk

我不确定git是如何确定文件是50%,或75%,或类似/不同的。我已经看到相似性指数基于" chunks"而不是线条(尽管通常的差异输出是面向行的),但是。

答案 1 :(得分:2)

您需要使用git mv而不只是mv来移动文件。

由于git获取内容的快照,因此它不关心文件名(作为元数据存储在idx文件中)。

如果您只是移动文件,git将无法“理解”您要移动它并将其视为新文件。

您需要还原更改,然后使用:

git mv <old path> <new path>

现在处于git状态,您将看到文件的移动,而不是删除文件并创建新文件。