如何执行忽略所有评论的差异?
Posted
技术标签:
【中文标题】如何执行忽略所有评论的差异?【英文标题】:How can I perform a diff that ignores all comments? 【发布时间】:2011-11-22 04:11:49 【问题描述】:我有一个从原始项目分叉的大型代码库,我正在尝试找出与原始项目的所有差异。许多文件编辑由注释掉的调试代码和其他杂项 cmets 组成。 Ubuntu 下名为 Meld 的 GUI diff/merge 工具可以忽略 cmets,但只能忽略单行 cmets。
是否有任何其他方便的方法可以仅查找非注释差异,无论是使用 GUI 工具还是 linux 命令行工具?万一有所不同,代码是 php 和 javascript 的混合体,所以我主要感兴趣的是忽略 //
、/* */
和 #
。
【问题讨论】:
【参考方案1】:要使用视觉差异,您可以尝试Meld 或DiffMerge。
差异合并
其规则集和选项提供自定义行为。
GNU diffutils
从命令行的角度来看,您可以使用--ignore-matching-lines=RE
选项来代替diff
,例如:
diff -d -I '^#' -I '^ #' file1 file2
请注意,正则表达式必须匹配两个文件中的相应行,并且它匹配大块中每个更改的行才能工作,否则它仍然会显示差异。
使用单引号保护模式免受外壳扩展和转义正则表达式保留的字符(例如括号)。
我们可以阅读diffutils
手册:
但是,
-I
仅在块中每个更改的行(每个插入和每个删除)都与正则表达式匹配时,才会忽略包含正则表达式的行的插入或删除。换句话说,对于每个不可忽略的更改,
diff
会在其附近打印完整的更改集,包括可忽略的更改。您可以使用多个-I
选项为要忽略的行指定多个正则表达式。diff
尝试将每一行与每个正则表达式匹配,从给定的最后一个开始。
armel here 也很好地解释了这种行为。
另见:
How to diff files ignoring comments (lines starting with #)?或者,检查其他差异应用程序,例如:
对于 macOS:Code compare and merge tools 对于 Windows:3-way merge tools for Windows【讨论】:
我想知道如何设置 DiffMerge 以忽略 C/C++ 代码的注释行。尤其是在比较文件夹时。【参考方案2】:您可以先通过stripcmt 过滤这两个文件,这将删除 C 和 C++ cmets。对于删除 #
cmets,sed 's/#.*//'
将删除这些。
当然,当首先删除 cmets 时,您会失去一些上下文,但另一方面, cmets 的差异不会造成任何问题。我想我会这样做(针对单个文件进行描述,根据需要自动执行):
-
如果原始代码库的最新版本是
A
并且
最新的复制代码库是B
,让我们用
为 A'
和 B'
删除了 cmets(例如,在处理时将它们保存到临时文件中)。
找到一些常见的原始版本并将 cmets 从中剥离到 O'
中(或者只需为此重新使用 B'
)。
执行O'
、A'
和B'
的三向合并并保存到C'
。 KDiff3 是一个很好的工具。
现在您有了想要合并的代码更改,但是 C'
没有 cmets,所以回到“正常”模式,以 A'
为基础和 A
和 @987654339 进行新的 3 路合并@。这会将 A'
和 C'
之间的更改(这是您想要的代码更改)提取到基于版本 A
的 cmets 的普通代码库中。
强烈建议您在开始之前在纸上绘制版本树,以便清楚地了解您要处理的版本。但是不要受限于树显示的内容,如果您只是弄清楚要使用哪些版本,您可以merge any version and in any direction。
【讨论】:
【参考方案3】:diff <file1> <file2> | grep -v '^[<>]\ #'
远非完美,但它会让你了解差异
【讨论】:
【参考方案4】:请参阅我们的Smart Differencer 工具系列,它使用语言结构而不是作为指南的布局来比较计算机语言源文件。这尤其意味着它在比较代码时会忽略 cmets 和空格。
有一个SmartDifferencer for PHP。
【讨论】:
PS:马特,我们也在奥斯汀。 @TomasTintera:嗯,我们认为 SmartDiff 非常聪明。您能否更清楚地了解您尝试了哪种语言(PHP?Java?...)Smart Diff,以及没有产生您所期望的情况/实际情况,正是您所期望的? (您可以将示例发送到“support@semanticdesigns.com”,我们会查看)。 @TomasTintera:我注意到 OP 正在寻找一种可以忽略评论(更改)的工具。 SmartDiff 执行 OP 要求的操作。 当然。谢谢你的提醒。删除了我的评论,因为它属于另一个问题和答案。【参考方案5】:gnu diff 支持忽略匹配正则表达式的行:
diff --ignore-matching-lines='^#' file1 file2
对于文件夹:
diff -[bB]qr --ignore-matching-lines='^#' folder1/ folder2/
这将忽略所有以 # 开头的行。
【讨论】:
This would ignore all lines which start with a # at the line beginning
。这不是真的。 --ignore-matching-lines 的行为不同。【参考方案6】:
我试过了:diff file1 file2
和 diff -d -I ^#.\* file1 file2
两种情况下的结果都是一样的 - 包括 cmets;
但是,diff -u file1 file2 | grep -v '^ \|^.#\|^.$'
给出了
我需要的是:只有真正的差异,没有 cmets,没有空行。 ;)
【讨论】:
【参考方案7】:试试:
diff -I REGEXP -I REGEXP2 file1 file 2
参见:Regular expression ***
以下是正则表达式的示例,它们会导致差异忽略预处理器指令和标准注释块类型。
例如:
\#*\n
/***/
//*\n
【讨论】:
不,--ignore-matching-lines 并没有完全消灭 cmets。以上是关于如何执行忽略所有评论的差异?的主要内容,如果未能解决你的问题,请参考以下文章