如何将函数声明移动到另一个文件,同时保留Git历史记录?

13
我正在重构一个单文件PHP脚本,将函数和类声明为不同的文件。如何将一段代码块从一个文件移动到另一个文件,同时保留每个单独行的Git历史记录? 我希望能够至少使用git blame查看代码。比较旧版本也会很有帮助。
请注意,我不感兴趣的“解决方法”需要在代码上使用附加命令或标志(例如--follow)来查看其“旧”的历史记录,这需要查看历史记录的人知道该文件需要特殊处理。我正在寻找一种解决方案,可以编写必要的元数据,使得诸如blamelogdiff等常规git命令“正常工作”,而不需要向它们提供附加标志或参数。
我已经阅读了相当帖子,寻找解决类似问题的方法,但没有一个解决git blame单独行的问题。我认为一个可行的解决方案是复制文件及其整个历史记录,然后在此基础上工作。然而,这个问题仍然没有一个令人满意的答案。

1
请注意,git blame 已经跟踪了文件中的代码行,但是除非文件被重命名,否则您仍然需要传递其他选项来告诉 Git 进行移动/复制检测,可能是因为这是一个昂贵的操作。 - user456814
假设“Stas”编写了一段代码并将其检入Git,然后我将该块剪切并粘贴到另一个文件中。现在,git blame将显示我编写了该代码块。我正在寻找一种解决方案,可以让我移动代码,但仍应显示Stas编写的时间和内容。 - dotancohen
2
你是否阅读过git blame文档,看它是否已经实现了你所需要的功能? - user456814
2
具体而言,-C 可能是您想要的(我已删除我的答案,因为虽然从技术上讲 git 不会跟踪此内容,但在实践中,-C 可能已经足够满足您的需求了)。 - andrew cooke
谢谢,我知道 --follow-C1,但我真的在寻找一种解决方案,可以“重写”文件历史记录,以添加原始函数作者的信息到新位置。 - dotancohen
我觉得这非常相关。它可以被扩展为一个更广泛的问题:“我怎样在Git上作为一个编辑器工作并保持原始作者不变?”就像我们在SEN上发布帖子一样。答案是:我们做不到。但我希望我们能够做到。 - cregox
1个回答

6

警告: 这假定改写历史是可以接受的。除非你知道改写历史的影响,否则不要使用此功能。

要将文件拆分为多个文件并保留历史记录,请使用git filter-branch

git filter-branch --tree-filter 'if [ -f original.php ]; then 
    echo part1.php part2.php part3.php | xargs -n 1 cp original.php; fi' HEAD

然后从每个文件中删除您不想要的行(仅保留所需的函数和类),然后提交结果!

4
请注意,链接的文档是Git用户手册,我直到现在才知道它的存在(可能排名较低什么的),但它非常详细,看起来会非常有用。我尽量避免写“谢谢!”这样的评论,但我真的想强调那个链接有多重要。我为了学习Git买了整整一本书,而那个页面上还有一些书里没有的信息。 - jrh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接