举个例子,如果我们提交了以下(无意义的)代码:
if (x.some_property)
{
dothing1();
dothing2();
}
我们在顶部添加一个条件分支,并将现有代码设为 else 分支:
if (x.something_else)
{
now_other_here();
second_here();
}
else if (x.some_property)
{
dothing1();
dothing2();
}
然后
git diff
以及所有支持的比较算法显示:
- if (x.some_property)
+ if (x.something_else)
+ {
+ now_other_here();
+ second_here();
+ }
+ else if (x.some_property)
这是正确的。在我看来,还有另一个可能的差异:
+ if (x.something_else)
+ {
+ now_other_here();
+ second_here();
+ }
- if (x.some_property)
+ else if (x.some_property)
为什么 git 更喜欢第一个?我发现第二个差异更容易作为人类解析,原因有两个:
我的假设是 git 从上到下解析文件,因此更喜欢更早而不是稍后显示修改。
是否可以更改 git 的行为以显示第二个差异?
将其写为答案而不是评论只是因为长度限制。很确定这不是您正在寻找的答案。 :-)
为了实现你想要的,这肯定会产生更直观的结果,diff 算法需要能够执行以下两件事之一:
它需要能够识别:
else if (x.some_property)
更改为
if (x.some_property)
这需要 diff 查看每对不同线的内部,找出它们有多少不同,并检查某种“相似性阈值”。这会对性能造成影响,并且阈值的设置可能非常主观 - 需要更改多少个字符才能确定两行完全不相关?
另一个解决方案是教 diff 实际解析语言。然后它就可以看到
else if
行后面的整个代码块没有改变,并识别出 else if
行原来是 if
行。然而,将 diff 从“愚蠢”的基于行的文本处理器转变为“智能”语法感知解析器将会对性能造成很大影响。这值得么?我不知道。