我正在寻找一个可以比较两个 C++ 源代码并找到代码意义差异的应用程序(用于比较可能被重新格式化的版本)。至少,它能够忽略空格、制表符和换行符的变化,而不会影响源代码的功能(请注意,换行符是否被视为空格依赖于语言,而 C 和 C++ 也是如此)。而且,理想情况下,可以准确识别所有代码有意义的差异。我在 Ubuntu 下。
按照diff --help | grep ignore
我的diff -bBwZ
预期合理地这项工作(我预计会得到一些假阴性,稍后处理)。然而,事实并非如此。
如果我有以下带有片段的文件
测试_diff1.txt
else if (prop == "P1") { return 0; }
和 test_diff2.txt
else if (prop == "P1") {
return 0;
}
然后
$ diff -bBwZ test_diff1.txt test_diff2.txt
1c1,3
< else if (prop == "P1") { return 0; }
---
> else if (prop == "P1") {
> return 0;
> }
而不是空的结果。
使用代码格式化程序作为两个输入的“过滤器”可能会过滤掉这些差异,但随后必须将最终的输出绑定到原始输入,以便最终报告差异以保留实际的文本和行号。因此,无需适当的编译器即可实现目标……但我不知道是否有可用的方法。
能达到目的吗diff
?
否则,还有其他方法吗(最好是命令行)?
答案1
您可以使用dwdiff
。从man dwdiff
:
dwdiff
- 分隔词差异程序
程序非常巧妙 - 参见dwdiff --help
:
$ dwdiff --help
Usage: dwdiff [OPTIONS] <OLD FILE> <NEW FILE>
-h, --help Print this help message
-v, --version Print version and copyright information
-d <delim>, --delimiters=<delim> Specify delimiters
-P, --punctuation Use punctuation characters as delimiters
-W <ws>, --white-space=<ws> Specify whitespace characters
-u, --diff-input Read the input as the output from diff
-S[<marker>], --paragraph-separator[=<marker>] Show inserted or deleted blocks
of empty lines, optionally overriding the marker
-1, --no-deleted Do not print deleted words
-2, --no-inserted Do not print inserted words
-3, --no-common Do not print common words
-L[<width>], --line-numbers[<width>] Prepend line numbers
-C<num>, --context=<num> Show <num> lines of context
-s, --statistics Print statistics when done
--wdiff-output Produce wdiff compatible output
-i, --ignore-case Ignore differences in case
-I, --ignore-formatting Ignore formatting differences
-m <num>, --match-context=<num> Use <num> words of context for matching
--aggregate-changes Allow close changes to aggregate
-A <alg>, --algorithm=<alg> Choose algorithm: best, normal, fast
-c[<spec>], --color[=<spec>] Color mode
-l, --less-mode As -p but also overstrike whitespace
-p, --printer Use overstriking and bold text
-w <string>, --start-delete=<string> String to mark begin of deleted text
-x <string>, --stop-delete=<string> String to mark end of deleted text
-y <string>, --start-insert=<string> String to mark begin of inserted text
-z <string>, --stop-insert=<string> String to mark end of inserted text
-R, --repeat-markers Repeat markers at newlines
--profile=<name> Use profile <name>
--no-profile Disable profile reading
测试一下:
cat << EOF > test_diff1.txt
else if (prop == "P1") { return 0; }
EOF
cat << EOF > test_diff2.txt
else if (prop == "P1") {
return 0;
}
EOF
然后启动比较:
$ dwdiff test_diff1.txt test_diff2.txt --statistics
else if (prop == "P1") {
return 0;
}
old: 9 words 9 100% common 0 0% deleted 0 0% changed
new: 9 words 9 100% common 0 0% inserted 0 0% changed
请注意100% common
多于。
答案2
答案3
在类似的情况下,当我需要以git
与代码格式无关的方式比较两个分支时,我这样做了:
创建临时分支:
$ git co feature-a $ git co -b 1 $ git co feature-b $ git co -b 2
使用以下方法格式化两个分支
clang-format
:$ git co 1 $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google $ git ci -a -m1 --no-verify $ git co 2 $ find . -name '*.cpp' -print0 | parallel -0 -n 1 clang-format -i -style=google $ git ci -a -m2 --no-verify
做了实际比较:
$ git diff -w -b 1 2
(
-w -b
允许您忽略空间差异,以防万一)。
您可能uncrustify
更喜欢clang-format
(uncrustify
可以mod_full_brace_if
用来强制在单行if
主体周围插入/删除花括号)。
此外,如果parallel
未安装 GNU,请使用xargs
- 其功能相同,但时间会稍长一些。