From 719c2b9d926bf2be4879015e3620d27d32f007b6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 29 Aug 2007 22:41:34 +1000 Subject: [PATCH 01/10] gitk: Fix bug causing undefined variable error when cherry-picking When "Show nearby tags" is turned off and the user did a cherry-pick, we were trying to access variables relating to the descendent/ancestor tag & head computations in addnewchild though they hadn't been set. This makes sure we don't do that. Reported by Johannes Sixt. Signed-off-by: Paul Mackerras --- gitk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gitk b/gitk index b7730ae202..300fdceb35 100755 --- a/gitk +++ b/gitk @@ -6641,8 +6641,9 @@ proc splitarc {p} { proc addnewchild {id p} { global allids allparents allchildren idtags nextarc nbmp global arcnos arcids arctags arcout arcend arcstart archeads growing - global seeds + global seeds allcommits + if {![info exists allcommits]} return lappend allids $id set allparents($id) [list $p] set allchildren($id) {} From 0166419a197cea0ceef3aed8c72023deb015ecf4 Mon Sep 17 00:00:00 2001 From: Sam Vilain Date: Wed, 17 Oct 2007 11:33:04 +1300 Subject: [PATCH 02/10] gitk: disable colours when calling git log If the user specifies 'diff.color = 1' in their configuration file, then gitk will not start. Disable colours when calling git log. Signed-off-by: Sam Vilain Signed-off-by: Shawn O. Pearce --- gitk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitk b/gitk index 300fdceb35..999e3c2188 100755 --- a/gitk +++ b/gitk @@ -92,7 +92,7 @@ proc start_rev_list {view} { set order "--date-order" } if {[catch { - set fd [open [concat | git log -z --pretty=raw $order --parents \ + set fd [open [concat | git log --no-color -z --pretty=raw $order --parents \ --boundary $viewargs($view) "--" $viewfiles($view)] r] } err]} { error_popup "Error executing git rev-list: $err" From 5dd57d512225bb82aa0010b39aaec0085d471eac Mon Sep 17 00:00:00 2001 From: Jonathan del Strother Date: Mon, 15 Oct 2007 10:33:07 +0100 Subject: [PATCH 03/10] gitk: Add support for OS X mouse wheel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (Väinö Järvelä supplied this patch a while ago for 1.5.2. It no longer applied cleanly, so I'm reposting it.) MacBook doesn't seem to recognize MouseRelease-4 and -5 events, at all. So i added a support for the MouseWheel event, which i limited to Tcl/tk aqua, as i couldn't test it neither on Linux or Windows. Tcl/tk needs to be updated from the version that is shipped with OS X 10.4 Tiger, for this patch to work. Signed-off-by: Jonathan del Strother Signed-off-by: Shawn O. Pearce --- gitk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gitk b/gitk index 999e3c2188..46673e3b9c 100755 --- a/gitk +++ b/gitk @@ -843,6 +843,12 @@ proc makewindow {} { } else { bindall "allcanvs yview scroll -5 units" bindall "allcanvs yview scroll 5 units" + if {[tk windowingsystem] eq "aqua"} { + bindall { + set delta [expr {- (%D)}] + allcanvs yview scroll $delta units + } + } } bindall <2> "canvscan mark %W %x %y" bindall "canvscan dragto %W %x %y" From 5e85ec4cd0658232fa8ee13e8cd9da21e0e4973e Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 2 Oct 2007 16:16:54 +0200 Subject: [PATCH 04/10] gitk: Do not pick up file names of "copy from" lines A file copy would be detected only if the original file was modified in the same commit. This implies that there will be a patch listed under the original file name, and we would expect that clicking the original file name in the file list warps the patch window to that file's patch. (If the original file was not modified, the copy would not be detected in the first place, the copied file would be listed as "new file", and this whole matter would not apply.) However, if the name of the copy is sorted after the original file's patch, then the logic introduced by commit d1cb298b0b (which picks up the link information from the "copy from" line) would overwrite the link information that is already present for the original file name, which was parsed earlier. Hence, this patch reverts part of said commit. Signed-off-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- gitk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gitk b/gitk index 46673e3b9c..516e14a8fc 100755 --- a/gitk +++ b/gitk @@ -5221,8 +5221,7 @@ proc getblobdiffline {bdf ids} { set diffinhdr 0 } elseif {$diffinhdr} { - if {![string compare -length 12 "rename from " $line] || - ![string compare -length 10 "copy from " $line]} { + if {![string compare -length 12 "rename from " $line]} { set fname [string range $line [expr 6 + [string first " from " $line] ] end] if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] From 5d7589d4c43e941563dfa2d096e6d6c184191702 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 20 Oct 2007 21:21:03 +1000 Subject: [PATCH 05/10] gitk: Check that we are running on at least Tcl/Tk 8.4 This checks that we have Tcl/Tk 8.4 or later, and puts up an error message in a window and quits if not. This was prompted by a patch submitted by Steffen Prohaska, but is done a bit differently (this uses package require rather than looking at [info tclversion], and uses show_error to display the error rather than printing it to stderr). Signed-off-by: Paul Mackerras --- gitk | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gitk b/gitk index 516e14a8fc..06172a434b 100755 --- a/gitk +++ b/gitk @@ -7838,6 +7838,13 @@ proc tcl_encoding {enc} { return {} } +# First check that Tcl/Tk is recent enough +if {[catch {package require Tk 8.4} err]} { + show_error {} . "Sorry, gitk cannot run with this version of Tcl/Tk.\n\ + Gitk requires at least Tcl/Tk 8.4." + exit 1 +} + # defaults... set datemode 0 set diffopts "-U 5 -p" From 3ebba3c724f77d149061c62f4414166649c2e56e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 20 Oct 2007 22:10:52 +1000 Subject: [PATCH 06/10] gitk: Avoid an error when cherry-picking if HEAD has moved on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an error reported by Adam Piątyszek: if the current HEAD is not in the graph that gitk knows about when we do a cherry-pick using gitk, then gitk hits an error when trying to update its internal representation of the topology. This avoids the error by not doing that update if the HEAD before the cherry-pick was a commit that gitk doesn't know about. Signed-off-by: Paul Mackerras --- gitk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitk b/gitk index 06172a434b..f910cba8bf 100755 --- a/gitk +++ b/gitk @@ -6648,7 +6648,7 @@ proc addnewchild {id p} { global arcnos arcids arctags arcout arcend arcstart archeads growing global seeds allcommits - if {![info exists allcommits]} return + if {![info exists allcommits] || ![info exists arcnos($p)]} return lappend allids $id set allparents($id) [list $p] set allchildren($id) {} From e5ef6f952a13342065d44bab53999e8d8529cc3b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 21 Oct 2007 12:58:42 +1000 Subject: [PATCH 07/10] gitk: Fix "can't unset prevlines(...)" Tcl error This fixes the error reported by Michele Ballabio, where gitk will throw a Tcl error "can't unset prevlines(...)" when displaying a commit that has a parent commit listed more than once, and the commit is the first child of that parent. The problem was basically that we had two variables, prevlines and lineends, and were relying on the invariant that prevlines($id) was set iff $id was in the lineends($r) list for some $r. But having a duplicate parent breaks that invariant since we end up with the parent listed twice in lineends. This fixes it by simplifying the logic to use only a single variable, lineend. It also rearranges things a little so that we don't try to draw the line for the duplicated parent twice. Signed-off-by: Paul Mackerras --- gitk | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/gitk b/gitk index f910cba8bf..41a1c69e19 100755 --- a/gitk +++ b/gitk @@ -3695,34 +3695,23 @@ proc drawcommits {row {endrow {}}} { drawcmitrow $r if {$r == $er} break set nextid [lindex $displayorder [expr {$r + 1}]] - if {$wasdrawn && [info exists iddrawn($nextid)]} { - catch {unset prevlines} - continue - } + if {$wasdrawn && [info exists iddrawn($nextid)]} continue drawparentlinks $id $r - if {[info exists lineends($r)]} { - foreach lid $lineends($r) { - unset prevlines($lid) - } - } set rowids [lindex $rowidlist $r] foreach lid $rowids { if {$lid eq {}} continue + if {[info exists lineend($lid)] && $lineend($lid) > $r} continue if {$lid eq $id} { # see if this is the first child of any of its parents foreach p [lindex $parentlist $r] { if {[lsearch -exact $rowids $p] < 0} { # make this line extend up to the child - set le [drawlineseg $p $r $er 0] - lappend lineends($le) $p - set prevlines($p) 1 + set lineend($p) [drawlineseg $p $r $er 0] } } - } elseif {![info exists prevlines($lid)]} { - set le [drawlineseg $lid $r $er 1] - lappend lineends($le) $lid - set prevlines($lid) 1 + } else { + set lineend($lid) [drawlineseg $lid $r $er 1] } } } From 7a39a17a873b818e3a4d121b3a43baf10f68cf61 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 23 Oct 2007 10:15:11 +1000 Subject: [PATCH 08/10] gitk: Limit diff display to listed paths by default When the user has specified a list of paths, either on the command line or when creating a view, gitk currently displays the diffs for all files that a commit has modified, not just the ones that match the path list. This is different from other git commands such as git log. This change makes gitk behave the same as these other git commands by default, that is, gitk only displays the diffs for files that match the path list. There is now a checkbox labelled "Limit diffs to listed paths" in the Edit/Preferences pane. If that is unchecked, gitk will display the diffs for all files as before. When gitk is run with the --merge flag, it will get the list of unmerged files at startup, intersect that with the paths listed on the command line (if any), and use that as the list of paths. Signed-off-by: Paul Mackerras --- gitk | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 10 deletions(-) diff --git a/gitk b/gitk index 41a1c69e19..248f5fbd04 100755 --- a/gitk +++ b/gitk @@ -1019,7 +1019,7 @@ proc savestuff {w} { global stuffsaved findmergefiles maxgraphpct global maxwidth showneartags showlocalchanges global viewname viewfiles viewargs viewperm nextviewnum - global cmitmode wrapcomment datetimeformat + global cmitmode wrapcomment datetimeformat limitdiffs global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor if {$stuffsaved} return @@ -1038,6 +1038,7 @@ proc savestuff {w} { puts $f [list set showneartags $showneartags] puts $f [list set showlocalchanges $showlocalchanges] puts $f [list set datetimeformat $datetimeformat] + puts $f [list set limitdiffs $limitdiffs] puts $f [list set bgcolor $bgcolor] puts $f [list set fgcolor $fgcolor] puts $f [list set colors $colors] @@ -5015,9 +5016,31 @@ proc startdiff {ids} { } } +proc path_filter {filter name} { + foreach p $filter { + set l [string length $p] + if {[string compare -length $l $p $name] == 0 && + ([string length $name] == $l || [string index $name $l] eq "/")} { + return 1 + } + } + return 0 +} + proc addtocflist {ids} { - global treediffs cflist - add_flist $treediffs($ids) + global treediffs cflist viewfiles curview limitdiffs + + if {$limitdiffs && $viewfiles($curview) ne {}} { + set flist {} + foreach f $treediffs($ids) { + if {[path_filter $viewfiles($curview) $f]} { + lappend flist $f + } + } + } else { + set flist $treediffs($ids) + } + add_flist $flist getblobdiffs $ids } @@ -5124,9 +5147,14 @@ proc getblobdiffs {ids} { global diffopts blobdifffd diffids env global diffinhdr treediffs global diffcontext + global limitdiffs viewfiles curview set env(GIT_DIFF_OPTS) $diffopts - if {[catch {set bdf [open [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] r]} err]} { + set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] + if {$limitdiffs && $viewfiles($curview) ne {}} { + set cmd [concat $cmd $viewfiles($curview)] + } + if {[catch {set bdf [open $cmd r]} err]} { puts "error getting diffs: $err" return } @@ -7382,7 +7410,7 @@ proc doprefs {} { global maxwidth maxgraphpct diffopts global oldprefs prefstop showneartags showlocalchanges global bgcolor fgcolor ctext diffcolors selectbgcolor - global uifont tabstop + global uifont tabstop limitdiffs set top .gitkprefs set prefstop $top @@ -7390,7 +7418,8 @@ proc doprefs {} { raise $top return } - foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges} { + foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges \ + limitdiffs} { set oldprefs($v) [set $v] } toplevel $top @@ -7428,6 +7457,11 @@ proc doprefs {} { label $top.tabstopl -text "tabstop" -font optionfont spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop grid x $top.tabstopl $top.tabstop -sticky w + frame $top.ldiff + label $top.ldiff.l -text "Limit diffs to listed paths" -font optionfont + checkbutton $top.ldiff.b -variable limitdiffs + pack $top.ldiff.b $top.ldiff.l -side left + grid x $top.ldiff -sticky w label $top.cdisp -text "Colors: press to choose" $top.cdisp configure -font $uifont @@ -7514,9 +7548,10 @@ proc setfg {c} { proc prefscan {} { global maxwidth maxgraphpct diffopts - global oldprefs prefstop showneartags showlocalchanges + global oldprefs prefstop showneartags showlocalchanges limitdiffs - foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges} { + foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges \ + limitdiffs} { set $v $oldprefs($v) } catch {destroy $prefstop} @@ -7526,7 +7561,7 @@ proc prefscan {} { proc prefsok {} { global maxwidth maxgraphpct global oldprefs prefstop showneartags showlocalchanges - global charspc ctext tabstop + global charspc ctext tabstop limitdiffs catch {destroy $prefstop} unset prefstop @@ -7541,7 +7576,8 @@ proc prefsok {} { if {$maxwidth != $oldprefs(maxwidth) || $maxgraphpct != $oldprefs(maxgraphpct)} { redisplay - } elseif {$showneartags != $oldprefs(showneartags)} { + } elseif {$showneartags != $oldprefs(showneartags) || + $limitdiffs != $oldprefs(limitdiffs)} { reselectline } } @@ -7869,6 +7905,7 @@ set showneartags 1 set maxrefs 20 set maxlinelen 200 set showlocalchanges 1 +set limitdiffs 1 set datetimeformat "%Y-%m-%d %H:%M:%S" set colors {green red blue magenta darkgrey brown orange} @@ -7892,6 +7929,7 @@ if {![file isdirectory $gitdir]} { exit 1 } +set mergeonly 0 set revtreeargs {} set cmdline_files {} set i 0 @@ -7899,6 +7937,10 @@ foreach arg $argv { switch -- $arg { "" { } "-d" { set datemode 1 } + "--merge" { + set mergeonly 1 + lappend revtreeargs $arg + } "--" { set cmdline_files [lrange $argv [expr {$i + 1}] end] break @@ -7939,6 +7981,40 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} { } } +if {$mergeonly} { + # find the list of unmerged files + set mlist {} + set nr_unmerged 0 + if {[catch { + set fd [open "| git ls-files -u" r] + } err]} { + show_error {} . "Couldn't get list of unmerged files: $err" + exit 1 + } + while {[gets $fd line] >= 0} { + set i [string first "\t" $line] + if {$i < 0} continue + set fname [string range $line [expr {$i+1}] end] + if {[lsearch -exact $mlist $fname] >= 0} continue + incr nr_unmerged + if {$cmdline_files eq {} || [path_filter $cmdline_files $fname]} { + lappend mlist $fname + } + } + catch {close $fd} + if {$mlist eq {}} { + if {$nr_unmerged == 0} { + show_error {} . "No files selected: --merge specified but\ + no files are unmerged." + } else { + show_error {} . "No files selected: --merge specified but\ + no unmerged files are within file limit." + } + exit 1 + } + set cmdline_files $mlist +} + set nullid "0000000000000000000000000000000000000000" set nullid2 "0000000000000000000000000000000000000001" From 94503918e480123d0d4cf03b03153e4d83cdfd4e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 23 Oct 2007 10:33:38 +1000 Subject: [PATCH 09/10] gitk: Ensure tabstop setting gets restored by Cancel button We weren't restoring the tabstop setting if the user pressed the Cancel button in the Edit/Preferences window. Also improved the label for the checkbox (made it "Tab spacing" rather than the laconic "tabstop") and moved it above the "Display nearby tags" checkbox. Signed-off-by: Paul Mackerras --- gitk | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gitk b/gitk index 248f5fbd04..0d3705c43c 100755 --- a/gitk +++ b/gitk @@ -7419,7 +7419,7 @@ proc doprefs {} { return } foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges \ - limitdiffs} { + limitdiffs tabstop} { set oldprefs($v) [set $v] } toplevel $top @@ -7449,14 +7449,14 @@ proc doprefs {} { -font optionfont entry $top.diffopt -width 20 -textvariable diffopts grid x $top.diffoptl $top.diffopt -sticky w + label $top.tabstopl -text "Tab spacing" -font optionfont + spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop + grid x $top.tabstopl $top.tabstop -sticky w frame $top.ntag label $top.ntag.l -text "Display nearby tags" -font optionfont checkbutton $top.ntag.b -variable showneartags pack $top.ntag.b $top.ntag.l -side left grid x $top.ntag -sticky w - label $top.tabstopl -text "tabstop" -font optionfont - spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop - grid x $top.tabstopl $top.tabstop -sticky w frame $top.ldiff label $top.ldiff.l -text "Limit diffs to listed paths" -font optionfont checkbutton $top.ldiff.b -variable limitdiffs @@ -7547,11 +7547,11 @@ proc setfg {c} { } proc prefscan {} { - global maxwidth maxgraphpct diffopts - global oldprefs prefstop showneartags showlocalchanges limitdiffs + global oldprefs prefstop foreach v {maxwidth maxgraphpct diffopts showneartags showlocalchanges \ - limitdiffs} { + limitdiffs tabstop} { + global $v set $v $oldprefs($v) } catch {destroy $prefstop} From bd8f677e1c8349b9128490e2a21e0f573d0bea1d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 23 Oct 2007 22:37:23 +1000 Subject: [PATCH 10/10] gitk: Fix some bugs with path limiting in the diff display First, we weren't putting "--" between the ids and the paths in the git diff-tree/diff-index/diff-files command, so if there was a tag and a file with the same name, we could get an ambiguity in the command. This puts the "--" in to make it clear that the paths are paths. Secondly, this implements the path limiting for merge diffs as well as the normal 2-way diffs. Signed-off-by: Paul Mackerras --- gitk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gitk b/gitk index 0d3705c43c..f41e30207b 100755 --- a/gitk +++ b/gitk @@ -4913,12 +4913,16 @@ proc mergediff {id l} { global diffmergeid diffopts mdifffd global diffids global parentlist + global limitdiffs viewfiles curview set diffmergeid $id set diffids $id # this doesn't seem to actually affect anything... set env(GIT_DIFF_OPTS) $diffopts set cmd [concat | git diff-tree --no-commit-id --cc $id] + if {$limitdiffs && $viewfiles($curview) ne {}} { + set cmd [concat $cmd -- $viewfiles($curview)] + } if {[catch {set mdf [open $cmd r]} err]} { error_popup "Error getting merge diffs: $err" return @@ -5152,7 +5156,7 @@ proc getblobdiffs {ids} { set env(GIT_DIFF_OPTS) $diffopts set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] if {$limitdiffs && $viewfiles($curview) ne {}} { - set cmd [concat $cmd $viewfiles($curview)] + set cmd [concat $cmd -- $viewfiles($curview)] } if {[catch {set bdf [open $cmd r]} err]} { puts "error getting diffs: $err"