【发布时间】:2016-04-26 03:57:52
【问题描述】:
在 Java 中,文件名与类名相关联。重命名一个重命名两个。
问题是,每当我这样做时,都会发生不好的事情。历史迷失了。发生合并冲突。人们吓坏了。
如何在 git 中重命名文件并处理可能产生的合并冲突?
【问题讨论】:
标签: git
在 Java 中,文件名与类名相关联。重命名一个重命名两个。
问题是,每当我这样做时,都会发生不好的事情。历史迷失了。发生合并冲突。人们吓坏了。
如何在 git 中重命名文件并处理可能产生的合并冲突?
【问题讨论】:
标签: git
在 Git 中:
第一项意味着历史永远不会丢失,它只是神秘的。这并没有太大帮助,但git log --follow(如CodeWizard wrote in his answer)通常可以完成这项工作(尽管--follow 有一些失败)。
第二项的一个后果是 git 不会跟踪文件重命名等目录操作。这意味着在合并操作期间(无论是来自git merge,还是来自git rebase 或git cherry-pick 或git revert 或其他),git 必须猜测哪些文件被命名为什么。
Git 的猜测是基于它的相似性指数,whose computation is a bit complex。您在这里的主要保证是,与之前版本逐位相同的文件将被检测为重命名。
这本身并不足够,因为 Git 稍后会在 git merge 或 git rebase 或其他任何时间启动合并机制,并且重命名(具有逐位相同的内容)可能是埋葬在历史中。例如,假设提交 C0 创建文件,C1 对其进行一些修改,C2 对其进行重命名,然后 C3 再次对其进行修改。如果你说服 git 比较 C1 和 C2,它会找到重命名 - 但在合并操作时,git 会比较 C0 和 C3,如果文件不够相似,git 会错过重命名。
(我们可以修改 Git,使其遍历从 C0 到 C3 的祖先路径上的所有提交以查找重命名,只要您将重命名作为单独的操作提交,这将完全解决此问题。这有点从计算上讲,这很昂贵,但对于某些未来版本的 Git 来说可能是个好主意。当然,它现在也对您没有帮助。还有另一个工具 git-imerge,今天可以提供帮助。)
或者至少,如果您进行其他更改,请对其他文件进行更改。使重命名的文件尽可能相似(位对位相同 = 保证重命名检测,其他任何内容 = 相似性指数起作用)。
这只有在合并的人知道如何说服 Git 进行正确的合并时才有帮助。在最坏的情况下,三个合并应该可以解决问题:一个到重命名点,一个引入重命名,一个从那里到最后。如果未来的 Git 版本提供了 ancestry-path-rename-detect,那么在未来使用它。同时,仅重命名的提交也很好。
【讨论】:
使用git rm
使用git mv 重命名文件后,您可以使用git log --follow <path> 查看文件的历史记录
# Rename the desired files
git mv <old path> <new path>
# Add and commit your changes
git add .
git commit ...
# To view the history of the modified files use
git log --follow <path>
【讨论】: