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

18

我试图将一个特定项目的历史快照放入git的历史记录中。我是通过将存储库目录填充为每个快照的内容,然后运行

git add -A .
git commit -m 'Version X'
这是这个答案中推荐的方法。但是我看到提交只有当文件内容保持100%相同时才会识别文件重命名。有没有办法影响git commit的重命名检测,让它在文件内容稍有改动时也能找到重命名呢?我看到git mergegit diff有各种选项来控制重命名阈值,但是这些选项在git commit中并不存在。
我尝试过以下事情:
- 使用自制脚本查找重命名文件,将原始文件重命名为其新位置,然后提交新的文件内容前进行提交。但是,这样会引入人为的提交,并且似乎不够优雅,因为它没有使用git的重命名检测功能。 - 为每个快照创建一个单独的分支,然后使用以下命令将连续的分支合并到master上: git merge -s recursive -Xtheirs -Xpatience -Xrename-threshold=20 但是,这会让旧版本的重命名文件留在原地,同时无法检测到重命名。

2
有关紧急情况,设置git commit中的此类选项只会影响该命令的用户界面;Git实际上并不跟踪重命名。 - Fred Foo
1
我希望 git log --follow 能够跨越重命名的文件进行工作。对于一系列普通的提交,它会在文件的最新版本处停止。 - Diomidis Spinellis
2个回答

17

git commit 无法检测重命名,它只是将内容写入仓库。重命名(和复制)只有在事后才能被检测到,即在运行 git diffgit merge 等命令时。这是因为 git 不存储任何重命名/复制信息。


4
git commit 的输出会指示文件是否已被重命名。我曾经看到过当这个输出表明了一个重命名时,我可以用 git log --follow来追踪该文件的历史记录。这就是我的目标。 - Diomidis Spinellis
2
但是该信息不被存储,因此git-commit没有这样的选项是没有意义的。 - Michael Wild
1
我被一个在新位置具有相同内容的提交所分散了注意力,这似乎改善了git log --follow使用的启发式算法。 - Diomidis Spinellis
1
这是我想要遵循的一个模式:将重命名和修改分别作为两个提交。这会显著提高重命名检测的效果,并且在我的经验中还有助于解决合并冲突。 - Michael Wild
1
如果像答案所示,git不存储任何重命名/复制信息,那么git mv命令是做什么的?! - smohadjer
1
它等价于执行 git rm --cached,然后执行 git add - Michael Wild

15

正如评论和其他答案所指出的那样,在提交中调整重命名检测阈值是没有意义的,因为这只会改变命令的输出,而不会改变实际存储在提交中的内容。

然而,你可以在 git log 命令中调整重命名检测阈值。你可以使用 --find-renames 参数来实现这一点。这基本上可以实现我想要的结果。


3
git log --find-renames 命令只会显示提交日志。我知道我需要更改复制/重命名的阈值百分比,但是我没有看到任何直接的语法示例。你可以再稍微具体一些吗? - fIwJlxSzApHEZIl
--find-renames参数可以改变阈值。我不知道有哪些选项可以提供更多的控制。 - Diomidis Spinellis
我找到了更多关于我的确切问题的信息。在一天的过程中,我对我的代码进行了大量的更改,包括添加和删除文件等操作。然后我运行git add *.java将所有更改添加到当前的更改列表中。但是git错误地假设某些文件被重命名了,而实际上它们并没有。为了解决这个问题,我必须将被错误认为是重命名的文件添加到一个独占的更改列表中,提交这些更改,然后再提交其他所有文件的更改。因此,我希望改变查找重命名的阈值,但是在git add命令中找不到它。 - fIwJlxSzApHEZIl
6
--find-renames(或 -M)也可以带有一个可选的阈值参数:https://git-scm.com/docs/git-diff。例如,`-M90%`意味着如果超过90%的文件内容没有改变,Git应将删除/添加的一对文件视为重命名。 - Kevin Cooper
1
太棒了,谢谢@KevinCooper - 令人惊讶的是,1.5年后仍然很有帮助。 - fIwJlxSzApHEZIl

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