Code

Add "--patch" option to git-add--interactive
[git.git] / gitk
diff --git a/gitk b/gitk
index 3b3cc4bd93cad39e7d377e2b2586a52b0514a11a..1da0b0af1d1da6c8596f366d7a36519b4e249c3b 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -95,7 +95,7 @@ proc start_rev_list {view} {
        set order "--date-order"
     }
     if {[catch {
        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"
                         --boundary $viewargs($view) "--" $viewfiles($view)] r]
     } err]} {
        error_popup "Error executing git rev-list: $err"
@@ -111,7 +111,7 @@ proc start_rev_list {view} {
        fconfigure $fd -encoding $tclencoding
     }
     filerun $fd [list getcommitlines $fd $view]
        fconfigure $fd -encoding $tclencoding
     }
     filerun $fd [list getcommitlines $fd $view]
-    nowbusy $view
+    nowbusy $view "Reading"
     if {$view == $curview} {
        set progressdirn 1
        set progresscoords {0 0}
     if {$view == $curview} {
        set progressdirn 1
        set progresscoords {0 0}
@@ -626,6 +626,7 @@ proc makewindow {} {
     global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
     global headctxmenu progresscanv progressitem progresscoords statusw
     global fprogitem fprogcoord lastprogupdate progupdatepending
     global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
     global headctxmenu progresscanv progressitem progresscoords statusw
     global fprogitem fprogcoord lastprogupdate progupdatepending
+    global rprogitem rprogcoord
     global have_tk85
 
     menu .bar
     global have_tk85
 
     menu .bar
@@ -752,17 +753,19 @@ proc makewindow {} {
     canvas $progresscanv -relief sunken -height $h -borderwidth 2
     set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
     set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
     canvas $progresscanv -relief sunken -height $h -borderwidth 2
     set progressitem [$progresscanv create rect -1 0 0 $h -fill green]
     set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow]
+    set rprogitem [$progresscanv create rect -1 0 0 $h -fill red]
     pack $progresscanv -side right -expand 1 -fill x
     set progresscoords {0 0}
     set fprogcoord 0
     pack $progresscanv -side right -expand 1 -fill x
     set progresscoords {0 0}
     set fprogcoord 0
+    set rprogcoord 0
     bind $progresscanv <Configure> adjustprogress
     set lastprogupdate [clock clicks -milliseconds]
     set progupdatepending 0
 
     # build up the bottom bar of upper window
     label .tf.lbar.flabel -text "Find " -font uifont
     bind $progresscanv <Configure> adjustprogress
     set lastprogupdate [clock clicks -milliseconds]
     set progupdatepending 0
 
     # build up the bottom bar of upper window
     label .tf.lbar.flabel -text "Find " -font uifont
-    button .tf.lbar.fnext -text "next" -command dofind -font uifont
-    button .tf.lbar.fprev -text "prev" -command {dofind 1} -font uifont
+    button .tf.lbar.fnext -text "next" -command {dofind 1 1} -font uifont
+    button .tf.lbar.fprev -text "prev" -command {dofind -1 1} -font uifont
     label .tf.lbar.flab2 -text " commit " -font uifont
     pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
        -side left -fill y
     label .tf.lbar.flab2 -text " commit " -font uifont
     pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \
        -side left -fill y
@@ -827,11 +830,11 @@ proc makewindow {} {
     lappend entries $sstring
     trace add variable searchstring write incrsearch
     pack $sstring -side left -expand 1 -fill x
     lappend entries $sstring
     trace add variable searchstring write incrsearch
     pack $sstring -side left -expand 1 -fill x
-    radiobutton .bleft.mid.diff -text "Diff" \
+    radiobutton .bleft.mid.diff -text "Diff" -font uifont \
        -command changediffdisp -variable diffelide -value {0 0}
        -command changediffdisp -variable diffelide -value {0 0}
-    radiobutton .bleft.mid.old -text "Old version" \
+    radiobutton .bleft.mid.old -text "Old version" -font uifont \
        -command changediffdisp -variable diffelide -value {0 1}
        -command changediffdisp -variable diffelide -value {0 1}
-    radiobutton .bleft.mid.new -text "New version" \
+    radiobutton .bleft.mid.new -text "New version" -font uifont \
        -command changediffdisp -variable diffelide -value {1 0}
     label .bleft.mid.labeldiffcontext -text "      Lines of context: " \
        -font uifont
        -command changediffdisp -variable diffelide -value {1 0}
     label .bleft.mid.labeldiffcontext -text "      Lines of context: " \
        -font uifont
@@ -943,6 +946,12 @@ proc makewindow {} {
     } else {
        bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
        bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
     } else {
        bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
        bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
+        if {[tk windowingsystem] eq "aqua"} {
+            bindall <MouseWheel> {
+                set delta [expr {- (%D)}]
+                allcanvs yview scroll $delta units
+            }
+        }
     }
     bindall <2> "canvscan mark %W %x %y"
     bindall <B2-Motion> "canvscan dragto %W %x %y"
     }
     bindall <2> "canvscan mark %W %x %y"
     bindall <B2-Motion> "canvscan dragto %W %x %y"
@@ -950,6 +959,8 @@ proc makewindow {} {
     bindkey <End> sellastline
     bind . <Key-Up> "selnextline -1"
     bind . <Key-Down> "selnextline 1"
     bindkey <End> sellastline
     bind . <Key-Up> "selnextline -1"
     bind . <Key-Down> "selnextline 1"
+    bind . <Shift-Key-Up> "dofind -1 0"
+    bind . <Shift-Key-Down> "dofind 1 0"
     bindkey <Key-Right> "goforw"
     bindkey <Key-Left> "goback"
     bind . <Key-Prior> "selnextpage -1"
     bindkey <Key-Right> "goforw"
     bindkey <Key-Left> "goback"
     bind . <Key-Prior> "selnextpage -1"
@@ -974,14 +985,14 @@ proc makewindow {} {
     bindkey b "$ctext yview scroll -1 pages"
     bindkey d "$ctext yview scroll 18 units"
     bindkey u "$ctext yview scroll -18 units"
     bindkey b "$ctext yview scroll -1 pages"
     bindkey d "$ctext yview scroll 18 units"
     bindkey u "$ctext yview scroll -18 units"
-    bindkey / {findnext 1}
-    bindkey <Key-Return> {findnext 0}
-    bindkey ? findprev
+    bindkey / {dofind 1 1}
+    bindkey <Key-Return> {dofind 1 1}
+    bindkey ? {dofind -1 1}
     bindkey f nextfile
     bindkey <F5> updatecommits
     bind . <$M1B-q> doquit
     bindkey f nextfile
     bindkey <F5> updatecommits
     bind . <$M1B-q> doquit
-    bind . <$M1B-f> dofind
-    bind . <$M1B-g> {findnext 0}
+    bind . <$M1B-f> {dofind 1 1}
+    bind . <$M1B-g> {dofind 1 0}
     bind . <$M1B-r> dosearchback
     bind . <$M1B-s> dosearch
     bind . <$M1B-equal> {incrfont 1}
     bind . <$M1B-r> dosearchback
     bind . <$M1B-s> dosearch
     bind . <$M1B-equal> {incrfont 1}
@@ -990,7 +1001,7 @@ proc makewindow {} {
     bind . <$M1B-KP_Subtract> {incrfont -1}
     wm protocol . WM_DELETE_WINDOW doquit
     bind . <Button-1> "click %W"
     bind . <$M1B-KP_Subtract> {incrfont -1}
     wm protocol . WM_DELETE_WINDOW doquit
     bind . <Button-1> "click %W"
-    bind $fstring <Key-Return> dofind
+    bind $fstring <Key-Return> {dofind 1 1}
     bind $sha1entry <Key-Return> gotocommit
     bind $sha1entry <<PasteSelection>> clearsha1
     bind $cflist <1> {sel_flist %W %x %y; break}
     bind $sha1entry <Key-Return> gotocommit
     bind $sha1entry <<PasteSelection>> clearsha1
     bind $cflist <1> {sel_flist %W %x %y; break}
@@ -1110,6 +1121,7 @@ proc click {w} {
 proc adjustprogress {} {
     global progresscanv progressitem progresscoords
     global fprogitem fprogcoord lastprogupdate progupdatepending
 proc adjustprogress {} {
     global progresscanv progressitem progresscoords
     global fprogitem fprogcoord lastprogupdate progupdatepending
+    global rprogitem rprogcoord
 
     set w [expr {[winfo width $progresscanv] - 4}]
     set x0 [expr {$w * [lindex $progresscoords 0]}]
 
     set w [expr {[winfo width $progresscanv] - 4}]
     set x0 [expr {$w * [lindex $progresscoords 0]}]
@@ -1117,6 +1129,7 @@ proc adjustprogress {} {
     set h [winfo height $progresscanv]
     $progresscanv coords $progressitem $x0 0 $x1 $h
     $progresscanv coords $fprogitem 0 0 [expr {$w * $fprogcoord}] $h
     set h [winfo height $progresscanv]
     $progresscanv coords $progressitem $x0 0 $x1 $h
     $progresscanv coords $fprogitem 0 0 [expr {$w * $fprogcoord}] $h
+    $progresscanv coords $rprogitem 0 0 [expr {$w * $rprogcoord}] $h
     set now [clock clicks -milliseconds]
     if {$now >= $lastprogupdate + 100} {
        set progupdatepending 0
     set now [clock clicks -milliseconds]
     if {$now >= $lastprogupdate + 100} {
        set progupdatepending 0
@@ -1142,7 +1155,7 @@ proc savestuff {w} {
     global stuffsaved findmergefiles maxgraphpct
     global maxwidth showneartags showlocalchanges
     global viewname viewfiles viewargs viewperm nextviewnum
     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
     global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
 
     if {$stuffsaved} return
@@ -1161,6 +1174,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 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]
        puts $f [list set bgcolor $bgcolor]
        puts $f [list set fgcolor $fgcolor]
        puts $f [list set colors $colors]
@@ -1313,8 +1327,8 @@ Gitk key bindings:
 <$M1T-Down>    Scroll commit list down one line
 <$M1T-PageUp>  Scroll commit list up one page
 <$M1T-PageDown>        Scroll commit list down one page
 <$M1T-Down>    Scroll commit list down one line
 <$M1T-PageUp>  Scroll commit list up one page
 <$M1T-PageDown>        Scroll commit list down one page
-<Shift-Up>     Move to previous highlighted line
-<Shift-Down>   Move to next highlighted line
+<Shift-Up>     Find backwards (upwards, later commits)
+<Shift-Down>   Find forwards (downwards, earlier commits)
 <Delete>, b    Scroll diff view up one page
 <Backspace>    Scroll diff view up one page
 <Space>                Scroll diff view down one page
 <Delete>, b    Scroll diff view up one page
 <Backspace>    Scroll diff view up one page
 <Space>                Scroll diff view down one page
@@ -2447,11 +2461,7 @@ proc readfhighlight {} {
        return 0
     }
     if {[info exists find_dirn]} {
        return 0
     }
     if {[info exists find_dirn]} {
-       if {$find_dirn > 0} {
-           run findmore
-       } else {
-           run findmorerev
-       }
+       run findmore
     }
     return 1
 }
     }
     return 1
 }
@@ -3808,34 +3818,23 @@ proc drawcommits {row {endrow {}}} {
        drawcmitrow $r
        if {$r == $er} break
        set nextid [lindex $displayorder [expr {$r + 1}]]
        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
 
        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
        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
            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]
            }
        }
     }
            }
        }
     }
@@ -4195,20 +4194,30 @@ proc settextcursor {c} {
     set curtextcursor $c
 }
 
     set curtextcursor $c
 }
 
-proc nowbusy {what} {
-    global isbusy
+proc nowbusy {what {name {}}} {
+    global isbusy busyname statusw
 
     if {[array names isbusy] eq {}} {
        . config -cursor watch
        settextcursor watch
     }
     set isbusy($what) 1
 
     if {[array names isbusy] eq {}} {
        . config -cursor watch
        settextcursor watch
     }
     set isbusy($what) 1
+    set busyname($what) $name
+    if {$name ne {}} {
+       $statusw conf -text $name
+    }
 }
 
 proc notbusy {what} {
 }
 
 proc notbusy {what} {
-    global isbusy maincursor textcursor
+    global isbusy maincursor textcursor busyname statusw
 
 
-    catch {unset isbusy($what)}
+    catch {
+       unset isbusy($what)
+       if {$busyname($what) ne {} &&
+           [$statusw cget -text] eq $busyname($what)} {
+           $statusw conf -text {}
+       }
+    }
     if {[array names isbusy] eq {}} {
        . config -cursor $maincursor
        settextcursor $textcursor
     if {[array names isbusy] eq {}} {
        . config -cursor $maincursor
        settextcursor $textcursor
@@ -4236,31 +4245,30 @@ proc findmatches {f} {
     return $matches
 }
 
     return $matches
 }
 
-proc dofind {{rev 0}} {
+proc dofind {{dirn 1} {wrap 1}} {
     global findstring findstartline findcurline selectedline numcommits
     global findstring findstartline findcurline selectedline numcommits
-    global gdttype filehighlight fh_serial find_dirn
+    global gdttype filehighlight fh_serial find_dirn findallowwrap
 
 
-    unmarkmatches
+    if {[info exists find_dirn]} {
+       if {$find_dirn == $dirn} return
+       stopfinding
+    }
     focus .
     if {$findstring eq {} || $numcommits == 0} return
     if {![info exists selectedline]} {
     focus .
     if {$findstring eq {} || $numcommits == 0} return
     if {![info exists selectedline]} {
-       set findstartline [lindex [visiblerows] $rev]
+       set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
     } else {
        set findstartline $selectedline
     }
     set findcurline $findstartline
     } else {
        set findstartline $selectedline
     }
     set findcurline $findstartline
-    nowbusy finding
+    nowbusy finding "Searching"
     if {$gdttype ne "containing:" && ![info exists filehighlight]} {
        after cancel do_file_hl $fh_serial
        do_file_hl $fh_serial
     }
     if {$gdttype ne "containing:" && ![info exists filehighlight]} {
        after cancel do_file_hl $fh_serial
        do_file_hl $fh_serial
     }
-    if {!$rev} {
-       set find_dirn 1
-       run findmore
-    } else {
-       set find_dirn -1
-       run findmorerev
-    }
+    set find_dirn $dirn
+    set findallowwrap $wrap
+    run findmore
 }
 
 proc stopfinding {} {
 }
 
 proc stopfinding {} {
@@ -4275,147 +4283,52 @@ proc stopfinding {} {
     }
 }
 
     }
 }
 
-proc findnext {restart} {
-    global findcurline find_dirn
-
-    if {[info exists find_dirn]} return
-    if {![info exists findcurline]} {
-       if {$restart} {
-           dofind
-       } else {
-           bell
-       }
-    } else {
-       set find_dirn 1
-       run findmore
-       nowbusy finding
-    }
-}
-
-proc findprev {} {
-    global findcurline find_dirn
-
-    if {[info exists find_dirn]} return
-    if {![info exists findcurline]} {
-       dofind 1
-    } else {
-       set find_dirn -1
-       run findmorerev
-       nowbusy finding
-    }
-}
-
 proc findmore {} {
     global commitdata commitinfo numcommits findpattern findloc
     global findstartline findcurline displayorder
     global find_dirn gdttype fhighlights fprogcoord
 proc findmore {} {
     global commitdata commitinfo numcommits findpattern findloc
     global findstartline findcurline displayorder
     global find_dirn gdttype fhighlights fprogcoord
+    global findallowwrap
 
     if {![info exists find_dirn]} {
        return 0
     }
     set fldtypes {Headline Author Date Committer CDate Comments}
 
     if {![info exists find_dirn]} {
        return 0
     }
     set fldtypes {Headline Author Date Committer CDate Comments}
-    set l [expr {$findcurline + 1}]
-    if {$l >= $numcommits} {
-       set l 0
-    }
-    if {$l <= $findstartline} {
-       set lim [expr {$findstartline + 1}]
-    } else {
-       set lim $numcommits
-    }
-    if {$lim - $l > 500} {
-       set lim [expr {$l + 500}]
-    }
-    set found 0
-    set domore 1
-    if {$gdttype eq "containing:"} {
-       for {} {$l < $lim} {incr l} {
-           set id [lindex $displayorder $l]
-           # shouldn't happen unless git log doesn't give all the commits...
-           if {![info exists commitdata($id)]} continue
-           if {![doesmatch $commitdata($id)]} continue
-           if {![info exists commitinfo($id)]} {
-               getcommit $id
-           }
-           set info $commitinfo($id)
-           foreach f $info ty $fldtypes {
-               if {($findloc eq "All fields" || $findloc eq $ty) &&
-                   [doesmatch $f]} {
-                   set found 1
-                   break
-               }
-           }
-           if {$found} break
+    set l $findcurline
+    set moretodo 0
+    if {$find_dirn > 0} {
+       incr l
+       if {$l >= $numcommits} {
+           set l 0
+       }
+       if {$l <= $findstartline} {
+           set lim [expr {$findstartline + 1}]
+       } else {
+           set lim $numcommits
+           set moretodo $findallowwrap
        }
     } else {
        }
     } else {
-       for {} {$l < $lim} {incr l} {
-           set id [lindex $displayorder $l]
-           if {![info exists fhighlights($l)]} {
-               askfilehighlight $l $id
-               if {$domore} {
-                   set domore 0
-                   set findcurline [expr {$l - 1}]
-               }
-           } elseif {$fhighlights($l)} {
-               set found $domore
-               break
-           }
+       if {$l == 0} {
+           set l $numcommits
        }
        }
-    }
-    if {$found || ($domore && $l == $findstartline + 1)} {
-       unset findcurline
-       unset find_dirn
-       notbusy finding
-       set fprogcoord 0
-       adjustprogress
-       if {$found} {
-           findselectline $l
+       incr l -1
+       if {$l >= $findstartline} {
+           set lim [expr {$findstartline - 1}]
        } else {
        } else {
-           bell
+           set lim -1
+           set moretodo $findallowwrap
        }
        }
-       return 0
-    }
-    if {!$domore} {
-       flushhighlights
-    } else {
-       set findcurline [expr {$l - 1}]
-    }
-    set n [expr {$findcurline - ($findstartline + 1)}]
-    if {$n < 0} {
-       incr n $numcommits
-    }
-    set fprogcoord [expr {$n * 1.0 / $numcommits}]
-    adjustprogress
-    return $domore
-}
-
-proc findmorerev {} {
-    global commitdata commitinfo numcommits findpattern findloc
-    global findstartline findcurline displayorder
-    global find_dirn gdttype fhighlights fprogcoord
-
-    if {![info exists find_dirn]} {
-       return 0
-    }
-    set fldtypes {Headline Author Date Committer CDate Comments}
-    set l $findcurline
-    if {$l == 0} {
-       set l $numcommits
     }
     }
-    incr l -1
-    if {$l >= $findstartline} {
-       set lim [expr {$findstartline - 1}]
-    } else {
-       set lim -1
-    }
-    if {$l - $lim > 500} {
-       set lim [expr {$l - 500}]
+    set n [expr {($lim - $l) * $find_dirn}]
+    if {$n > 500} {
+       set n 500
+       set moretodo 1
     }
     set found 0
     set domore 1
     if {$gdttype eq "containing:"} {
     }
     set found 0
     set domore 1
     if {$gdttype eq "containing:"} {
-       for {} {$l > $lim} {incr l -1} {
+       for {} {$n > 0} {incr n -1; incr l $find_dirn} {
            set id [lindex $displayorder $l]
            set id [lindex $displayorder $l]
+           # shouldn't happen unless git log doesn't give all the commits...
            if {![info exists commitdata($id)]} continue
            if {![doesmatch $commitdata($id)]} continue
            if {![info exists commitinfo($id)]} {
            if {![info exists commitdata($id)]} continue
            if {![doesmatch $commitdata($id)]} continue
            if {![info exists commitinfo($id)]} {
@@ -4432,13 +4345,13 @@ proc findmorerev {} {
            if {$found} break
        }
     } else {
            if {$found} break
        }
     } else {
-       for {} {$l > $lim} {incr l -1} {
+       for {} {$n > 0} {incr n -1; incr l $find_dirn} {
            set id [lindex $displayorder $l]
            if {![info exists fhighlights($l)]} {
                askfilehighlight $l $id
                if {$domore} {
                    set domore 0
            set id [lindex $displayorder $l]
            if {![info exists fhighlights($l)]} {
                askfilehighlight $l $id
                if {$domore} {
                    set domore 0
-                   set findcurline [expr {$l + 1}]
+                   set findcurline [expr {$l - $find_dirn}]
                }
            } elseif {$fhighlights($l)} {
                set found $domore
                }
            } elseif {$fhighlights($l)} {
                set found $domore
@@ -4446,7 +4359,7 @@ proc findmorerev {} {
            }
        }
     }
            }
        }
     }
-    if {$found || ($domore && $l == $findstartline - 1)} {
+    if {$found || ($domore && !$moretodo)} {
        unset findcurline
        unset find_dirn
        notbusy finding
        unset findcurline
        unset find_dirn
        notbusy finding
@@ -4462,9 +4375,9 @@ proc findmorerev {} {
     if {!$domore} {
        flushhighlights
     } else {
     if {!$domore} {
        flushhighlights
     } else {
-       set findcurline [expr {$l + 1}]
+       set findcurline [expr {$l - $find_dirn}]
     }
     }
-    set n [expr {($findstartline - 1) - $findcurline}]
+    set n [expr {($findcurline - $findstartline) * $find_dirn - 1}]
     if {$n < 0} {
        incr n $numcommits
     }
     if {$n < 0} {
        incr n $numcommits
     }
@@ -5122,11 +5035,15 @@ proc mergediff {id l} {
     global diffmergeid mdifffd
     global diffids
     global parentlist
     global diffmergeid mdifffd
     global diffids
     global parentlist
+    global limitdiffs viewfiles curview
 
     set diffmergeid $id
     set diffids $id
     # this doesn't seem to actually affect anything...
     set cmd [concat | git diff-tree --no-commit-id --cc $id]
 
     set diffmergeid $id
     set diffids $id
     # this doesn't seem to actually affect anything...
     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
     if {[catch {set mdf [open $cmd r]} err]} {
        error_popup "Error getting merge diffs: $err"
        return
@@ -5226,8 +5143,27 @@ proc startdiff {ids} {
     }
 }
 
     }
 }
 
+proc path_filter {filter name} {
+    foreach p $filter {
+       set l [string length $p]
+       if {[string index $p end] eq "/"} {
+           if {[string compare -length $l $p $name] == 0} {
+               return 1
+           }
+       } else {
+           if {[string compare -length $l $p $name] == 0 &&
+               ([string length $name] == $l ||
+                [string index $name $l] eq "/")} {
+               return 1
+           }
+       }
+    }
+    return 0
+}
+
 proc addtocflist {ids} {
 proc addtocflist {ids} {
-    global treediffs cflist
+    global treediffs
+
     add_flist $treediffs($ids)
     getblobdiffs $ids
 }
     add_flist $treediffs($ids)
     getblobdiffs $ids
 }
@@ -5284,7 +5220,7 @@ proc gettreediffs {ids} {
 
 proc gettreediffline {gdtf ids} {
     global treediff treediffs treepending diffids diffmergeid
 
 proc gettreediffline {gdtf ids} {
     global treediff treediffs treepending diffids diffmergeid
-    global cmitmode
+    global cmitmode viewfiles curview limitdiffs
 
     set nr 0
     while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
 
     set nr 0
     while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
@@ -5301,7 +5237,17 @@ proc gettreediffline {gdtf ids} {
        return [expr {$nr >= 1000? 2: 1}]
     }
     close $gdtf
        return [expr {$nr >= 1000? 2: 1}]
     }
     close $gdtf
-    set treediffs($ids) $treediff
+    if {$limitdiffs && $viewfiles($curview) ne {}} {
+       set flist {}
+       foreach f $treediff {
+           if {[path_filter $viewfiles($curview) $f]} {
+               lappend flist $f
+           }
+       }
+       set treediffs($ids) $flist
+    } else {
+       set treediffs($ids) $treediff
+    }
     unset treepending
     if {$cmitmode eq "tree"} {
        gettree $diffids
     unset treepending
     if {$cmitmode eq "tree"} {
        gettree $diffids
@@ -5335,8 +5281,13 @@ proc getblobdiffs {ids} {
     global blobdifffd diffids env
     global diffinhdr treediffs
     global diffcontext
     global blobdifffd diffids env
     global diffinhdr treediffs
     global diffcontext
+    global limitdiffs viewfiles curview
 
 
-    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
     }
        puts "error getting diffs: $err"
        return
     }
@@ -5420,8 +5371,7 @@ proc getblobdiffline {bdf ids} {
            set diffinhdr 0
 
        } elseif {$diffinhdr} {
            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]
                set fname [string range $line [expr 6 + [string first " from " $line] ] end]
                if {[string index $fname 0] eq "\""} {
                    set fname [lindex $fname 0]
@@ -6366,7 +6316,7 @@ proc cherrypick {} {
                        included in branch $mainhead -- really re-apply it?"]
        if {!$ok} return
     }
                        included in branch $mainhead -- really re-apply it?"]
        if {!$ok} return
     }
-    nowbusy cherrypick
+    nowbusy cherrypick "Cherry-picking"
     update
     # Unfortunately git-cherry-pick writes stuff to stderr even when
     # no error occurs, and exec takes that as an indication of error...
     update
     # Unfortunately git-cherry-pick writes stuff to stderr even when
     # no error occurs, and exec takes that as an indication of error...
@@ -6432,32 +6382,23 @@ proc resethead {} {
        error_popup $err
     } else {
        dohidelocalchanges
        error_popup $err
     } else {
        dohidelocalchanges
-       set w ".resetprogress"
-       filerun $fd [list readresetstat $fd $w]
-       toplevel $w
-       wm transient $w
-       wm title $w "Reset progress"
-       message $w.m -text "Reset in progress, please wait..." \
-           -justify center -aspect 1000
-       pack $w.m -side top -fill x -padx 20 -pady 5
-       canvas $w.c -width 150 -height 20 -bg white
-       $w.c create rect 0 0 0 20 -fill green -tags rect
-       pack $w.c -side top -fill x -padx 20 -pady 5 -expand 1
-       nowbusy reset
+       filerun $fd [list readresetstat $fd]
+       nowbusy reset "Resetting"
     }
 }
 
     }
 }
 
-proc readresetstat {fd w} {
-    global mainhead mainheadid showlocalchanges
+proc readresetstat {fd} {
+    global mainhead mainheadid showlocalchanges rprogcoord
 
     if {[gets $fd line] >= 0} {
        if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
 
     if {[gets $fd line] >= 0} {
        if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
-           set x [expr {($m * 150) / $n}]
-           $w.c coords rect 0 0 $x 20
+           set rprogcoord [expr {1.0 * $m / $n}]
+           adjustprogress
        }
        return 1
     }
        }
        return 1
     }
-    destroy $w
+    set rprogcoord 0
+    adjustprogress
     notbusy reset
     if {[catch {close $fd} err]} {
        error_popup $err
     notbusy reset
     if {[catch {close $fd} err]} {
        error_popup $err
@@ -6499,7 +6440,7 @@ proc cobranch {} {
 
     # check the tree is clean first??
     set oldmainhead $mainhead
 
     # check the tree is clean first??
     set oldmainhead $mainhead
-    nowbusy checkout
+    nowbusy checkout "Checking out"
     update
     dohidelocalchanges
     if {[catch {
     update
     dohidelocalchanges
     if {[catch {
@@ -6967,7 +6908,7 @@ proc addnewchild {id p} {
     global arcnos arcids arctags arcout arcend arcstart archeads growing
     global seeds allcommits
 
     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
     set allparents($id) [list $p]
     set allchildren($id) {}
     set arcnos($id) {}
     set allparents($id) [list $p]
     set allchildren($id) {}
     set arcnos($id) {}
@@ -8001,7 +7942,7 @@ proc doprefs {} {
     global maxwidth maxgraphpct
     global oldprefs prefstop showneartags showlocalchanges
     global bgcolor fgcolor ctext diffcolors selectbgcolor
     global maxwidth maxgraphpct
     global oldprefs prefstop showneartags showlocalchanges
     global bgcolor fgcolor ctext diffcolors selectbgcolor
-    global uifont tabstop
+    global uifont tabstop limitdiffs
 
     set top .gitkprefs
     set prefstop $top
 
     set top .gitkprefs
     set prefstop $top
@@ -8009,7 +7950,8 @@ proc doprefs {} {
        raise $top
        return
     }
        raise $top
        return
     }
-    foreach v {maxwidth maxgraphpct showneartags showlocalchanges} {
+    foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
+                  limitdiffs tabstop} {
        set oldprefs($v) [set $v]
     }
     toplevel $top
        set oldprefs($v) [set $v]
     }
     toplevel $top
@@ -8035,14 +7977,19 @@ proc doprefs {} {
     label $top.ddisp -text "Diff display options"
     $top.ddisp configure -font uifont
     grid $top.ddisp - -sticky w -pady 10
     label $top.ddisp -text "Diff display options"
     $top.ddisp configure -font uifont
     grid $top.ddisp - -sticky w -pady 10
+    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
     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
+    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
 
     label $top.cdisp -text "Colors: press to choose"
     $top.cdisp configure -font uifont
@@ -8135,10 +8082,11 @@ proc setfg {c} {
 }
 
 proc prefscan {} {
 }
 
 proc prefscan {} {
-    global maxwidth maxgraphpct
-    global oldprefs prefstop showneartags showlocalchanges
+    global oldprefs prefstop
 
 
-    foreach v {maxwidth maxgraphpct showneartags showlocalchanges} {
+    foreach v {maxwidth maxgraphpct showneartags showlocalchanges \
+                  limitdiffs tabstop} {
+       global $v
        set $v $oldprefs($v)
     }
     catch {destroy $prefstop}
        set $v $oldprefs($v)
     }
     catch {destroy $prefstop}
@@ -8150,6 +8098,7 @@ proc prefsok {} {
     global maxwidth maxgraphpct
     global oldprefs prefstop showneartags showlocalchanges
     global fontpref mainfont textfont uifont
     global maxwidth maxgraphpct
     global oldprefs prefstop showneartags showlocalchanges
     global fontpref mainfont textfont uifont
+    global limitdiffs treediffs
 
     catch {destroy $prefstop}
     unset prefstop
 
     catch {destroy $prefstop}
     unset prefstop
@@ -8182,10 +8131,15 @@ proc prefsok {} {
            dohidelocalchanges
        }
     }
            dohidelocalchanges
        }
     }
+    if {$limitdiffs != $oldprefs(limitdiffs)} {
+       # treediffs elements are limited by path
+       catch {unset treediffs}
+    }
     if {$fontchanged || $maxwidth != $oldprefs(maxwidth)
        || $maxgraphpct != $oldprefs(maxgraphpct)} {
        redisplay
     if {$fontchanged || $maxwidth != $oldprefs(maxwidth)
        || $maxgraphpct != $oldprefs(maxgraphpct)} {
        redisplay
-    } elseif {$showneartags != $oldprefs(showneartags)} {
+    } elseif {$showneartags != $oldprefs(showneartags) ||
+         $limitdiffs != $oldprefs(limitdiffs)} {
        reselectline
     }
 }
        reselectline
     }
 }
@@ -8471,6 +8425,13 @@ proc tcl_encoding {enc} {
     return {}
 }
 
     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 wrcomcmd "git diff-tree --stdin -p --pretty"
 # defaults...
 set datemode 0
 set wrcomcmd "git diff-tree --stdin -p --pretty"
@@ -8505,6 +8466,7 @@ set showneartags 1
 set maxrefs 20
 set maxlinelen 200
 set showlocalchanges 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}
 set datetimeformat "%Y-%m-%d %H:%M:%S"
 
 set colors {green red blue magenta darkgrey brown orange}
@@ -8539,6 +8501,7 @@ if {![file isdirectory $gitdir]} {
     exit 1
 }
 
     exit 1
 }
 
+set mergeonly 0
 set revtreeargs {}
 set cmdline_files {}
 set i 0
 set revtreeargs {}
 set cmdline_files {}
 set i 0
@@ -8546,6 +8509,10 @@ foreach arg $argv {
     switch -- $arg {
        "" { }
        "-d" { set datemode 1 }
     switch -- $arg {
        "" { }
        "-d" { set datemode 1 }
+       "--merge" {
+           set mergeonly 1
+           lappend revtreeargs $arg
+       }
        "--" {
            set cmdline_files [lrange $argv [expr {$i + 1}] end]
            break
        "--" {
            set cmdline_files [lrange $argv [expr {$i + 1}] end]
            break
@@ -8586,6 +8553,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"
 
 set nullid "0000000000000000000000000000000000000000"
 set nullid2 "0000000000000000000000000000000000000001"