【问题标题】:how does git handle merging code that was moved to a different file?git 如何处理移动到不同文件的合并代码?
【发布时间】:2009-12-13 20:12:06
【问题描述】:

假设我在文件 A 中有函数 X,我想将该函数移动到文件 B。与此同时,其他人对文件 A 中的函数 X 进行了更改。

合并这两个更改时,git 有什么特别之处吗?它会识别出相同的功能已移至文件 B 并在那里应用更改吗?或者我们最终会丢失更改或在文件 A 和 B 中拥有相同函数的两个副本?

我发现的大多数关于在 git 中移动代码的文章主要是指重命名整个文件,而不是文件内的代码块。我找到的最接近的是blurb from Linus at kerneltrap

而当使用 git 时,整个 'keep 代码移动与更改分开' 还有一个更根本的原因: git 可以跟踪代码移动(再次, 无论是移动整个文件还是仅移动一个 文件之间的函数),并做一个 'git blame -C' 实际上会跟随 文件之间的代码移动。它确实 通过相似性分析,但它 确实意味着如果你们都移动 代码同时改变它, git 看不到'哦,那个功能 最初来自另一个文件', 现在你得到更糟糕的注释 关于代码的实际来源。

所以看起来 git 会识别出代码被移到了其他地方,但并没有真正说明合并期间会发生什么。

【问题讨论】:

    标签: git


    【解决方案1】:

    不,git 不会进行这种级别的更改。当您移动整个文件时它会注意到;因此,例如,如果您移动了文件,删除了其中的所有其他内容,那么它可能有机会获取更改。但它不会对每个子文件进行更改或任何类型的重构。

    【讨论】:

    • 因此,如果我将 A 中 X 的更改合并到我将 ​​X 移动到 B 的分支中,我基本上会丢失这些更改,因为 Git 认为我删除了这些行?我想我只需要仔细查看差异然后...
    • 您不会丢失它们:您必须手动合并冲突。
    【解决方案2】:

    我不认为前面的答案在一般情况下是正确的,因为 git 并不真正关心文件 - 文件名被用作一些启发式的基础,但 git 考虑内容的方式不是完全围绕文件的概念。与其他 VCS 不同,git 跟踪 content,在这种情况下,内容恰好发生了移动,但它是 相同的内容

    因此,即使文件已被重命名或代码在文件之间移动,git 也应该能够处理分支之间的合并,因此根据您所做的具体操作,它可能会很好地处理合并。

    只要对 X 的更改不会导致合并冲突(如果您同时更改了原始版本重命名的版本,可能会发生这种情况),X 已被移动的事实到 B 无关紧要,合并结果应该包含两个更改的结果。如果有问题,则表明 git 没有正确跟踪代码移动。

    在实践中,之前的答案可能是基于个人经验,当检测机器失败时,https://git.wiki.kernel.org/index.php/GitFaq#How_to_manually_resolve_conflicts_when_Git_failed_to_detect_rename.3F 可能会有所帮助。

    【讨论】:

    • 这个答案在文件重命名的情况下是正确的(只要提交相对于文件大小来说很小,所以重命名检测不会失败)。但问题明确不是关于重命名,而是将一个文件的一部分移动到另一个文件中。在这种情况下,即使进行简单的测试,git 也会可靠地失败。在文件中移动也是一样的,总是失败。
    【解决方案3】:

    我认为 AlBlue 是正确的,而不是 Nye。

    在我的简单测试中,git 1.7.0.5 无法自动合并两个分支,其中一个分支将一行插入一个函数,另一个将该函数移动到同一文件中的新位置。 git 似乎没有跟踪小于文件的内容块。

    要解决合并冲突,进行合并的人必须知道这两个更改是如何工作的以及它们应该如何组合。

    另见git merge: apply changes to code that moved to a different file

    【讨论】:

      【解决方案4】:

      我认为实际情况要复杂得多,但从我的经验来看,git可以很好地处理这种3路合并。

      例如:

      分支 A 中的一个文件的一个功能被移动到同一文件中的另一个位置,同时创建一个分支 B 来保存它。分支B和分支A的区别只是在同一个文件中代码位置的变化。

      C 分支更改了该功能。

      所以,如果你这样做:

      $ git rebase --onto B A C

      它会自动将分支 C 的更改合并到分支 B 中该函数的新位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 1970-01-01
        相关资源
        最近更新 更多