Git原理-探究rename规则

2024/06/13 | 字数758 | 阅读2分钟


在《Git原理-探寻日志记录》中我们看到,git是可以判断文件是否被改了个名字:

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
git log --name-status
commit dc91f7f38cdb3c8876a7bfd38020e2a64f33015d (HEAD -> master, origin/master)
Author: ticktechman <ticktechman@gmail.com>
Date:   2024-06-12 19:28:09 +0800

    delete conn.c

D    src/conn.c

commit 0909df98f750118bebab6fb325ede8a836b6b7c1
Author: ticktechman <ticktechman@gmail.com>
Date:   2024-06-12 19:27:38 +0800

    rename demo.c to conn.c

R100 src/demo.c  src/conn.c

这里最后一行中的R100表示这是一个rename的改动,100表示100%相同。由此我们有了下面两个疑问:

  1. Git是如何判断是一个rename的改动的呢?
  2. 除了100%相同,是否还有90%或者80%相同呢?

判断依据

相似度计算

从上面的判断依据中,我们可以看到有一个两个文件相似度的值,这个值是如何来的呢?既然是要判断相似度,那就免不了要读取文件内容,git会将两个文件中的内容分割成64Bytes大小的块,然后分块计算HASH值,HASH值相同则认为文件内容相同,相似度就等于相同部分的大小与文件总大小的比值。计算HASH的时候会忽略换行符和回车符,因为他们对文件相似度没有贡献。公式如下:

c
1
2
3
4
5
6
// diffcore-rename.c
//     max_size为需要对比的两个文件大小取最大值
//     src_copied就是两个文件相同部分的大小
//     score就是计算出来的分值,相似度百分比 = score / MAX_SCORE
#define MAX_SCORE 60000.0
score = (int)(src_copied * MAX_SCORE / max_size);

选哪些文件进行对比

上一篇:Git原理-探寻日志记录

【文章不错,鼓励一下】