Git squash 重命名文件的提交(保留历史记录)

Posted

技术标签:

【中文标题】Git squash 重命名文件的提交(保留历史记录)【英文标题】:Git squash commits of renamed files (an keep history) 【发布时间】:2015-04-20 18:42:14 【问题描述】:

背景

您好,我正在开发本地功能分支。这个本地分支被很多小提交搞砸了。在将分支推送到远程之前,我想整理一下。

为此,我会做一个交互式变基:

git rebase -i

目前没有问题。

问题

现在是困难的部分: 在开发该功能的过程中,我进行了几次重构,包括文件的重命名移动。 由于重命名文件,重命名文件的历史可用:

git -mv

但是当我在重命名提交之前和之后压缩提交时,历史记录已经消失,git 将更改通知为删除和添加文件。

有什么问题?

如何在不丢失文件历史记录的情况下压缩提交,包括重命名?

【问题讨论】:

【参考方案1】:

Git 不直接跟踪重命名,它会比较文件内容并通过相似性检测重命名。

压缩历史记录时,会将文件的所有更改放在一次提交中。与之前的提交相比,该文件可能会发生很大变化。因此它与之前的提交不是很相似,git认为它是一个删除/添加。

如果您想查看此类文件的历史记录,您必须调整find-renames 阈值。例如。 50% 相似度使用

git log --follow --find-rename=50 -- someFile

diffmergerebase 也有类似的选项。 查看文档:

git rebase

重命名阈值=n 控制用于重命名检测的相似度阈值。另见 git-diff1 -M。

git diff

--查找重命名[=n]

检测重命名。如果指定了 n,则它是相似性指数的阈值(即添加/删除的数量与文件大小相比)。例如,-M90% 表示如果超过 90% 的文件没有更改,Git 应该将删除/添加对视为重命名。如果没有 % 符号,则该数字将被读取为分数,前面有一个小数点。即,-M5 变为 0.5,因此与 -M50% 相同。同样,-M05 与 -M5% 相同。要将检测限制为精确重命名,请使用 -M100%。 默认相似度指数为 50%

【讨论】:

感谢您的回答。所以,用git mv重命名文件实际上并没有告诉 git 保留文件的历史记录,而是只是重命名文件,然后它会自动检测到文件已被重命名?换句话说:没有可能做我想做的事?唯一的可能是在单独的提交中进行重命名。 有没有办法通过在签入时指定相似性来强制 git 将文件识别为重命名而不是新文件? 哇,这是一个令人震惊的消息,真的很糟糕。我一直鼓吹使用git mv 进行重命名以允许git 跟踪重命名 到git newbees,现在我也陷入了一个不可能的rebase 重命名文件的提交中。 @ViRuSTriNiTy 当一个 git 提交包含对文件的大量更改以及重命名时,我经常遇到问题。当开发人员压缩大量提交时,通常会发生这种情况。我通常更喜欢在一次提交中重命名或更改文件。当然,在 Java 等一些语言中,由于有包声明,移动也会更改源文件的内容,但这是一个很小的内容更改,git 可以轻松跟踪它。 @RenéLink 是的,小提交是关键。在发布我的最后一条评论后,我基本上只压缩了那些不包含重命名的提交。

以上是关于Git squash 重命名文件的提交(保留历史记录)的主要内容,如果未能解决你的问题,请参考以下文章

text git实用程序用于移动/重命名文件或文件夹并使用它保留历史记录。

在 git 文件重命名后使 Xcode 5 跟随历史

如何在 Visual Studio 中重命名方法并保留历史记录?

在git下提交文件时如何控制重命名阈值?

在 Git 中,如何在不挑选新分支的情况下对历史中具有多个合并提交的分支进行 rebase + squash

如何在GIT Rebase Interactive Squash之后删除远程存储库上的历史记录提交消息