You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查看Git两个提交间文件的相似内容及匹配代码行?

提交A到提交B的代码留存检测与匹配行提取方法

基础检测方式

最直接的方法是对比两个提交中对应文件的内容,提取完全匹配的代码行:

  • 先用git diff A B --name-status定位提交A中已追踪文件在提交B中的状态(存在、重命名、删除等)
  • 对仍存在的文件,通过git show A:文件路径和git show B:文件路径导出内容,再用工具筛选匹配行:比如grep -Fxf <(git show A:文件路径) <(git show B:文件路径)可按原顺序提取匹配行;comm -12 <(sort 文件A内容) <(sort 文件B内容)能找出共同行(会忽略行顺序)

进阶场景处理

为更精准统计相似代码占比,需处理以下特殊情况:

1. 文件重命名场景

Git可自动追踪文件重命名,先通过git log --follow --name-only -- 文件原路径找到提交B中该文件的新路径,再用git diff --no-index --find-renames=100% <(git show A:原路径) <(git show B:新路径)进行对比,确保按原文件内容匹配。

2. 内容相同的代码块迁移

若代码只是整体迁移(比如函数从文件顶部移到底部),可先提取文件中的代码块(针对Shell脚本,可用awk按function关键字分割函数),再对比代码块内容的一致性,而非逐行按顺序对比。

3. 空白字符变更忽略

如果仅涉及单词后的缩进、未转义/未引用的空白字符变更,对比时可忽略这类差异:

  • 使用diff -w命令忽略所有空白字符差异
  • 或用git diff --ignore-all-space A B -- 文件路径查看忽略空白后的差异,再提取无差异的行

4. Shell脚本的行拆分处理

Shell中未被单引号包裹的行用\拆分后功能一致,需先合并这类拆分行再对比:

  • 用简单脚本预处理文件内容,将以\结尾且不在单引号内的行与下一行合并:
awk '{
    while(sub(/\\$/, "") && getline line > 0) {
        $0 = $0 line
    }
    print
}' 输入文件 > 预处理后文件
  • 用预处理后的文件进行对比,确保拆分后的行被视为相同内容

可选的逻辑级相似性检测

若需要识别变量/函数重命名但逻辑一致的代码,可采用以下方式:

  • 针对Shell脚本,用静态分析工具(如shellcheck的AST输出)提取代码的逻辑结构(分支、循环、命令调用关系),忽略变量/函数名的差异
  • 自定义脚本将所有自定义变量/函数名替换为统一占位符(比如VAR_X、FUNC_X),再对比处理后的代码内容是否一致

内容的提问来源于stack exchange,提问作者jarno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:45:09