}
}
-proc getcommits {rargs} {
- global commits commfd phase canv mainfont env
- global startmsecs nextupdate ncmupdate
- global ctext maincursor textcursor leftover gitencoding
+proc parse_args {rargs} {
+ global parsed_args
- # check that we can find a .git directory somewhere...
- set gitdir [gitdir]
- if {![file isdirectory $gitdir]} {
- error_popup "Cannot find the git directory \"$gitdir\"."
- exit 1
- }
- set commits {}
- set phase getcommits
- set startmsecs [clock clicks -milliseconds]
- set nextupdate [expr {$startmsecs + 100}]
- set ncmupdate 1
- if [catch {
+ if {[catch {
set parse_args [concat --default HEAD $rargs]
set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
- }] {
+ }]} {
# if git-rev-parse failed for some reason...
if {$rargs == {}} {
set rargs HEAD
}
set parsed_args $rargs
}
- if [catch {
- set commfd [open "|git-rev-list --header --topo-order --parents $parsed_args" r]
- } err] {
+ return $parsed_args
+}
+
+proc start_rev_list {rlargs} {
+ global startmsecs nextupdate ncmupdate
+ global commfd leftover tclencoding
+
+ set startmsecs [clock clicks -milliseconds]
+ set nextupdate [expr {$startmsecs + 100}]
+ set ncmupdate 1
+ if {[catch {
+ set commfd [open [concat | git-rev-list --header --topo-order \
+ --parents $rlargs] r]
+ } err]} {
puts stderr "Error executing git-rev-list: $err"
exit 1
}
set leftover {}
- fconfigure $commfd -blocking 0 -translation lf -encoding $gitencoding
+ fconfigure $commfd -blocking 0 -translation lf
+ if {$tclencoding != {}} {
+ fconfigure $commfd -encoding $tclencoding
+ }
fileevent $commfd readable [list getcommitlines $commfd]
+ . config -cursor watch
+ settextcursor watch
+}
+
+proc getcommits {rargs} {
+ global oldcommits commits phase canv mainfont env
+
+ # check that we can find a .git directory somewhere...
+ set gitdir [gitdir]
+ if {![file isdirectory $gitdir]} {
+ error_popup "Cannot find the git directory \"$gitdir\"."
+ exit 1
+ }
+ set oldcommits {}
+ set commits {}
+ set phase getcommits
+ start_rev_list [parse_args $rargs]
$canv delete all
$canv create text 3 3 -anchor nw -text "Reading commits..." \
-font $mainfont -tags textitems
- . config -cursor watch
- settextcursor watch
}
proc getcommitlines {commfd} {
- global commits parents cdate children
+ global oldcommits commits parents cdate children nchildren
global commitlisted phase nextupdate
global stopped redisplaying leftover
+ global canv
set stuff [read $commfd]
if {$stuff == {}} {
lappend commits $id
set commitlisted($id) 1
parsecommit $id $cmit 1 [lrange $ids 1 end]
- drawcommit $id
+ drawcommit $id 1
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate 1
}
set stopped 0
set phase "getcommits"
foreach id $commits {
- drawcommit $id
+ drawcommit $id 1
if {$stopped} break
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate 1
}
proc readcommit {id} {
- if [catch {set contents [exec git-cat-file commit $id]}] return
+ if {[catch {set contents [exec git-cat-file commit $id]}]} return
parsecommit $id $contents 0 {}
}
-proc parsecommit {id contents listed olds} {
- global commitinfo children nchildren parents nparents cdate ncleft
+proc updatecommits {rargs} {
+ global commitlisted commfd phase
+ global startmsecs nextupdate ncmupdate
+ global idtags idheads idotherrefs
+ global leftover
+ global parsed_args
+ global canv mainfont
+ global oldcommits commits
+ global parents nchildren children ncleft
+
+ set old_args $parsed_args
+ parse_args $rargs
+
+ if {$phase == "getcommits" || $phase == "incrdraw"} {
+ # havent read all the old commits, just start again from scratch
+ stopfindproc
+ set oldcommits {}
+ set commits {}
+ foreach v {children nchildren parents commitlisted commitinfo
+ selectedline matchinglines treediffs
+ mergefilelist currentid rowtextx} {
+ global $v
+ catch {unset $v}
+ }
+ readrefs
+ if {$phase == "incrdraw"} {
+ allcanvs delete all
+ $canv create text 3 3 -anchor nw -text "Reading commits..." \
+ -font $mainfont -tags textitems
+ set phase getcommits
+ }
+ start_rev_list $parsed_args
+ return
+ }
+
+ foreach id $old_args {
+ if {![regexp {^[0-9a-f]{40}$} $id]} continue
+ if {[info exists oldref($id)]} continue
+ set oldref($id) $id
+ lappend ignoreold "^$id"
+ }
+ foreach id $parsed_args {
+ if {![regexp {^[0-9a-f]{40}$} $id]} continue
+ if {[info exists ref($id)]} continue
+ set ref($id) $id
+ lappend ignorenew "^$id"
+ }
+
+ foreach a $old_args {
+ if {![info exists ref($a)]} {
+ lappend ignorenew $a
+ }
+ }
+
+ set phase updatecommits
+ set oldcommits $commits
+ set commits {}
+ set removed_commits [split [eval exec git-rev-list $ignorenew] "\n" ]
+ if {[llength $removed_commits] > 0} {
+ allcanvs delete all
+ foreach c $removed_commits {
+ set i [lsearch -exact $oldcommits $c]
+ if {$i >= 0} {
+ set oldcommits [lreplace $oldcommits $i $i]
+ unset commitlisted($c)
+ foreach p $parents($c) {
+ if {[info exists nchildren($p)]} {
+ set j [lsearch -exact $children($p) $c]
+ if {$j >= 0} {
+ set children($p) [lreplace $children($p) $j $j]
+ incr nchildren($p) -1
+ }
+ }
+ }
+ }
+ }
+ set phase removecommits
+ }
+
+ set args {}
+ foreach a $parsed_args {
+ if {![info exists oldref($a)]} {
+ lappend args $a
+ }
+ }
+
+ readrefs
+ start_rev_list [concat $ignoreold $args]
+}
+
+proc updatechildren {id olds} {
+ global children nchildren parents nparents ncleft
- set inhdr 1
- set comment {}
- set headline {}
- set auname {}
- set audate {}
- set comname {}
- set comdate {}
if {![info exists nchildren($id)]} {
set children($id) {}
set nchildren($id) 0
incr ncleft($p)
}
}
+}
+
+proc parsecommit {id contents listed olds} {
+ global commitinfo cdate
+
+ set inhdr 1
+ set comment {}
+ set headline {}
+ set auname {}
+ set audate {}
+ set comname {}
+ set comdate {}
+ updatechildren $id $olds
set hdrend [string first "\n\n" $contents]
if {$hdrend < 0} {
# should never happen...
global tagids idtags headids idheads tagcontents
global otherrefids idotherrefs
+ foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
+ catch {unset $v}
+ }
set refd [open [list | git-ls-remote [gitdir]] r]
while {0 <= [set n [gets $refd line]]} {
if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
tkwait window $w
}
-proc makewindow {} {
+proc makewindow {rargs} {
global canv canv2 canv3 linespc charspc ctext cflist textfont
global findtype findtypemenu findloc findstring fstring geometry
global entries sha1entry sha1string sha1but
menu .bar
.bar add cascade -label "File" -menu .bar.file
menu .bar.file
+ .bar.file add command -label "Update" -command [list updatecommits $rargs]
.bar.file add command -label "Reread references" -command rereadrefs
.bar.file add command -label "Quit" -command doquit
menu .bar.edit
$ctext tag conf m2 -fore green
$ctext tag conf m3 -fore purple
$ctext tag conf m4 -fore brown
+ $ctext tag conf m5 -fore "#009090"
+ $ctext tag conf m6 -fore magenta
+ $ctext tag conf m7 -fore "#808000"
+ $ctext tag conf m8 -fore "#009000"
+ $ctext tag conf m9 -fore "#ff0080"
+ $ctext tag conf m10 -fore cyan
+ $ctext tag conf m11 -fore "#b07070"
+ $ctext tag conf m12 -fore "#70b0f0"
+ $ctext tag conf m13 -fore "#70f0b0"
+ $ctext tag conf m14 -fore "#f0b070"
+ $ctext tag conf m15 -fore "#ff70b0"
$ctext tag conf mmax -fore darkgrey
- set mergemax 5
+ set mergemax 16
$ctext tag conf mresult -font [concat $textfont bold]
$ctext tag conf msep -font [concat $textfont bold]
$ctext tag conf found -back yellow
proc resizeclistpanes {win w} {
global oldwidth
- if [info exists oldwidth($win)] {
+ if {[info exists oldwidth($win)]} {
set s0 [$win sash coord 0]
set s1 [$win sash coord 1]
if {$w < 60} {
proc resizecdetpanes {win w} {
global oldwidth
- if [info exists oldwidth($win)] {
+ if {[info exists oldwidth($win)]} {
set s0 [$win sash coord 0]
if {$w < 60} {
set sash0 [expr {int($w*3/4 - 2)}]
global parents nparents children nchildren
global cornercrossings crossings
- if [info exists colormap($id)] return
+ if {[info exists colormap($id)]} return
set ncolors [llength $colors]
if {$nparents($id) <= 1 && $nchildren($id) == 1} {
set child [lindex $children($id) 0]
proc initgraph {} {
global canvy canvy0 lineno numcommits nextcolor linespc
- global mainline mainlinearrow sidelines
global nchildren ncleft
global displist nhyperspace
set canvy $canvy0
set lineno -1
set numcommits 0
- catch {unset mainline}
- catch {unset mainlinearrow}
- catch {unset sidelines}
+ foreach v {mainline mainlinearrow sidelines colormap cornercrossings
+ crossings idline lineid} {
+ global $v
+ catch {unset $v}
+ }
foreach id [array names nchildren] {
set ncleft($id) $nchildren($id)
}
}
}
}
- if {$level < 0} {
- if {$todo != {}} {
- puts "ERROR: none of the pending commits can be done yet:"
- foreach p $todo {
- puts " $p ($ncleft($p))"
- }
- }
- return -1
- }
return $level
}
-proc drawcommit {id} {
- global phase todo nchildren datemode nextupdate revlistorder
+proc drawcommit {id reading} {
+ global phase todo nchildren datemode nextupdate revlistorder ncleft
global numcommits ncmupdate displayorder todo onscreen parents
+ global commitlisted commitordered
if {$phase != "incrdraw"} {
set phase incrdraw
set displayorder {}
set todo {}
initgraph
+ catch {unset commitordered}
}
+ set commitordered($id) 1
if {$nchildren($id) == 0} {
lappend todo $id
set onscreen($id) 0
updatetodo $level 0
} else {
set level [decidenext 1]
- if {$level == {} || $id != [lindex $todo $level]} {
- return
- }
+ if {$level == {} || $level < 0} return
while 1 {
+ set id [lindex $todo $level]
+ if {![info exists commitordered($id)]} {
+ break
+ }
lappend displayorder [lindex $todo $level]
if {[updatetodo $level $datemode]} {
set level [decidenext 1]
- if {$level == {}} break
- }
- set id [lindex $todo $level]
- if {![info exists commitlisted($id)]} {
- break
+ if {$level == {} || $level < 0} break
}
}
}
- drawmore 1
+ drawmore $reading
}
proc finishcommits {} {
- global phase
+ global phase oldcommits commits
global canv mainfont ctext maincursor textcursor
+ global parents displayorder todo
- if {$phase != "incrdraw"} {
+ if {$phase == "incrdraw" || $phase == "removecommits"} {
+ foreach id $oldcommits {
+ lappend commits $id
+ drawcommit $id 0
+ }
+ set oldcommits {}
+ drawrest
+ } elseif {$phase == "updatecommits"} {
+ # there were no new commits, in fact
+ set commits $oldcommits
+ set oldcommits {}
+ set phase {}
+ } else {
$canv delete all
$canv create text 3 3 -anchor nw -text "No commits selected" \
-font $mainfont -tags textitems
set phase {}
- } else {
- drawrest
}
. config -cursor $maincursor
settextcursor $textcursor
proc drawrest {} {
global phase stopped redisplaying selectedline
- global datemode todo displayorder
+ global datemode todo displayorder ncleft
global numcommits ncmupdate
global nextupdate startmsecs revlistorder
}
}
}
+ if {$todo != {}} {
+ puts "ERROR: none of the pending commits can be done yet:"
+ foreach p $todo {
+ puts " $p ($ncleft($p))"
+ }
+ }
+
drawmore 0
set phase {}
set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
global selectedline numcommits lineid ctext
global ffileline finddidsel parents nparents
global findinprogress findstartline findinsertpos
- global treediffs fdiffids fdiffsneeded fdiffpos
+ global treediffs fdiffid fdiffsneeded fdiffpos
global findmergefiles
if {$numcommits == 0} return
while 1 {
set id $lineid($l)
if {$findmergefiles || $nparents($id) == 1} {
- foreach p $parents($id) {
- if {![info exists treediffs([list $id $p])]} {
- append diffsneeded "$id $p\n"
- lappend fdiffsneeded [list $id $p]
- }
+ if {![info exists treediffs($id)]} {
+ append diffsneeded "$id\n"
+ lappend fdiffsneeded $id
}
}
if {[incr l] >= $numcommits} {
error_popup "Error starting search process: $err"
return
}
- catch {unset fdiffids}
+ catch {unset fdiffid}
set fdiffpos 0
fconfigure $df -blocking 0
fileevent $df readable [list readfilediffs $df]
set finddidsel 0
set findinsertpos end
set id $lineid($l)
- set p [lindex $parents($id) 0]
. config -cursor watch
settextcursor watch
set findinprogress 1
- findcont [list $id $p]
+ findcont $id
update
}
proc readfilediffs {df} {
- global findids fdiffids fdiffs
+ global findid fdiffid fdiffs
set n [gets $df line]
if {$n < 0} {
stopfindproc
bell
error_popup "Error in git-diff-tree: $err"
- } elseif {[info exists findids]} {
- set ids $findids
+ } elseif {[info exists findid]} {
+ set id $findid
stopfindproc
bell
- error_popup "Couldn't find diffs for {$ids}"
+ error_popup "Couldn't find diffs for $id"
}
}
return
}
- if {[regexp {^([0-9a-f]{40}) \(from ([0-9a-f]{40})\)} $line match id p]} {
+ if {[regexp {^([0-9a-f]{40})$} $line match id]} {
# start of a new string of diffs
donefilediff
- set fdiffids [list $id $p]
+ set fdiffid $id
set fdiffs {}
} elseif {[string match ":*" $line]} {
lappend fdiffs [lindex $line 5]
}
proc donefilediff {} {
- global fdiffids fdiffs treediffs findids
+ global fdiffid fdiffs treediffs findid
global fdiffsneeded fdiffpos
- if {[info exists fdiffids]} {
- while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffids
+ if {[info exists fdiffid]} {
+ while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffid
&& $fdiffpos < [llength $fdiffsneeded]} {
# git-diff-tree doesn't output anything for a commit
# which doesn't change anything
- set nullids [lindex $fdiffsneeded $fdiffpos]
- set treediffs($nullids) {}
- if {[info exists findids] && $nullids eq $findids} {
- unset findids
- findcont $nullids
+ set nullid [lindex $fdiffsneeded $fdiffpos]
+ set treediffs($nullid) {}
+ if {[info exists findid] && $nullid eq $findid} {
+ unset findid
+ findcont $nullid
}
incr fdiffpos
}
incr fdiffpos
- if {![info exists treediffs($fdiffids)]} {
- set treediffs($fdiffids) $fdiffs
+ if {![info exists treediffs($fdiffid)]} {
+ set treediffs($fdiffid) $fdiffs
}
- if {[info exists findids] && $fdiffids eq $findids} {
- unset findids
- findcont $fdiffids
+ if {[info exists findid] && $fdiffid eq $findid} {
+ unset findid
+ findcont $fdiffid
}
}
}
-proc findcont {ids} {
- global findids treediffs parents nparents
+proc findcont {id} {
+ global findid treediffs parents nparents
global ffileline findstartline finddidsel
global lineid numcommits matchinglines findinprogress
global findmergefiles
- set id [lindex $ids 0]
- set p [lindex $ids 1]
- set pi [lsearch -exact $parents($id) $p]
set l $ffileline
while 1 {
if {$findmergefiles || $nparents($id) == 1} {
- if {![info exists treediffs($ids)]} {
- set findids $ids
+ if {![info exists treediffs($id)]} {
+ set findid $id
set ffileline $l
return
}
set doesmatch 0
- foreach f $treediffs($ids) {
+ foreach f $treediffs($id) {
set x [findmatches $f]
if {$x != {}} {
set doesmatch 1
}
if {$doesmatch} {
insertmatch $l $id
- set pi $nparents($id)
}
- } else {
- set pi $nparents($id)
}
- if {[incr pi] >= $nparents($id)} {
- set pi 0
- if {[incr l] >= $numcommits} {
- set l 0
- }
- if {$l == $findstartline} break
- set id $lineid($l)
+ if {[incr l] >= $numcommits} {
+ set l 0
}
- set p [lindex $parents($id) $pi]
- set ids [list $id $p]
+ if {$l == $findstartline} break
+ set id $lineid($l)
}
stopfindproc
if {!$finddidsel} {
global canvy0 linespc parents nparents children
global cflist currentid sha1entry
global commentend idtags idline linknum
+ global mergemax
$canv delete hover
normalline
}
set comment {}
- if {[info exists parents($id)]} {
+ if {$nparents($id) > 1} {
+ set np 0
foreach p $parents($id) {
- append comment "Parent: [commit_descriptor $p]\n"
+ if {$np >= $mergemax} {
+ set tag mmax
+ } else {
+ set tag m$np
+ }
+ $ctext insert end "Parent: " $tag
+ appendwithlinks [commit_descriptor $p]
+ incr np
+ }
+ } else {
+ if {[info exists parents($id)]} {
+ foreach p $parents($id) {
+ append comment "Parent: [commit_descriptor $p]\n"
+ }
}
}
+
if {[info exists children($id)]} {
foreach c $children($id) {
append comment "Child: [commit_descriptor $c]\n"
}
proc mergediff {id} {
- global parents diffmergeid diffmergegca mergefilelist diffpindex
+ global parents diffmergeid diffopts mdifffd
+ global difffilestart
set diffmergeid $id
- set diffpindex -1
- set diffmergegca [findgca $parents($id)]
- if {[info exists mergefilelist($id)]} {
- if {$mergefilelist($id) ne {}} {
- showmergediff
- }
- } else {
- contmergediff {}
- }
-}
-
-proc findgca {ids} {
- set gca {}
- foreach id $ids {
- if {$gca eq {}} {
- set gca $id
- } else {
- if {[catch {
- set gca [exec git-merge-base $gca $id]
- } err]} {
- return {}
- }
- }
- }
- return $gca
-}
-
-proc contmergediff {ids} {
- global diffmergeid diffpindex parents nparents diffmergegca
- global treediffs mergefilelist diffids treepending
-
- # diff the child against each of the parents, and diff
- # each of the parents against the GCA.
- while 1 {
- if {[lindex $ids 1] == $diffmergeid && $diffmergegca ne {}} {
- set ids [list $diffmergegca [lindex $ids 0]]
- } else {
- if {[incr diffpindex] >= $nparents($diffmergeid)} break
- set p [lindex $parents($diffmergeid) $diffpindex]
- set ids [list $p $diffmergeid]
- }
- if {![info exists treediffs($ids)]} {
- set diffids $ids
- if {![info exists treepending]} {
- gettreediffs $ids
- }
- return
- }
- }
-
- # If a file in some parent is different from the child and also
- # different from the GCA, then it's interesting.
- # If we don't have a GCA, then a file is interesting if it is
- # different from the child in all the parents.
- if {$diffmergegca ne {}} {
- set files {}
- foreach p $parents($diffmergeid) {
- set gcadiffs $treediffs([list $diffmergegca $p])
- foreach f $treediffs([list $p $diffmergeid]) {
- if {[lsearch -exact $files $f] < 0
- && [lsearch -exact $gcadiffs $f] >= 0} {
- lappend files $f
- }
- }
- }
- set files [lsort $files]
- } else {
- set p [lindex $parents($diffmergeid) 0]
- set files $treediffs([list $diffmergeid $p])
- for {set i 1} {$i < $nparents($diffmergeid) && $files ne {}} {incr i} {
- set p [lindex $parents($diffmergeid) $i]
- set df $treediffs([list $p $diffmergeid])
- set nf {}
- foreach f $files {
- if {[lsearch -exact $df $f] >= 0} {
- lappend nf $f
- }
- }
- set files $nf
- }
- }
-
- set mergefilelist($diffmergeid) $files
- if {$files ne {}} {
- showmergediff
- }
-}
-
-proc showmergediff {} {
- global cflist diffmergeid mergefilelist parents
- global diffopts diffinhunk currentfile currenthunk filelines
- global diffblocked groupfilelast mergefds groupfilenum grouphunks
-
- set files $mergefilelist($diffmergeid)
- foreach f $files {
- $cflist insert end $f
- }
+ catch {unset difffilestart}
+ # this doesn't seem to actually affect anything...
set env(GIT_DIFF_OPTS) $diffopts
- set flist {}
- catch {unset currentfile}
- catch {unset currenthunk}
- catch {unset filelines}
- catch {unset groupfilenum}
- catch {unset grouphunks}
- set groupfilelast -1
- foreach p $parents($diffmergeid) {
- set cmd [list | git-diff-tree -p $p $diffmergeid]
- set cmd [concat $cmd $mergefilelist($diffmergeid)]
- if {[catch {set f [open $cmd r]} err]} {
- error_popup "Error getting diffs: $err"
- foreach f $flist {
- catch {close $f}
- }
- return
- }
- lappend flist $f
- set ids [list $diffmergeid $p]
- set mergefds($ids) $f
- set diffinhunk($ids) 0
- set diffblocked($ids) 0
- fconfigure $f -blocking 0
- fileevent $f readable [list getmergediffline $f $ids $diffmergeid]
+ set cmd [concat | git-diff-tree --no-commit-id --cc $id]
+ if {[catch {set mdf [open $cmd r]} err]} {
+ error_popup "Error getting merge diffs: $err"
+ return
}
+ fconfigure $mdf -blocking 0
+ set mdifffd($id) $mdf
+ fileevent $mdf readable [list getmergediffline $mdf $id]
+ set nextupdate [expr {[clock clicks -milliseconds] + 100}]
}
-proc getmergediffline {f ids id} {
- global diffmergeid diffinhunk diffoldlines diffnewlines
- global currentfile currenthunk
- global diffoldstart diffnewstart diffoldlno diffnewlno
- global diffblocked mergefilelist
- global noldlines nnewlines difflcounts filelines
+proc getmergediffline {mdf id} {
+ global diffmergeid ctext cflist nextupdate nparents mergemax
+ global difffilestart
- set n [gets $f line]
+ set n [gets $mdf line]
if {$n < 0} {
- if {![eof $f]} return
- }
-
- if {!([info exists diffmergeid] && $diffmergeid == $id)} {
- if {$n < 0} {
- close $f
+ if {[eof $mdf]} {
+ close $mdf
}
return
}
-
- if {$diffinhunk($ids) != 0} {
- set fi $currentfile($ids)
- if {$n > 0 && [regexp {^[-+ \\]} $line match]} {
- # continuing an existing hunk
- set line [string range $line 1 end]
- set p [lindex $ids 1]
- if {$match eq "-" || $match eq " "} {
- set filelines($p,$fi,$diffoldlno($ids)) $line
- incr diffoldlno($ids)
- }
- if {$match eq "+" || $match eq " "} {
- set filelines($id,$fi,$diffnewlno($ids)) $line
- incr diffnewlno($ids)
- }
- if {$match eq " "} {
- if {$diffinhunk($ids) == 2} {
- lappend difflcounts($ids) \
- [list $noldlines($ids) $nnewlines($ids)]
- set noldlines($ids) 0
- set diffinhunk($ids) 1
- }
- incr noldlines($ids)
- } elseif {$match eq "-" || $match eq "+"} {
- if {$diffinhunk($ids) == 1} {
- lappend difflcounts($ids) [list $noldlines($ids)]
- set noldlines($ids) 0
- set nnewlines($ids) 0
- set diffinhunk($ids) 2
- }
- if {$match eq "-"} {
- incr noldlines($ids)
- } else {
- incr nnewlines($ids)
- }
- }
- # and if it's \ No newline at end of line, then what?
- return
- }
- # end of a hunk
- if {$diffinhunk($ids) == 1 && $noldlines($ids) != 0} {
- lappend difflcounts($ids) [list $noldlines($ids)]
- } elseif {$diffinhunk($ids) == 2
- && ($noldlines($ids) != 0 || $nnewlines($ids) != 0)} {
- lappend difflcounts($ids) [list $noldlines($ids) $nnewlines($ids)]
- }
- set currenthunk($ids) [list $currentfile($ids) \
- $diffoldstart($ids) $diffnewstart($ids) \
- $diffoldlno($ids) $diffnewlno($ids) \
- $difflcounts($ids)]
- set diffinhunk($ids) 0
- # -1 = need to block, 0 = unblocked, 1 = is blocked
- set diffblocked($ids) -1
- processhunks
- if {$diffblocked($ids) == -1} {
- fileevent $f readable {}
- set diffblocked($ids) 1
- }
- }
-
- if {$n < 0} {
- # eof
- if {!$diffblocked($ids)} {
- close $f
- set currentfile($ids) [llength $mergefilelist($diffmergeid)]
- set currenthunk($ids) [list $currentfile($ids) 0 0 0 0 {}]
- processhunks
- }
- } elseif {[regexp {^diff --git a/(.*) b/} $line match fname]} {
- # start of a new file
- set currentfile($ids) \
- [lsearch -exact $mergefilelist($diffmergeid) $fname]
- } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
- $line match f1l f1c f2l f2c rest]} {
- if {[info exists currentfile($ids)] && $currentfile($ids) >= 0} {
- # start of a new hunk
- if {$f1l == 0 && $f1c == 0} {
- set f1l 1
- }
- if {$f2l == 0 && $f2c == 0} {
- set f2l 1
- }
- set diffinhunk($ids) 1
- set diffoldstart($ids) $f1l
- set diffnewstart($ids) $f2l
- set diffoldlno($ids) $f1l
- set diffnewlno($ids) $f2l
- set difflcounts($ids) {}
- set noldlines($ids) 0
- set nnewlines($ids) 0
- }
- }
-}
-
-proc processhunks {} {
- global diffmergeid parents nparents currenthunk
- global mergefilelist diffblocked mergefds
- global grouphunks grouplinestart grouplineend groupfilenum
-
- set nfiles [llength $mergefilelist($diffmergeid)]
- while 1 {
- set fi $nfiles
- set lno 0
- # look for the earliest hunk
- foreach p $parents($diffmergeid) {
- set ids [list $diffmergeid $p]
- if {![info exists currenthunk($ids)]} return
- set i [lindex $currenthunk($ids) 0]
- set l [lindex $currenthunk($ids) 2]
- if {$i < $fi || ($i == $fi && $l < $lno)} {
- set fi $i
- set lno $l
- set pi $p
- }
- }
-
- if {$fi < $nfiles} {
- set ids [list $diffmergeid $pi]
- set hunk $currenthunk($ids)
- unset currenthunk($ids)
- if {$diffblocked($ids) > 0} {
- fileevent $mergefds($ids) readable \
- [list getmergediffline $mergefds($ids) $ids $diffmergeid]
- }
- set diffblocked($ids) 0
-
- if {[info exists groupfilenum] && $groupfilenum == $fi
- && $lno <= $grouplineend} {
- # add this hunk to the pending group
- lappend grouphunks($pi) $hunk
- set endln [lindex $hunk 4]
- if {$endln > $grouplineend} {
- set grouplineend $endln
- }
- continue
- }
- }
-
- # succeeding stuff doesn't belong in this group, so
- # process the group now
- if {[info exists groupfilenum]} {
- processgroup
- unset groupfilenum
- unset grouphunks
- }
-
- if {$fi >= $nfiles} break
-
- # start a new group
- set groupfilenum $fi
- set grouphunks($pi) [list $hunk]
- set grouplinestart $lno
- set grouplineend [lindex $hunk 4]
+ if {![info exists diffmergeid] || $id != $diffmergeid} {
+ return
}
-}
-
-proc processgroup {} {
- global groupfilelast groupfilenum difffilestart
- global mergefilelist diffmergeid ctext filelines
- global parents diffmergeid diffoffset
- global grouphunks grouplinestart grouplineend nparents
- global mergemax
-
$ctext conf -state normal
- set id $diffmergeid
- set f $groupfilenum
- if {$groupfilelast != $f} {
+ if {[regexp {^diff --cc (.*)} $line match fname]} {
+ # start of a new file
$ctext insert end "\n"
set here [$ctext index "end - 1c"]
- set difffilestart($f) $here
- set mark fmark.[expr {$f + 1}]
- $ctext mark set $mark $here
- $ctext mark gravity $mark left
- set header [lindex $mergefilelist($id) $f]
- set l [expr {(78 - [string length $header]) / 2}]
+ set i [$cflist index end]
+ $ctext mark set fmark.$i $here
+ $ctext mark gravity fmark.$i left
+ set difffilestart([expr {$i-1}]) $here
+ $cflist insert end $fname
+ set l [expr {(78 - [string length $fname]) / 2}]
set pad [string range "----------------------------------------" 1 $l]
- $ctext insert end "$pad $header $pad\n" filesep
- set groupfilelast $f
- foreach p $parents($id) {
- set diffoffset($p) 0
- }
- }
-
- $ctext insert end "@@" msep
- set nlines [expr {$grouplineend - $grouplinestart}]
- set events {}
- set pnum 0
- foreach p $parents($id) {
- set startline [expr {$grouplinestart + $diffoffset($p)}]
- set ol $startline
- set nl $grouplinestart
- if {[info exists grouphunks($p)]} {
- foreach h $grouphunks($p) {
- set l [lindex $h 2]
- if {$nl < $l} {
- for {} {$nl < $l} {incr nl} {
- set filelines($p,$f,$ol) $filelines($id,$f,$nl)
- incr ol
- }
- }
- foreach chunk [lindex $h 5] {
- if {[llength $chunk] == 2} {
- set olc [lindex $chunk 0]
- set nlc [lindex $chunk 1]
- set nnl [expr {$nl + $nlc}]
- lappend events [list $nl $nnl $pnum $olc $nlc]
- incr ol $olc
- set nl $nnl
- } else {
- incr ol [lindex $chunk 0]
- incr nl [lindex $chunk 0]
- }
- }
- }
- }
- if {$nl < $grouplineend} {
- for {} {$nl < $grouplineend} {incr nl} {
- set filelines($p,$f,$ol) $filelines($id,$f,$nl)
- incr ol
- }
- }
- set nlines [expr {$ol - $startline}]
- $ctext insert end " -$startline,$nlines" msep
- incr pnum
- }
-
- set nlines [expr {$grouplineend - $grouplinestart}]
- $ctext insert end " +$grouplinestart,$nlines @@\n" msep
-
- set events [lsort -integer -index 0 $events]
- set nevents [llength $events]
- set nmerge $nparents($diffmergeid)
- set l $grouplinestart
- for {set i 0} {$i < $nevents} {set i $j} {
- set nl [lindex $events $i 0]
- while {$l < $nl} {
- $ctext insert end " $filelines($id,$f,$l)\n"
- incr l
- }
- set e [lindex $events $i]
- set enl [lindex $e 1]
- set j $i
- set active {}
- while 1 {
- set pnum [lindex $e 2]
- set olc [lindex $e 3]
- set nlc [lindex $e 4]
- if {![info exists delta($pnum)]} {
- set delta($pnum) [expr {$olc - $nlc}]
- lappend active $pnum
+ $ctext insert end "$pad $fname $pad\n" filesep
+ } elseif {[regexp {^@@} $line]} {
+ $ctext insert end "$line\n" hunksep
+ } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
+ # do nothing
+ } else {
+ # parse the prefix - one ' ', '-' or '+' for each parent
+ set np $nparents($id)
+ set spaces {}
+ set minuses {}
+ set pluses {}
+ set isbad 0
+ for {set j 0} {$j < $np} {incr j} {
+ set c [string range $line $j $j]
+ if {$c == " "} {
+ lappend spaces $j
+ } elseif {$c == "-"} {
+ lappend minuses $j
+ } elseif {$c == "+"} {
+ lappend pluses $j
} else {
- incr delta($pnum) [expr {$olc - $nlc}]
- }
- if {[incr j] >= $nevents} break
- set e [lindex $events $j]
- if {[lindex $e 0] >= $enl} break
- if {[lindex $e 1] > $enl} {
- set enl [lindex $e 1]
- }
- }
- set nlc [expr {$enl - $l}]
- set ncol mresult
- set bestpn -1
- if {[llength $active] == $nmerge - 1} {
- # no diff for one of the parents, i.e. it's identical
- for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
- if {![info exists delta($pnum)]} {
- if {$pnum < $mergemax} {
- lappend ncol m$pnum
- } else {
- lappend ncol mmax
- }
- break
- }
- }
- } elseif {[llength $active] == $nmerge} {
- # all parents are different, see if one is very similar
- set bestsim 30
- for {set pnum 0} {$pnum < $nmerge} {incr pnum} {
- set sim [similarity $pnum $l $nlc $f \
- [lrange $events $i [expr {$j-1}]]]
- if {$sim > $bestsim} {
- set bestsim $sim
- set bestpn $pnum
- }
- }
- if {$bestpn >= 0} {
- lappend ncol m$bestpn
+ set isbad 1
+ break
}
}
- set pnum -1
- foreach p $parents($id) {
- incr pnum
- if {![info exists delta($pnum)] || $pnum == $bestpn} continue
- set olc [expr {$nlc + $delta($pnum)}]
- set ol [expr {$l + $diffoffset($p)}]
- incr diffoffset($p) $delta($pnum)
- unset delta($pnum)
- for {} {$olc > 0} {incr olc -1} {
- $ctext insert end "-$filelines($p,$f,$ol)\n" m$pnum
- incr ol
- }
- }
- set endl [expr {$l + $nlc}]
- if {$bestpn >= 0} {
- # show this pretty much as a normal diff
- set p [lindex $parents($id) $bestpn]
- set ol [expr {$l + $diffoffset($p)}]
- incr diffoffset($p) $delta($bestpn)
- unset delta($bestpn)
- for {set k $i} {$k < $j} {incr k} {
- set e [lindex $events $k]
- if {[lindex $e 2] != $bestpn} continue
- set nl [lindex $e 0]
- set ol [expr {$ol + $nl - $l}]
- for {} {$l < $nl} {incr l} {
- $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
- }
- set c [lindex $e 3]
- for {} {$c > 0} {incr c -1} {
- $ctext insert end "-$filelines($p,$f,$ol)\n" m$bestpn
- incr ol
- }
- set nl [lindex $e 1]
- for {} {$l < $nl} {incr l} {
- $ctext insert end "+$filelines($id,$f,$l)\n" mresult
- }
- }
+ set tags {}
+ set num {}
+ if {!$isbad && $minuses ne {} && $pluses eq {}} {
+ # line doesn't appear in result, parents in $minuses have the line
+ set num [lindex $minuses 0]
+ } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
+ # line appears in result, parents in $pluses don't have the line
+ lappend tags mresult
+ set num [lindex $spaces 0]
}
- for {} {$l < $endl} {incr l} {
- $ctext insert end "+$filelines($id,$f,$l)\n" $ncol
+ if {$num ne {}} {
+ if {$num >= $mergemax} {
+ set num "max"
+ }
+ lappend tags m$num
}
- }
- while {$l < $grouplineend} {
- $ctext insert end " $filelines($id,$f,$l)\n"
- incr l
+ $ctext insert end "$line\n" $tags
}
$ctext conf -state disabled
-}
-
-proc similarity {pnum l nlc f events} {
- global diffmergeid parents diffoffset filelines
-
- set id $diffmergeid
- set p [lindex $parents($id) $pnum]
- set ol [expr {$l + $diffoffset($p)}]
- set endl [expr {$l + $nlc}]
- set same 0
- set diff 0
- foreach e $events {
- if {[lindex $e 2] != $pnum} continue
- set nl [lindex $e 0]
- set ol [expr {$ol + $nl - $l}]
- for {} {$l < $nl} {incr l} {
- incr same [string length $filelines($id,$f,$l)]
- incr same
- }
- set oc [lindex $e 3]
- for {} {$oc > 0} {incr oc -1} {
- incr diff [string length $filelines($p,$f,$ol)]
- incr diff
- incr ol
- }
- set nl [lindex $e 1]
- for {} {$l < $nl} {incr l} {
- incr diff [string length $filelines($id,$f,$l)]
- incr diff
- }
- }
- for {} {$l < $endl} {incr l} {
- incr same [string length $filelines($id,$f,$l)]
- incr same
- }
- if {$same == 0} {
- return 0
+ if {[clock clicks -milliseconds] >= $nextupdate} {
+ incr nextupdate 100
+ fileevent $mdf readable {}
+ update
+ fileevent $mdf readable [list getmergediffline $mdf $id]
}
- return [expr {200 * $same / (2 * $same + $diff)}]
}
proc startdiff {ids} {
global treediff parents treepending
set treepending $ids
set treediff {}
- if [catch {set gdtf [open [concat | git-diff-tree --no-commit-id -r $ids] r]}] return
+ if {[catch \
+ {set gdtf [open [concat | git-diff-tree --no-commit-id -r $ids] r]} \
+ ]} return
fconfigure $gdtf -blocking 0
fileevent $gdtf readable [list gettreediffline $gdtf $ids]
}
set ref($id) [listrefs $id]
}
}
- foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
- catch {unset $v}
- }
readrefs
set refids [lsort -unique [concat $refids [array names idtags] \
[array names idheads] [array names idotherrefs]]]
return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
}
+# This list of encoding names and aliases is distilled from
+# http://www.iana.org/assignments/character-sets.
+# Not all of them are supported by Tcl.
+set encoding_aliases {
+ { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
+ ISO646-US US-ASCII us IBM367 cp367 csASCII }
+ { ISO-10646-UTF-1 csISO10646UTF1 }
+ { ISO_646.basic:1983 ref csISO646basic1983 }
+ { INVARIANT csINVARIANT }
+ { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
+ { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
+ { NATS-SEFI iso-ir-8-1 csNATSSEFI }
+ { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
+ { NATS-DANO iso-ir-9-1 csNATSDANO }
+ { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
+ { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
+ { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
+ { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
+ { ISO-2022-KR csISO2022KR }
+ { EUC-KR csEUCKR }
+ { ISO-2022-JP csISO2022JP }
+ { ISO-2022-JP-2 csISO2022JP2 }
+ { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
+ csISO13JISC6220jp }
+ { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
+ { IT iso-ir-15 ISO646-IT csISO15Italian }
+ { PT iso-ir-16 ISO646-PT csISO16Portuguese }
+ { ES iso-ir-17 ISO646-ES csISO17Spanish }
+ { greek7-old iso-ir-18 csISO18Greek7Old }
+ { latin-greek iso-ir-19 csISO19LatinGreek }
+ { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
+ { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
+ { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
+ { ISO_5427 iso-ir-37 csISO5427Cyrillic }
+ { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
+ { BS_viewdata iso-ir-47 csISO47BSViewdata }
+ { INIS iso-ir-49 csISO49INIS }
+ { INIS-8 iso-ir-50 csISO50INIS8 }
+ { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
+ { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
+ { ISO_5428:1980 iso-ir-55 csISO5428Greek }
+ { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
+ { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
+ { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
+ csISO60Norwegian1 }
+ { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
+ { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
+ { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
+ { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
+ { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
+ { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
+ { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
+ { greek7 iso-ir-88 csISO88Greek7 }
+ { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
+ { iso-ir-90 csISO90 }
+ { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
+ { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
+ csISO92JISC62991984b }
+ { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
+ { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
+ { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
+ csISO95JIS62291984handadd }
+ { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
+ { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
+ { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
+ { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
+ CP819 csISOLatin1 }
+ { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
+ { T.61-7bit iso-ir-102 csISO102T617bit }
+ { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
+ { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
+ { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
+ { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
+ { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
+ { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
+ { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
+ { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
+ arabic csISOLatinArabic }
+ { ISO_8859-6-E csISO88596E ISO-8859-6-E }
+ { ISO_8859-6-I csISO88596I ISO-8859-6-I }
+ { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
+ greek greek8 csISOLatinGreek }
+ { T.101-G2 iso-ir-128 csISO128T101G2 }
+ { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
+ csISOLatinHebrew }
+ { ISO_8859-8-E csISO88598E ISO-8859-8-E }
+ { ISO_8859-8-I csISO88598I ISO-8859-8-I }
+ { CSN_369103 iso-ir-139 csISO139CSN369103 }
+ { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
+ { ISO_6937-2-add iso-ir-142 csISOTextComm }
+ { IEC_P27-1 iso-ir-143 csISO143IECP271 }
+ { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
+ csISOLatinCyrillic }
+ { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
+ { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
+ { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
+ { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
+ { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
+ { ISO_6937-2-25 iso-ir-152 csISO6937Add }
+ { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
+ { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
+ { ISO_10367-box iso-ir-155 csISO10367Box }
+ { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
+ { latin-lap lap iso-ir-158 csISO158Lap }
+ { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
+ { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
+ { us-dk csUSDK }
+ { dk-us csDKUS }
+ { JIS_X0201 X0201 csHalfWidthKatakana }
+ { KSC5636 ISO646-KR csKSC5636 }
+ { ISO-10646-UCS-2 csUnicode }
+ { ISO-10646-UCS-4 csUCS4 }
+ { DEC-MCS dec csDECMCS }
+ { hp-roman8 roman8 r8 csHPRoman8 }
+ { macintosh mac csMacintosh }
+ { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
+ csIBM037 }
+ { IBM038 EBCDIC-INT cp038 csIBM038 }
+ { IBM273 CP273 csIBM273 }
+ { IBM274 EBCDIC-BE CP274 csIBM274 }
+ { IBM275 EBCDIC-BR cp275 csIBM275 }
+ { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
+ { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
+ { IBM280 CP280 ebcdic-cp-it csIBM280 }
+ { IBM281 EBCDIC-JP-E cp281 csIBM281 }
+ { IBM284 CP284 ebcdic-cp-es csIBM284 }
+ { IBM285 CP285 ebcdic-cp-gb csIBM285 }
+ { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
+ { IBM297 cp297 ebcdic-cp-fr csIBM297 }
+ { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
+ { IBM423 cp423 ebcdic-cp-gr csIBM423 }
+ { IBM424 cp424 ebcdic-cp-he csIBM424 }
+ { IBM437 cp437 437 csPC8CodePage437 }
+ { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
+ { IBM775 cp775 csPC775Baltic }
+ { IBM850 cp850 850 csPC850Multilingual }
+ { IBM851 cp851 851 csIBM851 }
+ { IBM852 cp852 852 csPCp852 }
+ { IBM855 cp855 855 csIBM855 }
+ { IBM857 cp857 857 csIBM857 }
+ { IBM860 cp860 860 csIBM860 }
+ { IBM861 cp861 861 cp-is csIBM861 }
+ { IBM862 cp862 862 csPC862LatinHebrew }
+ { IBM863 cp863 863 csIBM863 }
+ { IBM864 cp864 csIBM864 }
+ { IBM865 cp865 865 csIBM865 }
+ { IBM866 cp866 866 csIBM866 }
+ { IBM868 CP868 cp-ar csIBM868 }
+ { IBM869 cp869 869 cp-gr csIBM869 }
+ { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
+ { IBM871 CP871 ebcdic-cp-is csIBM871 }
+ { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
+ { IBM891 cp891 csIBM891 }
+ { IBM903 cp903 csIBM903 }
+ { IBM904 cp904 904 csIBBM904 }
+ { IBM905 CP905 ebcdic-cp-tr csIBM905 }
+ { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
+ { IBM1026 CP1026 csIBM1026 }
+ { EBCDIC-AT-DE csIBMEBCDICATDE }
+ { EBCDIC-AT-DE-A csEBCDICATDEA }
+ { EBCDIC-CA-FR csEBCDICCAFR }
+ { EBCDIC-DK-NO csEBCDICDKNO }
+ { EBCDIC-DK-NO-A csEBCDICDKNOA }
+ { EBCDIC-FI-SE csEBCDICFISE }
+ { EBCDIC-FI-SE-A csEBCDICFISEA }
+ { EBCDIC-FR csEBCDICFR }
+ { EBCDIC-IT csEBCDICIT }
+ { EBCDIC-PT csEBCDICPT }
+ { EBCDIC-ES csEBCDICES }
+ { EBCDIC-ES-A csEBCDICESA }
+ { EBCDIC-ES-S csEBCDICESS }
+ { EBCDIC-UK csEBCDICUK }
+ { EBCDIC-US csEBCDICUS }
+ { UNKNOWN-8BIT csUnknown8BiT }
+ { MNEMONIC csMnemonic }
+ { MNEM csMnem }
+ { VISCII csVISCII }
+ { VIQR csVIQR }
+ { KOI8-R csKOI8R }
+ { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
+ { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
+ { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
+ { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
+ { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
+ { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
+ { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
+ { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
+ { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
+ { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
+ { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
+ { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
+ { IBM1047 IBM-1047 }
+ { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
+ { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
+ { UNICODE-1-1 csUnicode11 }
+ { CESU-8 csCESU-8 }
+ { BOCU-1 csBOCU-1 }
+ { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
+ { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
+ l8 }
+ { ISO-8859-15 ISO_8859-15 Latin-9 }
+ { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
+ { GBK CP936 MS936 windows-936 }
+ { JIS_Encoding csJISEncoding }
+ { Shift_JIS MS_Kanji csShiftJIS }
+ { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
+ EUC-JP }
+ { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
+ { ISO-10646-UCS-Basic csUnicodeASCII }
+ { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
+ { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
+ { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
+ { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
+ { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
+ { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
+ { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
+ { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
+ { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
+ { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
+ { Adobe-Standard-Encoding csAdobeStandardEncoding }
+ { Ventura-US csVenturaUS }
+ { Ventura-International csVenturaInternational }
+ { PC8-Danish-Norwegian csPC8DanishNorwegian }
+ { PC8-Turkish csPC8Turkish }
+ { IBM-Symbols csIBMSymbols }
+ { IBM-Thai csIBMThai }
+ { HP-Legal csHPLegal }
+ { HP-Pi-font csHPPiFont }
+ { HP-Math8 csHPMath8 }
+ { Adobe-Symbol-Encoding csHPPSMath }
+ { HP-DeskTop csHPDesktop }
+ { Ventura-Math csVenturaMath }
+ { Microsoft-Publishing csMicrosoftPublishing }
+ { Windows-31J csWindows31J }
+ { GB2312 csGB2312 }
+ { Big5 csBig5 }
+}
+
+proc tcl_encoding {enc} {
+ global encoding_aliases
+ set names [encoding names]
+ set lcnames [string tolower $names]
+ set enc [string tolower $enc]
+ set i [lsearch -exact $lcnames $enc]
+ if {$i < 0} {
+ # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
+ if {[regsub {^iso[-_]} $enc iso encx]} {
+ set i [lsearch -exact $lcnames $encx]
+ }
+ }
+ if {$i < 0} {
+ foreach l $encoding_aliases {
+ set ll [string tolower $l]
+ if {[lsearch -exact $ll $enc] < 0} continue
+ # look through the aliases for one that tcl knows about
+ foreach e $ll {
+ set i [lsearch -exact $lcnames $e]
+ if {$i < 0} {
+ if {[regsub {^iso[-_]} $e iso ex]} {
+ set i [lsearch -exact $lcnames $ex]
+ }
+ }
+ if {$i >= 0} break
+ }
+ break
+ }
+ }
+ if {$i >= 0} {
+ return [lindex $names $i]
+ }
+ return {}
+}
+
# defaults...
set datemode 0
set diffopts "-U 5 -p"
set wrcomcmd "git-diff-tree --stdin -p --pretty"
-set gitencoding ""
+set gitencoding {}
catch {
set gitencoding [exec git-repo-config --get i18n.commitencoding]
}
if {$gitencoding == ""} {
- set gitencoding "utf-8"
+ set gitencoding "utf-8"
+}
+set tclencoding [tcl_encoding $gitencoding]
+if {$tclencoding == {}} {
+ puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
}
set mainfont {Helvetica 9}
set stuffsaved 0
set patchnum 0
setcoords
-makewindow
+makewindow $revtreeargs
readrefs
getcommits $revtreeargs