X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gitk;h=2aa970d5cffea4bea0e3f8f1a100f68b53e5a7af;hb=dd53c7ab297cc491eb5164198e63d670c7b48530;hp=61af6390d339b58dc2e56ce7f1577be7ede243ff;hpb=9d2a52eca1b5ea6c7beb351b45aa2aff092bbd6c;p=git.git diff --git a/gitk b/gitk index 61af6390..2aa970d5 100755 --- a/gitk +++ b/gitk @@ -7,17 +7,22 @@ exec wish "$0" -- "${1+$@}" # and distributed under the terms of the GNU General Public Licence, # either version 2, or (at your option) any later version. +proc gitdir {} { + global env + if {[info exists env(GIT_DIR)]} { + return $env(GIT_DIR) + } else { + return ".git" + } +} + proc getcommits {rargs} { global commits commfd phase canv mainfont env global startmsecs nextupdate global ctext maincursor textcursor leftover # check that we can find a .git directory somewhere... - if {[info exists env(GIT_DIR)]} { - set gitdir $env(GIT_DIR) - } else { - set gitdir ".git" - } + set gitdir [gitdir] if {![file isdirectory $gitdir]} { error_popup "Cannot find the git directory \"$gitdir\"." exit 1 @@ -37,7 +42,7 @@ proc getcommits {rargs} { set parsed_args $rargs } if [catch { - set commfd [open "|git-rev-list --header --merge-order $parsed_args" r] + set commfd [open "|git-rev-list --header --topo-order $parsed_args" r] } err] { puts stderr "Error executing git-rev-list: $err" exit 1 @@ -212,7 +217,7 @@ proc parsecommit {id contents listed} { proc readrefs {} { global tagids idtags headids idheads - set tags [glob -nocomplain -types f .git/refs/tags/*] + set tags [glob -nocomplain -types f [gitdir]/refs/tags/*] foreach f $tags { catch { set fd [open $f r] @@ -241,7 +246,7 @@ proc readrefs {} { close $fd } } - set heads [glob -nocomplain -types f .git/refs/heads/*] + set heads [glob -nocomplain -types f [gitdir]/refs/heads/*] foreach f $heads { catch { set fd [open $f r] @@ -475,7 +480,8 @@ proc click {w} { proc savestuff {w} { global canv canv2 canv3 ctext cflist mainfont textfont - global stuffsaved + global stuffsaved findmergefiles gaudydiff + if {$stuffsaved} return if {![winfo viewable .]} return catch { @@ -2048,7 +2054,6 @@ proc processgroup {} { set pnum 0 foreach p $parents($id) { set startline [expr {$grouplinestart + $diffoffset($p)}] - set offset($p) $diffoffset($p) set ol $startline set nl $grouplinestart if {[info exists grouphunks($p)]} { @@ -2092,9 +2097,8 @@ proc processgroup {} { set events [lsort -integer -index 0 $events] set nevents [llength $events] set nmerge $nparents($diffmergeid) - set i 0 set l $grouplinestart - while {$i < $nevents} { + 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" @@ -2123,7 +2127,9 @@ proc processgroup {} { } 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} { @@ -2134,11 +2140,25 @@ proc processgroup {} { 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 pnum -1 foreach p $parents($id) { incr pnum - if {![info exists delta($pnum)]} continue + 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) @@ -2148,11 +2168,35 @@ proc processgroup {} { incr ol } } - for {} {$nlc > 0} {incr nlc -1} { + 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 + } + } + } + for {} {$l < $endl} {incr l} { $ctext insert end "+$filelines($id,$f,$l)\n" $ncol - incr l } - set i $j } while {$l < $grouplineend} { $ctext insert end " $filelines($id,$f,$l)\n" @@ -2161,6 +2205,45 @@ proc processgroup {} { $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 + } + return [expr {200 * $same / (2 * $same + $diff)}] +} + proc startdiff {ids} { global treediffs diffids treepending diffmergeid @@ -2751,10 +2834,7 @@ proc domktag {} { return } if {[catch { - set dir ".git" - if {[info exists env(GIT_DIR)]} { - set dir $env(GIT_DIR) - } + set dir [gitdir] set fname [file join $dir "refs/tags" $tag] set f [open $fname w] puts $f $id