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

Posted

技术标签:

【中文标题】在git下提交文件时如何控制重命名阈值?【英文标题】:How can I control the rename threshold when committing files under git? 【发布时间】:2013-01-27 18:48:39 【问题描述】:

我正在尝试将特定项目的连续快照放入 git 的历史记录中。我通过使用每个快照的内容填充存储库目录然后运行来做到这一点

git add -A .
git commit -m 'Version X'

这是this answer推荐的方法。但是,我看到只有当 100% 的文件内容保持不变时,提交才会识别文件重命名。有没有办法影响git commit 的重命名检测以使其找到文件内容发生了一些变化的重命名?我看到git mergegit diff 有多种控制重命名阈值的选项,但git commit 不存在这些选项。

我尝试过的事情:

使用自制脚本定位重命名的文件,并在提交新文件内容之前将重命名到新位置的原始文件执行提交。但是,这会引入人工提交,而且看起来不优雅,因为它没有使用 git 的重命名检测功能。

为每个快照创建一个单独的分支,然后将连续的分支合并到 master 使用

git merge -s recursive -Xtheirs -Xpatience -Xrename-threshold=20

但是,这让我保留了旧版本的重命名文件,同时也无法检测到重命名。

【问题讨论】:

这有关系吗?在git commit 中设置这样的选项只会影响该命令的 UI; Git 实际上并不跟踪重命名。 我希望 git log --follow 能够跨重命名工作。通过简单的提交序列,它会在文件的最新版本处停止。 【参考方案1】:

git commit 从不检测重命名。它只是将内容写入存储库。重命名(以及副本)仅在事后检测到,即在运行git diffgit merge 和朋友时。那是因为git 不存储任何重命名/复制信息。

【讨论】:

git commit 的输出表明某些文件是否已被重命名。我已经看到,当此输出指示重命名时,我可以使用git log --follow 追溯文件的历史记录。这是我希望完成的。 但该信息未存储,因此git-commit 拥有这样的选项没有意义。 在新位置提交具有相同内容的提交似乎改进了git log --follow 使用的启发式方法,这让我感到困惑。 这是我尝试遵循的模式:将重命名和修改设为两个单独的提交。这极大地改进了重命名检测,根据我的经验,这也有助于解决合并冲突。 如果 git 没有像答案所暗示的那样存储任何重命名/复制信息,那么 git mv 命令会做什么?!【参考方案2】:

如 cmets 和另一个答案所示,在提交中调整重命名检测阈值是没有意义的,因为这只会更改命令的输出,而不是实际存储在提交中的内容。

可以做的是调整git log 命令中的重命名检测阈值。您可以使用--find-renames 参数来执行此操作。这主要完成了我想要达到的结果。

【讨论】:

git log --find-renames 只显示提交日志。我知道我需要更改复制/重命名阈值百分比,但我没有看到任何直接的语法示例。你能稍微具体一点吗? --find-renames 更改阈值。我不知道有哪些选项可以为您提供更大的控制权。 我发现了更多关于我的确切问题的信息。在一天的时间里,我对我的代码进行了大量的更改。包括文件添加和删除等内容。然后我运行 git add *.java 将我的所有更改添加到当前更改列表中。并且 git 错误地假设某些文件是重命名的,但它们都不是。为了解决这个问题,我必须将错误地假定为重命名的文件添加到独占更改列表中,提交这些文件,然后对所有其他文件进行另一次提交。所以我希望更改 find-renames 阈值,但找不到 git add 命令 @anon58192932 --find-renames(或-M)也采用可选的阈值参数:git-scm.com/docs/git-diff。例如,-M90% 表示如果 90% 以上的文件未更改,Git 应该将删除/添加对视为重命名。 太棒了,感谢@KevinCooper - 1.5 年后仍然非常有用。

以上是关于在git下提交文件时如何控制重命名阈值?的主要内容,如果未能解决你的问题,请参考以下文章

git提交重命名文件

让 git 忽略重命名 [重复]

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

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

Git 修改最后一次提交,删除文件,重命名文件

git --删除文件重命名