假设我在文件A中有函数X,我想将该函数移动到文件B.同时,其他人对文件A中的函数X进行了更改.
合并这两个变化时git是否做了什么特别的事情?它是否会识别相同的功能被移动到文件B并在那里应用更改?或者我们最终会丢失更改或在文件A和B中有两个相同功能的副本?
我发现的关于在git中移动代码的大多数文章主要是指重命名整个文件而不是文件内的代码块.我发现的最接近的是来自内核陷阱的Linus:
当使用git时,整个'保持代码移动与更改分开'有一个更基本的原因:git可以跟踪代码移动(再次,无论是移动整个文件还是只移动文件之间的函数),并做一个'git blame - C'实际上将遵循文件之间的代码移动.它通过相似性分析来做到这一点,但它确实意味着如果你同时移动代码并改变它,git就看不到'哦,那个函数最初来自那个其他文件',现在你得到更糟糕的注释代码实际来自哪里.
所以看起来git会认识到代码被移动到其他地方,但并没有真正说明合并期间会发生什么.
我不认为以前的答案在一般情况下是正确的,因为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可能会有所帮助.
不,git不会做这种程度的改变.移动整个文件时会注意到; 因此,例如,如果您移动了文件,删除了其中的所有内容,则可能会有机会获取更改.但它不会对每个子文件或任何类型的重构进行更改.