试图理解'git diff'和'git mv'重命名检测机制
这是一个后续行动 在编辑之前,最初创建的文件试图理解'git diff'和'git mv'重命名检测机制,git,github,git-diff,git-status,git-mv,Git,Github,Git Diff,Git Status,Git Mv,这是一个后续行动 在编辑之前,最初创建的文件something将重命名为somethingelse,可以看到: 文件somethingelse然后在第二次vim编辑之前进入something: git mv somethingelse something 基本上如下: #如果在第一行添加了内容,Git将无法检测到重命名 #但是,如果您改为创建2个换行符并用新代码填充第3行, #无论出于何种原因,都会检测到重命名 printf“\n命令:vim某物\n\n” 维姆什么的 如果此时我在代码中添加
something
将重命名为somethingelse
,可以看到:
文件somethingelse
然后在第二次vim编辑之前进入something
:
git mv somethingelse something
基本上如下:
#如果在第一行添加了内容,Git将无法检测到重命名
#但是,如果您改为创建2个换行符并用新代码填充第3行,
#无论出于何种原因,都会检测到重命名
printf“\n命令:vim某物\n\n”
维姆什么的
如果此时我在代码中添加abc
,我们将得到:
First line of code. abc
我认为第1行增加了4个字节,结果是:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: something
deleted: somethingelse
Git会突然检测到重命名(包括编辑):
分支主机上的
要提交的更改:
(使用“git重置磁头…”取消分级)
重命名:somethingelse->something
@torek给出的一个很好的回答/评论在一定程度上解释了这一点,并考虑了git-diff
rename-detection-treshold的git-status
既然我们在这两种情况下都添加了4个字节,那么Git的行为不应该是相同的吗?但是以不同的方式还是换行符与此有关?据我所知,Git的“相似性指数”计算并没有记录在中以外的任何地方
要计算两个文件S(源)和D(目标)的相似性索引,Git:
- 读取两个文件
- 计算所有文件块的哈希表
- 计算文件D的所有块的第二个哈希表
- 从当前文件偏移量开始(最初为零)
- 读取64字节或直到
字符,以先到者为准'\n'
- 如果文件声明为文本,并且在
之前有一个'\n'
,则丢弃'\r'
'\r'
- 使用链接文件中显示的算法对结果字符串(最多64个字节)进行散列
diffcore\u count\u changes
中计算的这两个值(src\u copied
和literal\u added
)将移交给。它完全忽略添加的literal_
计数(此计数用于决定如何构建packfile delta,但不用于重命名评分)。相反,只有复制的src\u
编号才重要:
score = (int)(src_copied * MAX_SCORE / max_size);
其中max_size
是两个输入文件S和D中较大者的大小(以字节为单位)
请注意,有一个较早的计算:
max_size = ((src->size > dst->size) ? src->size : dst->size);
base_size = ((src->size < dst->size) ? src->size : dst->size);
delta_size = max_size - base_size;
max_size=((src->size>dst->size)?src->size:dst->size);
基本尺寸=((src->sizesize)?src->size:dst->size);
增量大小=最大大小-基本大小;
如果两个文件的大小变化“太大”:
if(最大尺寸*(最大尺寸分数-最小尺寸分数)
我们甚至从来没有进入diffcore delta.c
代码来散列它们。最低评分
这里是-M
或-find-renames
的参数,转换为缩放数字<代码>最大得分为60000.0
(键入双精度
),因此当您使用默认的-M50%
时,默认的最小得分
为30000(60000的一半)。但是,除了LF进食前的CR情况外,这种特殊的快捷方式不应影响更昂贵的相似性计算的结果
同样,
git status
始终使用默认值。没有旋钮来更改阈值(也没有重命名查找队列中允许的文件数)。如果存在代码,则设置差异选项的rename\u score
字段。为什么修改文件以添加abc
最终会报告为新文件和使用其他名称删除的文件?您是否也重命名了该文件?您不断地说和提到“重命名”,但您的问题实际上并不表明您正在重命名文件。请明确说明你在做什么。文件在编辑之前会被重命名,这是在第一次发生,但问题中没有提到。如果有先前的信息(即使这是在你发布后续信息的问题中),你需要在这里发布。堆栈溢出不是一个线程化的讨论板,每个问题都需要独立解决。对于小文件,重命名检测总是很脆弱的。
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: somethingelse -> something
score = (int)(src_copied * MAX_SCORE / max_size);
max_size = ((src->size > dst->size) ? src->size : dst->size);
base_size = ((src->size < dst->size) ? src->size : dst->size);
delta_size = max_size - base_size;
if (max_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
return 0;