git - 新的 git diff 压实启发式方法不起作用

标签 git git-diff

更新

感谢@torek 的回答,现在已经解决了

我需要在新添加的内容之上添加更多行,以便 Git 可以向上移动差异 block ,我的意思是:

+a
+b
+c
+
+["foo", "bar", "baz"].map do |i|
+  i
+end
+
 ["foo", "bar", "baz"].map do |i|
   i.upcase
 end

Note: I tried with a single line-break instead of a\nb\nc\n and it also worked as well


原始问题...

我在 Mac OSX 上使用 Git 2.9

这是一个简化的测试用例:

$ mkdir git-highlight && cd git-highlight
$ touch foo.rb

我添加并提交以下内容:

["foo", "bar", "baz"].map do |i|
  i.upcase
end

现在我将文件修改为具有以下内容:

["foo", "bar", "baz"].map do |i|
  i
end

["foo", "bar", "baz"].map do |i|
  i.upcase
end

如果我运行 git diffgit diff --compaction-heuristic 然后我得到以下意外输出:

diff --git a/foo.rb b/foo.rb
index 9056b22..f0d289a 100644
--- a/foo.rb
+++ b/foo.rb
@@ -1,3 +1,7 @@
 ["foo", "bar", "baz"].map do |i|
+  i
+end
+
+["foo", "bar", "baz"].map do |i|
   i.upcase
 end

如果您从 GitHub 阅读这篇博文 https://github.com/blog/2188-git-2-9-has-been-released我被引导相信我的输出应该看起来更像:

+["foo", "bar", "baz"].map do |i|
+  i
+end
+
 ["foo", "bar", "baz"].map do |i|
   i.upcase
 end

git 的 diffing 算法的想法更智能并且能够识别 block 更改。

我也尝试将以下内容添加到我的 ~/.gitconfig 但它对结果没有任何影响,我仍然得到意外的输出:

[diff]
  compactionHeuristic = true

关于我在这里遗漏了什么有什么想法吗?

最佳答案

谈到“git diff 压缩启发式算法不起作用”...Git 2.12(2017 年第一季度)将淘汰该启发式算法
Git 2.14 will set the indent heuristic instead as the default one .

"git diff" and its family had two experimental heuristics to shift the contents of a hunk to make the patch easier to read.
One of them turns out to be better than the other, so leave only the "--indent-heuristic" option and remove the other one.

参见 commit 3cde4e0 (2016 年 12 月 23 日)Junio C Hamano (gitster) .
推荐人:Jeff King (peff) .
(由 Junio C Hamano -- gitster -- merge 于 commit 2ced5f2 ,2017 年 1 月 10 日)

详细信息:

diff:退出“压缩”启发式

When a patch inserts a block of lines, whose last lines are the same as the existing lines that appear before the inserted block, "git diff" can choose any place between these existing lines as the boundary between the pre-context and the added lines (adjusting the end of the inserted block as appropriate) to come up with variants of the same patch, and some variants are easier to read than others.

We have been trying to improve the choice of this boundary, and Git 2.11 shipped with an experimental "compaction-heuristic".
Since then another attempt to improve the logic further resulted in a new "indent-heuristic" logic.
It is agreed that the latter gives better result overall, and the former outlived its usefulness.

Retire "compaction", and keep "indent" as an experimental feature.
The latter hopefully will be turned on by default in a future release, but that should be done as a separate step.


下一个 Git 2.15.x/2.16(2018 年第一季度)的更新:

参见 commit bab7614 (2017 年 10 月 29 日)Carlos Martín Nieto (carlosmn) .
(由 Junio C Hamano -- gitster -- merge 于 commit 662ac3b ,2017 年 11 月 6 日)

diff: --indent-heuristic is no longer experimental

This heuristic has been the default since 2.14 so we should not confuse our users by saying that it's experimental and off by default.


注意:“git diff --indent-heuristic”在极端情况下性能不佳,已在 Git 2.19(2018 年第 3 季度)中修复。

参见 commit 301ef85 (2018 年 7 月 27 日)作者 Stefan Beller (stefanbeller) .
(由 Junio C Hamano -- gitster -- merge 于 commit 791ad49 ,2018 年 8 月 17 日)

xdiff: reduce indent heuristic overhead

Skip searching for better indentation heuristics if we'd slide a hunk more than its size.
This is the easiest fix proposed in the analysis in response to a patch that mercurial took for xdiff to limit searching by a constant.
Using a performance test as:

#!python
open('a', 'w').write(" \n" * 1000000)
open('b', 'w').write(" \n" * 1000001)

This patch reduces the execution of "git diff --no-index a b" from 0.70s to 0.31s. However limiting the sliding to the size of the diff hunk, which was proposed as a solution (that I found easiest to implement for now) is not optimal for cases like:

open('a', 'w').write(" \n" * 1000000)
open('b', 'w').write(" \n" * 2000000)

as then we'd still slide 1000000 times.

In addition to limiting the sliding to size of the hunk, also limit by a constant. Choose 100 lines as the constant as that fits more than a screen, which really means that the diff sliding is probably not providing a lot of benefit anyway.

关于git - 新的 git diff 压实启发式方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37895083/

相关文章:

git - 使用 become/become_user 的 Ansible 2.1.0 无法设置临时文件的权限

git log -p 对比 git show 对比 git diff

git - 同一文件的暂存版本和未暂存版本之间的差异,使用 difftool

git diff 只有我的改变

git 稳定分支 : find not cherry-picked commits

javascript - 在 Windows XP 上安装 ungit 错误 : C:/Documents: No such file or directory

git - 使用 git rev-parse 获取同一分支中的提交范围

php - 使用 git 和 php 进行开发(网络开发)

c++ - cmake:外部项目更新和离线工作

git - 如何让 git 在本地使用图形差异并通过 ssh 使用文本差异?