Skip to content

Commit 22387f2

Browse files
committed
gitk: Speed up resolution of short SHA1 ids
On large repositories such as the Linux kernel, it can take quite a noticeable time (several seconds) for gitk to resolve short SHA1 IDs to their long form. This speeds up the process by maintaining lists of IDs indexed by the first 4 characters of the SHA1 ID, speeding up the search by a factor of 65536 on large repositories. Signed-off-by: Paul Mackerras <[email protected]>
1 parent 5c9096f commit 22387f2

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed

gitk

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,12 +641,16 @@ proc varcinit {view} {
641641

642642
proc resetvarcs {view} {
643643
global varcid varccommits parents children vseedcount ordertok
644+
global vshortids
644645

645646
foreach vid [array names varcid $view,*] {
646647
unset varcid($vid)
647648
unset children($vid)
648649
unset parents($vid)
649650
}
651+
foreach vid [array names vshortids $view,*] {
652+
unset vshortids($vid)
653+
}
650654
# some commits might have children but haven't been seen yet
651655
foreach vid [array names children $view,*] {
652656
unset children($vid)
@@ -933,7 +937,7 @@ proc fix_reversal {p a v} {
933937
proc insertrow {id p v} {
934938
global cmitlisted children parents varcid varctok vtokmod
935939
global varccommits ordertok commitidx numcommits curview
936-
global targetid targetrow
940+
global targetid targetrow vshortids
937941

938942
readcommit $id
939943
set vid $v,$id
@@ -942,6 +946,7 @@ proc insertrow {id p v} {
942946
set parents($vid) [list $p]
943947
set a [newvarc $v $id]
944948
set varcid($vid) $a
949+
lappend vshortids($v,[string range $id 0 3]) $id
945950
if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
946951
modify_arc $v $a
947952
}
@@ -1397,7 +1402,7 @@ proc getcommitlines {fd inst view updating} {
13971402
global commitidx commitdata vdatemode
13981403
global parents children curview hlview
13991404
global idpending ordertok
1400-
global varccommits varcid varctok vtokmod vfilelimit
1405+
global varccommits varcid varctok vtokmod vfilelimit vshortids
14011406

14021407
set stuff [read $fd 500000]
14031408
# git log doesn't terminate the last commit with a null...
@@ -1497,6 +1502,8 @@ proc getcommitlines {fd inst view updating} {
14971502
set id [lindex $ids 0]
14981503
set vid $view,$id
14991504

1505+
lappend vshortids($view,[string range $id 0 3]) $id
1506+
15001507
if {!$listed && $updating && ![info exists varcid($vid)] &&
15011508
$vfilelimit($view) ne {}} {
15021509
# git log doesn't rewrite parents for unlisted commits
@@ -1719,11 +1726,26 @@ proc getcommit {id} {
17191726
# and are present in the current view.
17201727
# This is fairly slow...
17211728
proc longid {prefix} {
1722-
global varcid curview
1729+
global varcid curview vshortids
17231730

17241731
set ids {}
1725-
foreach match [array names varcid "$curview,$prefix*"] {
1726-
lappend ids [lindex [split $match ","] 1]
1732+
if {[string length $prefix] >= 4} {
1733+
set vshortid $curview,[string range $prefix 0 3]
1734+
if {[info exists vshortids($vshortid)]} {
1735+
foreach id $vshortids($vshortid) {
1736+
if {[string match "$prefix*" $id]} {
1737+
if {[lsearch -exact $ids $id] < 0} {
1738+
lappend ids $id
1739+
if {[llength $ids] >= 2} break
1740+
}
1741+
}
1742+
}
1743+
}
1744+
} else {
1745+
foreach match [array names varcid "$curview,$prefix*"] {
1746+
lappend ids [lindex [split $match ","] 1]
1747+
if {[llength $ids] >= 2} break
1748+
}
17271749
}
17281750
return $ids
17291751
}

0 commit comments

Comments
 (0)