Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.
From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:23
Subsystem:
the rest · Maintainer:
Linus Torvalds
On Friday 19 September 2008 17:04:54 Johannes Sixt wrote:
Alexander Gavrilov schrieb:quoted
Also, it should work in the patch mode as well: it reads the patch as binary, and decodes each line separately, based on the encoding determined for the current file.This is great. But we'll have to see how this works on a multi-file diff on Windows. (I sense slowness.)
Yes, yesterday I noticed that when the patch is very big, like when the index has got out of sync, and gitk claims local changes in all of the git-gui repository (>1000 files), first view is slow even on Linux. I made a patch to optimize attribute lookup. I'm afraid that further optimization is impossible without interface changes in git-check-attr, or reimplementing the attribute parser in Tcl.
--- >8 ---From: Alexander Gavrilov <redacted> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs. When the diff contains thousands of files, calling git-check-attr once per file is very slow. With this patch gitk does attribute lookup in batches of 30 files while reading the diff file list, which leads to a very noticeable speedup. Signed-off-by: Alexander Gavrilov <redacted> --- gitk | 34 +++++++++++++++++++++++++++++++++- 1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/gitk b/gitk
index 1355aa2..6fc1e90 100755
--- a/gitk
+++ b/gitk@@ -6530,6 +6530,7 @@ proc gettreediffline {gdtf ids} { global cmitmode vfilelimit curview limitdiffs set nr 0 + set sublist {} while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} { set i [string first "\t" $line] if {$i >= 0} {
@@ -6539,8 +6540,10 @@ proc gettreediffline {gdtf ids} { } set file [encoding convertfrom $file] lappend treediff $file + lappend sublist $file } } + cache_gitattr encoding $sublist if {![eof $gdtf]} { return [expr {$nr >= 1000? 2: 1}] }
@@ -9839,18 +9842,47 @@ proc tcl_encoding {enc} { } proc gitattr {path attr default} { - if {[catch {set r [exec git check-attr $attr -- $path]}]} { + global path_attr_cache + if {[info exists path_attr_cache($attr,$path)]} { + set r $path_attr_cache($attr,$path) + } elseif {[catch {set r [exec git check-attr $attr -- $path]}]} { set r unspecified } else { set r [join [lrange [split $r :] 2 end] :] regsub {^ } $r {} r } + set path_attr_cache($attr,$path) $r if {$r eq {unspecified}} { return $default } return $r } +proc cache_gitattr {attr pathlist} { + global path_attr_cache + set newlist {} + foreach path $pathlist { + if {[info exists path_attr_cache($attr,$path)]} continue + lappend newlist $path + } + while {$newlist ne {}} { + set head [lrange $newlist 0 29] + set newlist [lrange $newlist 30 end] + if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} { + foreach row [split $rlist "\n"] { + set cols [split $row :] + set path [lindex $cols 0] + set value [join [lrange $cols 2 end] :] + if {[string index $path 0] eq "\""} { + set path [encoding convertfrom [lindex $path 0]] + } + set path_attr_cache($attr,$path) $value + } + } + update + } +} + proc get_path_encoding {path} { global gui_encoding set tcl_enc [tcl_encoding $gui_encoding]
--
1.6.0.20.g6148bc