新的 git diff 压实启发法不起作用
New git diff compaction heuristic isn't working
更新
感谢@torek 的回答,现在已经解决了
我需要在新添加的内容之上添加更多行,以便 Git 可以向上移动 diff'ed 块,我的意思是:
+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 diff
或 git diff --compaction-heuristic
那么我会得到以下 unexpected 输出:
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 阅读此博客 post,我相信我的输出应该看起来更像:
+["foo", "bar", "baz"].map do |i|
+ i
+end
+
["foo", "bar", "baz"].map do |i|
i.upcase
end
git 的 diffing 算法的想法更智能,能够识别区块变化。
我也试过将以下内容添加到我的 ~/.gitconfig
但它对结果没有任何影响,我仍然得到意外的输出:
[diff]
compactionHeuristic = true
关于我在这里遗漏的任何想法?
我还没有玩过新功能,所以这可能需要从一粒盐到满满的盐,但是:
Any ideas on what I'm missing here?
描述明确指出 git diff hunks 向上移动 直到到达 空白行 。第1行以上没有空行;如果有的话,这可能就足够了。 (它可能需要更多 "above" 上下文——不必为空——因为规范是在上下三行上下文中,并且从简短描述中不清楚 "moving up" 是否会是由于缺少额外的行而受阻。)
说到 "git diff compaction heuristic isn't working"...Git 2.12(2017 年第一季度)将 淘汰该启发式算法。
.
"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 (23 Dec 2016) by Junio C Hamano (gitster
)。
Suggested-by: Jeff King (peff
).
(由 Junio C Hamano -- gitster
-- in commit 2ced5f2 合并,2017 年 1 月 10 日)
详情:
diff
: 退出 "compaction" 启发式
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 (29 Oct 2017) by Carlos Martín Nieto (carlosmn
)。
(由 Junio C Hamano -- gitster
-- in 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 (27 Jul 2018) by Stefan Beller (stefanbeller
)。
(由 Junio C Hamano -- gitster
-- in 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.
更新
感谢@torek 的回答,现在已经解决了
我需要在新添加的内容之上添加更多行,以便 Git 可以向上移动 diff'ed 块,我的意思是:
+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 diff
或 git diff --compaction-heuristic
那么我会得到以下 unexpected 输出:
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 阅读此博客 post,我相信我的输出应该看起来更像:
+["foo", "bar", "baz"].map do |i|
+ i
+end
+
["foo", "bar", "baz"].map do |i|
i.upcase
end
git 的 diffing 算法的想法更智能,能够识别区块变化。
我也试过将以下内容添加到我的 ~/.gitconfig
但它对结果没有任何影响,我仍然得到意外的输出:
[diff]
compactionHeuristic = true
关于我在这里遗漏的任何想法?
我还没有玩过新功能,所以这可能需要从一粒盐到满满的盐,但是:
Any ideas on what I'm missing here?
描述明确指出 git diff hunks 向上移动 直到到达 空白行 。第1行以上没有空行;如果有的话,这可能就足够了。 (它可能需要更多 "above" 上下文——不必为空——因为规范是在上下三行上下文中,并且从简短描述中不清楚 "moving up" 是否会是由于缺少额外的行而受阻。)
说到 "git diff compaction heuristic isn't working"...Git 2.12(2017 年第一季度)将 淘汰该启发式算法。
"
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 (23 Dec 2016) by Junio C Hamano (gitster
)。
Suggested-by: Jeff King (peff
).
(由 Junio C Hamano -- gitster
-- in commit 2ced5f2 合并,2017 年 1 月 10 日)
详情:
diff
: 退出 "compaction" 启发式
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 (29 Oct 2017) by Carlos Martín Nieto (carlosmn
)。
(由 Junio C Hamano -- gitster
-- in commit 662ac3b 合并,2017 年 11 月 6 日)
diff
:--indent-heuristic
is no longer experimentalThis 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 (27 Jul 2018) by Stefan Beller (stefanbeller
)。
(由 Junio C Hamano -- gitster
-- in commit 791ad49 合并,2018 年 8 月 17 日)
xdiff
: reduce indent heuristic overheadSkip 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.