ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AngusGit 代码溯源是什么:在仓库里查相似代码,不是需求从哪来

AngusGit 代码溯源是什么:在仓库里查相似代码,不是需求从哪来

这篇讲 AngusGit 里的「代码溯源」到底在查什么。看完你可以把它和需求追踪、开源许可证合规分开:这里只做代码相似度查重,告诉你哪段代码和同一个实例里的哪个文件相同或高度相似,不会到互联网上找,也不会自动运行。

「代码溯源」常见还有需求追踪、许可证合规这两种含义,和这里的查重不是一回事;分清之后,才知道手上的问题该去哪个入口。AngusGit 的代码溯源在团队版和企业版中提供,入口是侧栏高级 → 溯源。

1. 三种「代码溯源」,分别是什么

同样说「代码溯源」,不同的人想问的问题并不一样,常见的有下面三种:

说法想回答的问题用什么解决
需求追踪这段代码是为哪个需求写的,哪次发布上线的提交信息、拉取请求里关联 Issue,加上发布记录
许可证合规项目依赖的开源组件是什么许可证,能不能用依赖扫描(SCA)和许可证检查
代码相似度这段代码和别的项目里哪段一样,一样到什么程度AngusGit 的代码溯源

前两种在 AngusGit 里各有做法。需求追踪靠拉取请求关联 Issue:在拉取请求的标题或描述里写上Closes #编号,合并后这个 Issue 会自动关闭,代码和需求就对应上了。许可证合规靠仓库的安全扫描,其中 SCA(软件成分分析)是指扫描项目依赖了哪些开源组件。这两件事都不在代码溯源页面里做,所以下面说的「代码溯源」,只指第三种:代码相似度检查。

2. AngusGit 的代码溯源做什么

打开高级 → 溯源,页面标题是代码溯源,说明是「比对代码相似度,并追踪重复片段的来源。」在这个页面里,每做一次检查就是一个溯源任务。创建溯源任务时要定下两件事:查什么,以及跟谁比。

  • 溯源目标:要检查的代码,也就是「查什么」。可以是一个仓库(可以选分支)、仓库里的一个文件、手工粘贴的一段代码块,或者一个函数。
  • 被溯源仓库:拿来比对的仓库,也就是「跟谁比」。从同一个 AngusGit 实例里选 1 到 50 个仓库,比对的是它们默认分支上的代码。

创建任务时还可以调整相似度阈值(文件默认 80%,代码块默认 90%):调低能看到更多「有点像」的结果,调高则只留下几乎一样的代码,具体怎么调见下一篇。

任务跑完后,结果页会先给出整体的重复率和唯一率,再把每一处匹配按相似度分档:完全相同(95–100%)、高度相似(80–95%)、中等相似(60–80%)、低度相似(40–60%)和唯一代码(0–40%)。每一条匹配都可以点对比代码,把两边的代码左右并排显示出来。

以已经跑完的任务 fixture: source vs dup (repo) 为例:溯源目标是仓库 xlliu/test-trace-source-example,被溯源仓库是 xlliu/test-trace-dup-example。结果页显示溯源仓库数 1/1、溯源文件数 2/2、代码行数 164/164,重复率 84.52%,唯一率 15.48%。其中有两处落在高度相似(80–95%)这一档:src/main/java/cloud/xcan/example/trace/InvoicePriceCalculator.java的相似度是 86.86%(73/94 行),src/billing.py的相似度是 82.18%(62/70 行)。

3. 它是怎么判断「相似」的

不必先搞懂算法,只要知道它大概怎么比,读结果时就不容易误判。

代码溯源不逐个字符地比较文本。它先按编程语言把代码拆成一个个「词」,比如关键字、变量名、运算符和括号,再在两边寻找连续相同的「词」:连续 50 个以上相同,才算作一处重复片段。找到重复片段之后,再综合几种相似度算法算出一个分数。

这样做有两个好处。第一,只改了缩进、空行或注释的代码,判断结果不受影响。第二,可以有意忽略一部分改动:打开忽略标识符差异后,改过变量名、函数名的代码也能被识别为相似;打开忽略字面量差异后,只是字符串和数字不同的代码也能被识别为相似。这两个开关都在创建任务时的高级配置里。

另外,有几类目录不参与比对:以.开头的目录(例如.git、.idea),以及node_modules和target。这些目录里大多是依赖包和构建产物,比对它们没有意义。

4. 适合用在哪些场景

交付验收时查重复。外包或合作方交付了一个新仓库,你想知道里面有多少代码和公司已有的项目重复。做法是把交付的仓库设为溯源目标,把已有的相关仓库选为被溯源仓库,然后看重复率和具体是哪些文件重复。

重构前找复制粘贴的代码。几个服务各自复制了一份相同的工具类,结果改一处就得改好几处。可以先用代码溯源把这些重复找出来,再决定要不要抽成公共模块。

查一段代码还出现在哪里。发现一段有问题的代码,想知道其他项目里有没有同样的写法。可以把溯源目标设为代码块或函数,粘贴这段代码,在相关仓库里查一遍。

它也有做不到的事,用之前先确认:

  • 不会去互联网上找。比对范围只限于你选的、同一个实例里的仓库。想知道代码是否来自某个开源项目,要先把那个开源项目导入到实例里,再把它选为被溯源仓库。
  • 不会自动运行。推送代码不会触发溯源,每次都要手动创建并开始任务。
  • 不判断许可证。找到相似代码之后,能不能用、要不要声明出处,需要人来判断。

常见问题

社区版为什么没有溯源菜单?

代码溯源只在团队版和企业版中提供,社区版不包含,所以看不到这个菜单。这是版本差异,不是故障。

重复率高就说明有问题吗?

不一定。同一个团队的项目常用相同的框架和模板,本来就会有不少相似代码。重复率只是一个提示,还要点开对比代码,看具体是哪些文件重复、是不是本不应该重复的业务代码。

溯源和代码评审有什么关系?

没有直接关系。代码评审看的是一次改动对不对,在拉取请求里进行;代码溯源看的是整份代码和其他仓库像不像,是一次单独的检查任务。两者可以配合使用:溯源发现重复代码后,通过拉取请求做重构,再由评审人把关。

小结

「代码溯源」常被用来指三件事:需求追踪、许可证合规和代码相似度,AngusGit 的代码溯源做的是第三件。每个溯源任务把溯源目标(仓库、文件、代码块或函数)和同一实例里选定的 1 到 50 个被溯源仓库逐段比对,给出重复率、从完全相同到唯一代码的相似度分档,以及每处匹配的具体位置。它适合交付验收查重、重构前找复制粘贴的代码、查一段代码还在哪些项目里出现,但它不会去互联网上找、不会自动运行,也不判断许可证。代码溯源在团队版和企业版中提供,社区版没有溯源菜单;具体怎么建任务、怎么看结果,见下一篇。

结论:AngusGit 的代码溯源(高级 → 溯源)是在同一实例内跨仓库查相似代码的查重工具;需求追踪靠拉取请求关联 Issue(Closes #编号),开源许可证合规靠仓库安全扫描。

参考文章

  • AngusGit 手册:代码溯源
  • 怎么给仓库做代码查重:从建任务到看出重复函数
  • Issue 怎么关联合并请求:写上 Closes #编号,合并后自动关闭
  • 合并前怎么拦住不合规的开源许可证
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进