【问题标题】:How to rename files in git that are being worked on by other people without losing history?如何在不丢失历史记录的情况下重命名 git 中其他人正在处理的文件?
【发布时间】:2016-04-26 03:57:52
【问题描述】:

在 Java 中,文件名与类名相关联。重命名一个重命名两个。

问题是,每当我这样做时,都会发生不好的事情。历史迷失了。发生合并冲突。人们吓坏了。

如何在 git 中重命名文件并处理可能产生的合并冲突?

【问题讨论】:

    标签: git


    【解决方案1】:

    在 Git 中:

    1. 历史记录附加到提交,而不是文件。
    2. 提交记录是 state,而不是 change

    第一项意味着历史永远不会丢失,它只是神秘的。这并没有太大帮助,但git log --follow(如CodeWizard wrote in his answer)通常可以完成这项工作(尽管--follow 有一些失败)。

    第二项的一个后果是 git 不会跟踪文件重命名等目录操作。这意味着在合并操作期间(无论是来自git merge,还是来自git rebasegit cherry-pickgit revert 或其他),git 必须猜测哪些文件被命名为什么。

    Git 的猜测是基于它的相似性指数whose computation is a bit complex。您在这里的主要保证是,与之前版本逐位相同的文件将被检测为重命名。

    这本身并不足够,因为 Git 稍后会在 git mergegit rebase 或其他任何时间启动合并机制,并且重命名(具有逐位相同的内容)可能是埋葬在历史中。例如,假设提交 C0 创建文件,C1 对其进行一些修改,C2 对其进行重命名,然后 C3 再次对其进行修改。如果你说服 git 比较 C1 和 C2,它会找到重命名 - 但在合并操作时,git 会比较 C0 和 C3,如果文件不够相似,git 会错过重命名。

    (我们可以修改 Git,使其遍历从 C0 到 C3 的祖先路径上的所有提交以查找重命名,只要您将重命名作为单独的操作提交,这将完全解决此问题。这有点从计算上讲,这很昂贵,但对于某些未来版本的 Git 来说可能是个好主意。当然,它现在也对您没有帮助。还有另一个工具 git-imerge,今天可以提供帮助。)

    TL;DR 回答:尝试将重命名作为独立提交提交

    或者至少,如果您进行其他更改,请对其他文件进行更改。使重命名的文件尽可能相似(位对位相同 = 保证重命名检测,其他任何内容 = 相似性指数起作用)。

    这只有在合并的人知道如何说服 Git 进行正确的合并时才有帮助。在最坏的情况下,三个合并应该可以解决问题:一个到重命名点,一个引入重命名,一个从那里到最后。如果未来的 Git 版本提供了 ancestry-path-rename-detect,那么在未来使用它。同时,仅重命名的提交也很好。

    【讨论】:

    • 我想我要做的不是重命名文件,而是复制它并重命名副本。然后我将在原始文件中添加一个小注释,说明它正在被其他文件替换,因此请不要使用或修改它,而是修改副本。
    • “提交记录状态,而不是更改”到底是什么意思?
    • 嗯,通过例子定义:如果昨天是27度,今天是3度,今天的信息是变化的。如果昨天是27度,现在是30度,今天的信息就是一个状态。如果您知道某些先前的状态,则可以进行更改,但您必须从至少一个状态开始。只知道状态,您就可以发现变化。只知道变化,你无法找到实际的状态。所以状态似乎更好。但是假设我只告诉你今天是30,上周是25,然后问你四天前是什么?如果你有所有的变化,你可以回答。
    • (续)因此,由于 git 记录 states,因此很容易计算“上周与今天”(只需减去),但这并不能告诉您您是如何到达这里的。你必须走过每一天,计算每一天的变化,才能找到你到达今天状态的路径。这就是 git 可以(但不会)为查找重命名而做的事情,前提是您已经单独提交了重命名。
    【解决方案2】:

    使用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>
    

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 2012-06-05
      • 2011-03-09
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 2011-05-09
      相关资源
      最近更新 更多