git如何处理合并移动到不同文件的代码?

时间:2009-12-13 20:12:06

标签: git

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

在合并这两个更改时,git是否会执行任何特殊操作?它是否会识别相同的功能被移动到文件B并在那里应用更改?或者我们最终会丢失更改或在文件A和B中有两个相同功能的副本?

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

  

使用git时,整个'保持   代码运动与变化分开   有一个更根本的原因:   git可以跟踪代码移动(再次,   无论是移动整个文件还是只是移动文件   文件之间的功能)和做一个   'git blame -C'实际上会跟着   文件之间的代码移动。确实如此   通过相似性分析,但它   确实意味着,如果你们两个都移动了   代码同时更改它,   git看不到'哦,那个功能   最初来自那个其他文件',   现在你的注释变得更糟了   关于代码实际来源的地方。

所以看起来git会认识到代码被移动到了其他地方,但并没有真正说明合并过程中会发生什么。

4 个答案:

答案 0 :(得分:8)

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

因此,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可能会有所帮助。

答案 1 :(得分:7)

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

答案 2 :(得分:2)

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

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

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

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

答案 3 :(得分:0)

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

例如:

分支A中的文件的一个功能被移动到同一文件中的另一个位置,同时创建一个分支B来保存它。分支B和分支A之间的区别仅在于同一文件中的代码位置更改。

分支C改变了这个功能。

所以,如果你这样做:

$ git rebase --onto B A C

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