Skip to content

Commit 62d3ea6

Browse files
committed
gitk: Speed up the reading of references
We were doing two execs for each tag - one to map the tag ID to a commit ID and one to read the contents of the tag for later display. This speeds up the process by not reading the contents of the tag (instead it is read later if needed), and by using the -d flag to git show-ref, which gives us refs/tags/foo^{} lines which give us the commit ID. Also this uses string operations instead of regexps. Signed-off-by: Paul Mackerras <[email protected]>
1 parent 219ea3a commit 62d3ea6

File tree

1 file changed

+31
-34
lines changed

1 file changed

+31
-34
lines changed

gitk

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -387,47 +387,39 @@ proc getcommit {id} {
387387
}
388388

389389
proc readrefs {} {
390-
global tagids idtags headids idheads tagcontents
390+
global tagids idtags headids idheads tagobjid
391391
global otherrefids idotherrefs mainhead mainheadid
392392

393393
foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
394394
catch {unset $v}
395395
}
396-
set refd [open [list | git show-ref] r]
397-
while {0 <= [set n [gets $refd line]]} {
398-
if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
399-
match id path]} {
400-
continue
401-
}
402-
if {[regexp {^remotes/.*/HEAD$} $path match]} {
403-
continue
404-
}
405-
if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
406-
set type others
407-
set name $path
408-
}
409-
if {[regexp {^remotes/} $path match]} {
410-
set type heads
411-
}
412-
if {$type == "tags"} {
413-
set tagids($name) $id
414-
lappend idtags($id) $name
415-
set obj {}
416-
set type {}
417-
set tag {}
418-
catch {
419-
set commit [exec git rev-parse "$id^0"]
420-
if {$commit != $id} {
421-
set tagids($name) $commit
422-
lappend idtags($commit) $name
423-
}
424-
}
425-
catch {
426-
set tagcontents($name) [exec git cat-file tag $id]
396+
set refd [open [list | git show-ref -d] r]
397+
while {[gets $refd line] >= 0} {
398+
if {[string index $line 40] ne " "} continue
399+
set id [string range $line 0 39]
400+
set ref [string range $line 41 end]
401+
if {![string match "refs/*" $ref]} continue
402+
set name [string range $ref 5 end]
403+
if {[string match "remotes/*" $name]} {
404+
if {![string match "*/HEAD" $name]} {
405+
set headids($name) $id
406+
lappend idheads($id) $name
427407
}
428-
} elseif { $type == "heads" } {
408+
} elseif {[string match "heads/*" $name]} {
409+
set name [string range $name 6 end]
429410
set headids($name) $id
430411
lappend idheads($id) $name
412+
} elseif {[string match "tags/*" $name]} {
413+
# this lets refs/tags/foo^{} overwrite refs/tags/foo,
414+
# which is what we want since the former is the commit ID
415+
set name [string range $name 5 end]
416+
if {[string match "*^{}" $name]} {
417+
set name [string range $name 0 end-3]
418+
} else {
419+
set tagobjid($name) $id
420+
}
421+
set tagids($name) $id
422+
lappend idtags($id) $name
431423
} else {
432424
set otherrefids($name) $id
433425
lappend idotherrefs($id) $name
@@ -6777,14 +6769,19 @@ proc listrefs {id} {
67776769
}
67786770

67796771
proc showtag {tag isnew} {
6780-
global ctext tagcontents tagids linknum
6772+
global ctext tagcontents tagids linknum tagobjid
67816773

67826774
if {$isnew} {
67836775
addtohistory [list showtag $tag 0]
67846776
}
67856777
$ctext conf -state normal
67866778
clear_ctext
67876779
set linknum 0
6780+
if {![info exists tagcontents($tag)]} {
6781+
catch {
6782+
set tagcontents($tag) [exec git cat-file tag $tagobjid($tag)]
6783+
}
6784+
}
67886785
if {[info exists tagcontents($tag)]} {
67896786
set text $tagcontents($tag)
67906787
} else {

0 commit comments

Comments
 (0)