我对git比较新,我之前使用过Subversion.
我注意到,如果文件已重命名,大多数图形git前端和IDE插件似乎都无法显示文件的历史记录.我用的时候
git log --follow
Run Code Online (Sandbox Code Playgroud)
在命令行上,我可以看到重命名的整个日志.
根据Linus Torvalds的说法--follow switch是一个"SVN noob",严肃的git用户不使用它:
--follow是一个彻底的黑客,意味着只是满足前SVN用户,他们从来不知道任何事情,如父母身份或漂亮的修订图表无论如何.
这并不是完全基本的,但是" - follow"的当前实现实际上是一个快速的预处理事物,它固定在修订行走逻辑上,而不是真正的整体.
它实际上被设计为"SVN noob",而不是"真正的git功能".我们的想法是,你要摆脱思维的(破碎)思维方式,重新命名大局.
我的问题:你们中的硬核git用户如何在重命名时获取文件的历史记录?这样做的"真实"方法是什么?
CB *_*ley 68
我认为Linus背后的一般驱动力是 - 并且用一点点盐 - 硬核git用户不关心"文件"的历史.您将内容放在git存储库中,因为整个内容具有有意义的历史记录.
文件重命名是在路径之间移动的"内容"的一个小特例.您可能有一个在git用户可能跟踪的文件之间移动的功能与"pickaxe"功能(例如log -S).
其他"路径"更改包括合并和拆分文件; git并不关心您考虑重命名的文件以及您认为复制(或重命名和删除)的文件只跟踪树的完整内容.
git鼓励"整树"思考,因为许多版本控制系统都是以文件为中心的.这就是为什么git比"文件名"更频繁地引用"路径"的原因.
Alb*_*lli 35
我遇到了与你面临的问题完全相同的问题.即使我不能给你回答,我相信你可以阅读Linus在2005年写的这封电子邮件,这是非常贴切的,可能会给你一个关于如何处理问题的提示:
...我声称任何试图跟踪重命名的SCM都会从根本上被破坏,除非出于内部原因(即允许有效的增量)这样做,因为重命名并不重要.他们不帮你,他们是不是你有兴趣呢.
重要的是找到"这是从哪里来的",而git架构确实做得非常好 - 比其他任何东西都要好得多....
我发现这篇博文引用了它,这对你找到一个可行的解决方案也很有用:
在该消息中,Linus概述了理想的内容跟踪系统如何让您找到代码块如何进入当前形状.您将从文件中的当前代码块开始,返回历史记录以查找更改文件的提交.然后检查提交的更改以查看您感兴趣的代码块是否被它修改,因为更改文件的提交可能不会触及您感兴趣的代码块,而只会触及您感兴趣的代码块.文件.
如果在提交之前发现文件中不存在代码块,则会更深入地检查提交.您可能会发现这是许多可能的情况之一,包括:
- 提交真正引入了代码块.上提交的作者是你猎杀它的起源为很酷的功能的发明者(或谁介绍的bug有罪的一方); 要么
- 文件中不存在代码块,但是在不同的文件中存在五个相同的副本,所有这些副本在提交后都消失了.提交的作者通过引入单个辅助函数重构了重复的代码; 要么
- (作为特殊情况)在提交之前,当前包含您感兴趣的代码块的文件本身不存在,但是存在具有几乎相同内容的另一个文件,以及您感兴趣的代码块,与当时存在的文件中的所有其他内容一起,确实存在于该另一个文件中.提交后它就消失了.提交的作者重命名了该文件,同时对其进行了一些小修改.
在git中,Linus的终极内容跟踪工具尚未以完全自动化的方式存在.但大多数重要成分已经可用.
请告诉我们您在此方面取得的进展.
Mic*_*ker 11
我注意到,如果文件已重命名,大多数图形git前端和IDE插件似乎都无法显示文件的历史记录
您会很高兴知道一些流行的Git UI工具现在支持这一点.有许多可用的Git UI工具,所以我不会全部列出它们,但是例如:
有关Git UI工具的更多信息:
注意:git 2.9(2016年6月)将改善相当多的"错误"性质git log --follow:
见提交ca4e3ca通过(2016年3月30日)SZEDER的Gabor( )szeder.
(由Junio C gitsterHamano合并- -在提交26effb8,2016年4月13日)
如果两个路径'
dir/A/file'和'dir/B/file'具有相同的内容并且父目录被重命名,例如'git mv dir other-dir',则diffcore报告以下确切的重命名:
renamed: dir/B/file -> other-dir/A/file
renamed: dir/A/file -> other-dir/B/file
Run Code Online (Sandbox Code Playgroud)
(注意这里的反演:B/file -> A/file,和A/file -> B/file)
虽然技术上没有错,但这不仅令用户感到困惑,而且还使git命令混淆,这些命令基于重命名信息做出决定,例如
git log --follow other-dir/A/file"跟随"dir/B/file重命名之后.此行为是commit v2.0.0-rc4~8 ^ 2~14(
diffcore-rename.c简化查找精确重命名,2013-11-14)的副作用:存储源的hashmap返回来自同一存储桶的条目,即与当前目标匹配的源,以LIFO的顺序.
因此,迭代首先检查'other-dir/A/file'和'dir/B/file',并在找到相同的内容和基名后,报告确切的重命名.
操作方法如下:
git log -M --summary | grep rename | grep BASENAME
Run Code Online (Sandbox Code Playgroud)
只需将基本名称放入其中即可。
如果结果太多那么你也可以串行grep每个中间目录名称。