gitk: Put temporary directory inside .git
[gitweb.git] / gitk
diff --git a/gitk b/gitk
index 59970aff39a4cee3f905bd522f3ea1fcbb89a4f6..e263b49f5abc1aeb8ba2ff4cf11dfbce58f843f8 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -2,7 +2,7 @@
 # Tcl ignores the next line -*- tcl -*- \
 exec wish "$0" -- "$@"
 
-# Copyright © 2005-2009 Paul Mackerras.  All rights reserved.
+# Copyright © 2005-2011 Paul Mackerras.  All rights reserved.
 # This program is free software; it may be used, copied, modified
 # and distributed under the terms of the GNU General Public Licence,
 # either version 2, or (at your option) any later version.
@@ -131,6 +131,7 @@ proc unmerged_files {files} {
 
 proc parseviewargs {n arglist} {
     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env
+    global worddiff git_version
 
     set vdatemode($n) 0
     set vmergeonly($n) 0
@@ -168,7 +169,7 @@ proc parseviewargs {n arglist} {
                lappend diffargs $arg
            }
            "--raw" - "--patch-with-raw" - "--patch-with-stat" -
-           "--name-only" - "--name-status" - "--color" - "--color-words" -
+           "--name-only" - "--name-status" - "--color" -
            "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
            "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
            "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
@@ -177,6 +178,18 @@ proc parseviewargs {n arglist} {
                # These cause our parsing of git log's output to fail, or else
                # they're options we want to set ourselves, so ignore them.
            }
+           "--color-words*" - "--word-diff=color" {
+               # These trigger a word diff in the console interface,
+               # so help the user by enabling our own support
+               if {[package vcompare $git_version "1.7.2"] >= 0} {
+                   set worddiff [mc "Color words"]
+               }
+           }
+           "--word-diff*" {
+               if {[package vcompare $git_version "1.7.2"] >= 0} {
+                   set worddiff [mc "Markup words"]
+               }
+           }
            "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
            "--check" - "--exit-code" - "--quiet" - "--topo-order" -
            "--full-history" - "--dense" - "--sparse" -
@@ -313,6 +326,7 @@ proc start_rev_list {view} {
     global viewactive viewinstances vmergeonly
     global mainheadid viewmainheadid viewmainheadid_orig
     global vcanopt vflags vrevs vorigargs
+    global show_notes
 
     set startmsecs [clock clicks -milliseconds]
     set commitidx($view) 0
@@ -361,8 +375,8 @@ proc start_rev_list {view} {
     }
 
     if {[catch {
-       set fd [open [concat | git log --no-color -z --pretty=raw --parents \
-                        --boundary $args "--" $files] r]
+       set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
+                       --parents --boundary $args "--" $files] r]
     } err]} {
        error_popup "[mc "Error executing git log:"] $err"
        return 0
@@ -456,6 +470,7 @@ proc updatecommits {} {
     global mainheadid viewmainheadid viewmainheadid_orig pending_select
     global isworktree
     global varcid vposids vnegids vflags vrevs
+    global show_notes
 
     set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
     rereadrefs
@@ -508,8 +523,8 @@ proc updatecommits {} {
        set args $vorigargs($view)
     }
     if {[catch {
-       set fd [open [concat | git log --no-color -z --pretty=raw --parents \
-                         --boundary $args "--" $vfilelimit($view)] r]
+       set fd [open [concat | git log --no-color -z --pretty=raw $show_notes \
+                       --parents --boundary $args "--" $vfilelimit($view)] r]
     } err]} {
        error_popup "[mc "Error executing git log:"] $err"
        return
@@ -644,7 +659,7 @@ proc newvarc {view id} {
        if {![info exists commitinfo($id)]} {
            parsecommit $id $commitdata($id) 1
        }
-       set cdate [lindex $commitinfo($id) 4]
+       set cdate [lindex [lindex $commitinfo($id) 4] 0]
        if {![string is integer -strict $cdate]} {
            set cdate 0
        }
@@ -1606,7 +1621,7 @@ proc readcommit {id} {
 }
 
 proc parsecommit {id contents listed} {
-    global commitinfo cdate
+    global commitinfo
 
     set inhdr 1
     set comment {}
@@ -1626,10 +1641,10 @@ proc parsecommit {id contents listed} {
        set line [split $line " "]
        set tag [lindex $line 0]
        if {$tag == "author"} {
-           set audate [lindex $line end-1]
+           set audate [lrange $line end-1 end]
            set auname [join [lrange $line 1 end-2] " "]
        } elseif {$tag == "committer"} {
-           set comdate [lindex $line end-1]
+           set comdate [lrange $line end-1 end]
            set comname [join [lrange $line 1 end-2] " "]
        }
     }
@@ -1656,11 +1671,9 @@ proc parsecommit {id contents listed} {
        }
        set comment $newcomment
     }
-    if {$comdate != {}} {
-       set cdate($id) $comdate
-    }
+    set hasnote [string first "\nNotes:\n" $contents]
     set commitinfo($id) [list $headline $auname $audate \
-                            $comname $comdate $comment]
+                            $comname $comdate $comment $hasnote]
 }
 
 proc getcommit {id} {
@@ -1877,8 +1890,11 @@ proc setoptions {} {
     option add *Menubutton.font uifont startupFile
     option add *Label.font uifont startupFile
     option add *Message.font uifont startupFile
-    option add *Entry.font uifont startupFile
+    option add *Entry.font textfont startupFile
+    option add *Text.font textfont startupFile
     option add *Labelframe.font uifont startupFile
+    option add *Spinbox.font textfont startupFile
+    option add *Listbox.font mainfont startupFile
 }
 
 # Make a menu and submenus.
@@ -1967,6 +1983,8 @@ proc makewindow {} {
     global fprogitem fprogcoord lastprogupdate progupdatepending
     global rprogitem rprogcoord rownumsel numcommits
     global have_tk85 use_ttk NS
+    global git_version
+    global worddiff
 
     # The "mc" arguments here are purely so that xgettext
     # sees the following string as needing to be translated
@@ -2174,7 +2192,7 @@ proc makewindow {} {
     set findstring {}
     set fstring .tf.lbar.findstring
     lappend entries $fstring
-    ${NS}::entry $fstring -width 30 -font textfont -textvariable findstring
+    ${NS}::entry $fstring -width 30 -textvariable findstring
     trace add variable findstring write find_change
     set findtype [mc "Exact"]
     set findtypemenu [makedroplist .tf.lbar.findtype \
@@ -2217,7 +2235,7 @@ proc makewindow {} {
     pack .bleft.top.search -side left -padx 5
     set sstring .bleft.top.sstring
     set searchstring ""
-    ${NS}::entry $sstring -width 20 -font textfont -textvariable searchstring
+    ${NS}::entry $sstring -width 20 -textvariable searchstring
     lappend entries $sstring
     trace add variable searchstring write incrsearch
     pack $sstring -side left -expand 1 -fill x
@@ -2229,7 +2247,7 @@ proc makewindow {} {
        -command changediffdisp -variable diffelide -value {1 0}
     ${NS}::label .bleft.mid.labeldiffcontext -text "      [mc "Lines of context"]: "
     pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
-    spinbox .bleft.mid.diffcontext -width 5 -font textfont \
+    spinbox .bleft.mid.diffcontext -width 5 \
        -from 0 -increment 1 -to 10000000 \
        -validate all -validatecommand "diffcontextvalidate %P" \
        -textvariable diffcontextstring
@@ -2240,6 +2258,15 @@ proc makewindow {} {
     ${NS}::checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
        -command changeignorespace -variable ignorespace
     pack .bleft.mid.ignspace -side left -padx 5
+
+    set worddiff [mc "Line diff"]
+    if {[package vcompare $git_version "1.7.2"] >= 0} {
+       makedroplist .bleft.mid.worddiff worddiff [mc "Line diff"] \
+           [mc "Markup words"] [mc "Color words"]
+       trace add variable worddiff write changeworddiff
+       pack .bleft.mid.worddiff -side left -padx 5
+    }
+
     set ctext .bleft.bottom.ctext
     text $ctext -background $bgcolor -foreground $fgcolor \
        -state disabled -font textfont \
@@ -2448,6 +2475,7 @@ proc makewindow {} {
     global ctxbut
     bind $cflist $ctxbut {pop_flist_menu %W %X %Y %x %y}
     bind $ctext $ctxbut {pop_diff_menu %W %X %Y %x %y}
+    bind $ctext <Button-1> {focus %W}
 
     set maincursor [. cget -cursor]
     set textcursor [$ctext cget -cursor]
@@ -2622,7 +2650,7 @@ proc savestuff {w} {
     global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
     global cmitmode wrapcomment datetimeformat limitdiffs
     global colors uicolor bgcolor fgcolor diffcolors diffcontext selectbgcolor
-    global autoselect extdifftool perfile_attrs markbgcolor use_ttk
+    global autoselect autosellen extdifftool perfile_attrs markbgcolor use_ttk
     global hideremotes want_ttk
 
     if {$stuffsaved} return
@@ -2643,6 +2671,7 @@ proc savestuff {w} {
        puts $f [list set cmitmode $cmitmode]
        puts $f [list set wrapcomment $wrapcomment]
        puts $f [list set autoselect $autoselect]
+       puts $f [list set autosellen $autosellen]
        puts $f [list set showneartags $showneartags]
        puts $f [list set hideremotes $hideremotes]
        puts $f [list set showlocalchanges $showlocalchanges]
@@ -2784,7 +2813,7 @@ proc about {} {
     message $w.m -text [mc "
 Gitk - a commit viewer for git
 
-Copyright © 2005-2009 Paul Mackerras
+Copyright \u00a9 2005-2011 Paul Mackerras
 
 Use and redistribute under the terms of the GNU General Public License"] \
            -justify center -aspect 400 -border 2 -bg white -relief groove
@@ -3302,8 +3331,7 @@ proc gitknewtmpdir {} {
     global diffnum gitktmpdir gitdir
 
     if {![info exists gitktmpdir]} {
-       set gitktmpdir [file join [file dirname $gitdir] \
-                           [format ".gitk-tmp.%s" [pid]]]
+       set gitktmpdir [file join $gitdir [format ".gitk-tmp.%s" [pid]]]
        if {[catch {file mkdir $gitktmpdir} err]} {
            error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
            unset gitktmpdir
@@ -3335,10 +3363,10 @@ proc save_file_from_commit {filename output what} {
 
 proc external_diff_get_one_file {diffid filename diffdir} {
     global nullid nullid2 nullfile
-    global gitdir
+    global worktree
 
     if {$diffid == $nullid} {
-        set difffile [file join [file dirname $gitdir] $filename]
+        set difffile [file join $worktree $filename]
        if {[file exists $difffile]} {
            return $difffile
        }
@@ -3528,7 +3556,7 @@ proc make_relative {f} {
 }
 
 proc external_blame {parent_idx {line {}}} {
-    global flist_menu_file gitdir
+    global flist_menu_file cdup
     global nullid nullid2
     global parentlist selectedline currentid
 
@@ -3547,7 +3575,7 @@ proc external_blame {parent_idx {line {}}} {
     if {$line ne {} && $line > 1} {
        lappend cmdline "--line=$line"
     }
-    set f [file join [file dirname $gitdir] $flist_menu_file]
+    set f [file join $cdup $flist_menu_file]
     # Unfortunately it seems git gui blame doesn't like
     # being given an absolute path...
     set f [make_relative $f]
@@ -3560,7 +3588,7 @@ proc external_blame {parent_idx {line {}}} {
 proc show_line_source {} {
     global cmitmode currentid parents curview blamestuff blameinst
     global diff_menu_line diff_menu_filebase flist_menu_file
-    global nullid nullid2 gitdir
+    global nullid nullid2 gitdir cdup
 
     set from_index {}
     if {$cmitmode eq "tree"} {
@@ -3613,7 +3641,7 @@ proc show_line_source {} {
     } else {
        lappend blameargs $id
     }
-    lappend blameargs -- [file join [file dirname $gitdir] $flist_menu_file]
+    lappend blameargs -- [file join $cdup $flist_menu_file]
     if {[catch {
        set f [open $blameargs r]
     } err]} {
@@ -3808,10 +3836,10 @@ proc newview {ishighlight} {
        raise $top
        return
     }
+    decode_view_opts $nextviewnum $revtreeargs
     set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
     set newviewopts($nextviewnum,perm) 0
     set newviewopts($nextviewnum,cmd)  $viewargscmd($curview)
-    decode_view_opts $nextviewnum $revtreeargs
     vieweditor $top $nextviewnum [mc "Gitk view definition"]
 }
 
@@ -3848,6 +3876,7 @@ set known_view_options {
     {cmd       t50= +  {}               {mc "Command to generate more commits to include:"}}
     }
 
+# Convert $newviewopts($n, ...) into args for git log.
 proc encode_view_opts {n} {
     global known_view_options newviewopts
 
@@ -3881,6 +3910,7 @@ proc encode_view_opts {n} {
     return [concat $rargs [shellsplit $newviewopts($n,args)]]
 }
 
+# Fill $newviewopts($n, ...) based on args for git log.
 proc decode_view_opts {n view_args} {
     global known_view_options newviewopts
 
@@ -3963,10 +3993,10 @@ proc editview {} {
        raise $top
        return
     }
+    decode_view_opts $curview $viewargs($curview)
     set newviewname($curview)      $viewname($curview)
     set newviewopts($curview,perm) $viewperm($curview)
     set newviewopts($curview,cmd)  $viewargscmd($curview)
-    decode_view_opts $curview $viewargs($curview)
     vieweditor $top $curview "[mc "Gitk: edit view"] $viewname($curview)"
 }
 
@@ -4040,7 +4070,7 @@ proc vieweditor {top n title} {
        } elseif {$type eq "path"} {
            ${NS}::label $top.l -text $title
            pack $top.l -in $top -side top -pady [list 3 0] -anchor w -padx 3
-           text $top.t -width 40 -height 5 -background $bgcolor -font uifont
+           text $top.t -width 40 -height 5 -background $bgcolor
            if {[info exists viewfiles($n)]} {
                foreach f $viewfiles($n) {
                    $top.t insert end $f
@@ -4496,12 +4526,17 @@ proc makepatterns {l} {
 
 proc do_file_hl {serial} {
     global highlight_files filehighlight highlight_paths gdttype fhl_list
+    global cdup
 
     if {$gdttype eq [mc "touching paths:"]} {
        if {[catch {set paths [shellsplit $highlight_files]}]} return
        set highlight_paths [makepatterns $paths]
        highlight_filelist
-       set gdtargs [concat -- $paths]
+       set relative_paths {}
+       foreach path $paths {
+           lappend relative_paths [file join $cdup $path]
+       }
+       set gdtargs [concat -- $relative_paths]
     } elseif {$gdttype eq [mc "adding/removing string:"]} {
        set gdtargs [list "-S$highlight_files"]
     } else {
@@ -5866,6 +5901,9 @@ proc drawcmittext {id row col} {
        || [info exists idotherrefs($id)]} {
        set xt [drawtags $id $x $xt $y]
     }
+    if {[lindex $commitinfo($id) 6] > 0} {
+       set xt [drawnotesign $xt $y]
+    }
     set headline [lindex $commitinfo($id) 0]
     set name [lindex $commitinfo($id) 1]
     set date [lindex $commitinfo($id) 2]
@@ -6268,6 +6306,7 @@ proc drawtags {id x xt y1} {
               -width $lthickness -fill black -tags tag.$id]
     $canv lower $t
     foreach tag $marks x $xvals wid $wvals {
+       set tag_quoted [string map {% %%} $tag]
        set xl [expr {$x + $delta}]
        set xr [expr {$x + $delta + $wid + $lthickness}]
        set font mainfont
@@ -6276,7 +6315,7 @@ proc drawtags {id x xt y1} {
            set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
                       $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
                       -width 1 -outline black -fill yellow -tags tag.$id]
-           $canv bind $t <1> [list showtag $tag 1]
+           $canv bind $t <1> [list showtag $tag_quoted 1]
            set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}]
        } else {
            # draw a head or other ref
@@ -6303,14 +6342,25 @@ proc drawtags {id x xt y1} {
        set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
                   -font $font -tags [list tag.$id text]]
        if {$ntags >= 0} {
-           $canv bind $t <1> [list showtag $tag 1]
+           $canv bind $t <1> [list showtag $tag_quoted 1]
        } elseif {$nheads >= 0} {
-           $canv bind $t $ctxbut [list headmenu %X %Y $id $tag]
+           $canv bind $t $ctxbut [list headmenu %X %Y $id $tag_quoted]
        }
     }
     return $xt
 }
 
+proc drawnotesign {xt y} {
+    global linespc canv fgcolor
+
+    set orad [expr {$linespc / 3}]
+    set t [$canv create rectangle [expr {$xt - $orad}] [expr {$y - $orad}] \
+              [expr {$xt + $orad - 1}] [expr {$y + $orad - 1}] \
+              -fill yellow -outline $fgcolor -width 1 -tags circle]
+    set xt [expr {$xt + $orad * 3}]
+    return $xt
+}
+
 proc xcoord {i level ln} {
     global canvx0 xspc1 xspc2
 
@@ -6864,7 +6914,7 @@ proc selectline {l isnew {desired_loc {}}} {
     global mergemax numcommits pending_select
     global cmitmode showneartags allcommits
     global targetrow targetid lastscrollrows
-    global autoselect jump_to_here
+    global autoselect autosellen jump_to_here
 
     catch {unset pending_select}
     $canv delete hover
@@ -6926,7 +6976,7 @@ proc selectline {l isnew {desired_loc {}}} {
     $sha1entry delete 0 end
     $sha1entry insert 0 $id
     if {$autoselect} {
-       $sha1entry selection range 0 end
+       $sha1entry selection range 0 $autosellen
     }
     rhighlight_sel $id
 
@@ -7296,6 +7346,7 @@ proc getblobline {bf id} {
                            [lindex [split $commentend .] 0]}]
            mark_ctext_line $lnum
        }
+       $ctext config -state disabled
        return 0
     }
     $ctext config -state disabled
@@ -7497,14 +7548,19 @@ proc changeignorespace {} {
     reselectline
 }
 
+proc changeworddiff {name ix op} {
+    reselectline
+}
+
 proc getblobdiffs {ids} {
     global blobdifffd diffids env
     global diffinhdr treediffs
     global diffcontext
     global ignorespace
+    global worddiff
     global limitdiffs vfilelimit curview
     global diffencoding targetline diffnparents
-    global git_version
+    global git_version currdiffsubmod
 
     set textconv {}
     if {[package vcompare $git_version "1.6.1"] >= 0} {
@@ -7518,6 +7574,9 @@ proc getblobdiffs {ids} {
     if {$ignorespace} {
        append cmd " -w"
     }
+    if {$worddiff ne [mc "Line diff"]} {
+       append cmd " --word-diff=porcelain"
+    }
     if {$limitdiffs && $vfilelimit($curview) ne {}} {
        set cmd [concat $cmd -- $vfilelimit($curview)]
     }
@@ -7531,6 +7590,7 @@ proc getblobdiffs {ids} {
     set diffencoding [get_path_encoding {}]
     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}
     set blobdifffd($ids) $bdf
+    set currdiffsubmod ""
     filerun $bdf [list getblobdiffline $bdf $diffids]
 }
 
@@ -7601,7 +7661,8 @@ proc getblobdiffline {bdf ids} {
     global diffnexthead diffnextnote difffilestart
     global ctext_file_names ctext_file_lines
     global diffinhdr treediffs mergemax diffnparents
-    global diffencoding jump_to_here targetline diffline
+    global diffencoding jump_to_here targetline diffline currdiffsubmod
+    global worddiff
 
     set nr 0
     $ctext conf -state normal
@@ -7682,19 +7743,30 @@ proc getblobdiffline {bdf ids} {
 
        } elseif {![string compare -length 10 "Submodule " $line]} {
            # start of a new submodule
-           if {[string compare [$ctext get "end - 4c" end] "\n \n\n"]} {
+           if {[regexp -indices "\[0-9a-f\]+\\.\\." $line nameend]} {
+               set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]
+           } else {
+               set fname [string range $line 10 [expr [string first "contains " $line] - 2]]
+           }
+           if {$currdiffsubmod != $fname} {
                $ctext insert end "\n";     # Add newline after commit message
            }
            set curdiffstart [$ctext index "end - 1c"]
            lappend ctext_file_names ""
-           set fname [string range $line 10 [expr [string last " " $line] - 1]]
-           lappend ctext_file_lines $fname
-           makediffhdr $fname $ids
-           $ctext insert end "\n$line\n" filesep
+           if {$currdiffsubmod != $fname} {
+               lappend ctext_file_lines $fname
+               makediffhdr $fname $ids
+               set currdiffsubmod $fname
+               $ctext insert end "\n$line\n" filesep
+           } else {
+               $ctext insert end "$line\n" filesep
+           }
        } elseif {![string compare -length 3 "  >" $line]} {
+           set $currdiffsubmod ""
            set line [encoding convertfrom $diffencoding $line]
            $ctext insert end "$line\n" dresult
        } elseif {![string compare -length 3 "  <" $line]} {
+           set $currdiffsubmod ""
            set line [encoding convertfrom $diffencoding $line]
            $ctext insert end "$line\n" d0
        } elseif {$diffinhdr} {
@@ -7730,15 +7802,28 @@ proc getblobdiffline {bdf ids} {
            # parse the prefix - one ' ', '-' or '+' for each parent
            set prefix [string range $line 0 [expr {$diffnparents - 1}]]
            set tag [expr {$diffnparents > 1? "m": "d"}]
+           set dowords [expr {$worddiff ne [mc "Line diff"] && $diffnparents == 1}]
+           set words_pre_markup ""
+           set words_post_markup ""
            if {[string trim $prefix " -+"] eq {}} {
                # prefix only has " ", "-" and "+" in it: normal diff line
                set num [string first "-" $prefix]
+               if {$dowords} {
+                   set line [string range $line 1 end]
+               }
                if {$num >= 0} {
                    # removed line, first parent with line is $num
                    if {$num >= $mergemax} {
                        set num "max"
                    }
-                   $ctext insert end "$line\n" $tag$num
+                   if {$dowords && $worddiff eq [mc "Markup words"]} {
+                       $ctext insert end "\[-$line-\]" $tag$num
+                   } else {
+                       $ctext insert end "$line" $tag$num
+                   }
+                   if {!$dowords} {
+                       $ctext insert end "\n" $tag$num
+                   }
                } else {
                    set tags {}
                    if {[string first "+" $prefix] >= 0} {
@@ -7753,6 +7838,8 @@ proc getblobdiffline {bdf ids} {
                                lappend tags m$num
                            }
                        }
+                       set words_pre_markup "{+"
+                       set words_post_markup "+}"
                    }
                    if {$targetline ne {}} {
                        if {$diffline == $targetline} {
@@ -7762,8 +7849,17 @@ proc getblobdiffline {bdf ids} {
                            incr diffline
                        }
                    }
-                   $ctext insert end "$line\n" $tags
+                   if {$dowords && $worddiff eq [mc "Markup words"]} {
+                       $ctext insert end "$words_pre_markup$line$words_post_markup" $tags
+                   } else {
+                       $ctext insert end "$line" $tags
+                   }
+                   if {!$dowords} {
+                       $ctext insert end "\n" $tags
+                   }
                }
+           } elseif {$dowords && $prefix eq "~"} {
+               $ctext insert end "\n" {}
            } else {
                # "\ No newline at end of file",
                # or something else we don't recognize
@@ -8530,7 +8626,7 @@ proc do_cmp_commits {a b} {
 }
 
 proc diffcommits {a b} {
-    global diffcontext diffids blobdifffd diffinhdr
+    global diffcontext diffids blobdifffd diffinhdr currdiffsubmod
 
     set tmpdir [gitknewtmpdir]
     set fna [file join $tmpdir "commit-[string range $a 0 7]"]
@@ -8551,6 +8647,7 @@ proc diffcommits {a b} {
     set diffids [list commits $a $b]
     set blobdifffd($diffids) $fd
     set diffinhdr 0
+    set currdiffsubmod ""
     filerun $fd [list getblobdiffline $fd $diffids]
 }
 
@@ -8984,7 +9081,7 @@ proc cherrypick {} {
                        to file '%s'.\nPlease commit, reset or stash\
                        your changes and try again." $fname]
        } elseif {[regexp -line \
-                      {^(CONFLICT \(.*\):|Automatic cherry-pick failed)} \
+                      {^(CONFLICT \(.*\):|Automatic cherry-pick failed|error: could not apply)} \
                       $err]} {
            if {[confirm_popup [mc "Cherry-pick failed because of merge\
                        conflict.\nDo you wish to run git citool to\
@@ -10677,7 +10774,7 @@ proc doprefs {} {
     global maxwidth maxgraphpct use_ttk NS
     global oldprefs prefstop showneartags showlocalchanges
     global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
-    global tabstop limitdiffs autoselect extdifftool perfile_attrs
+    global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs
     global hideremotes want_ttk have_ttk
 
     set top .gitkprefs
@@ -10705,9 +10802,10 @@ proc doprefs {} {
     ${NS}::checkbutton $top.showlocal -text [mc "Show local changes"] \
        -variable showlocalchanges
     grid x $top.showlocal -sticky w
-    ${NS}::checkbutton $top.autoselect -text [mc "Auto-select SHA1"] \
+    ${NS}::checkbutton $top.autoselect -text [mc "Auto-select SHA1 (length)"] \
        -variable autoselect
-    grid x $top.autoselect -sticky w
+    spinbox $top.autosellen -from 1 -to 40 -width 4 -textvariable autosellen
+    grid x $top.autoselect $top.autosellen -sticky w
     ${NS}::checkbutton $top.hideremotes -text [mc "Hide remote refs"] \
        -variable hideremotes
     grid x $top.hideremotes -sticky w
@@ -10842,6 +10940,7 @@ proc setselbg {c} {
 # radiobuttons look bad.  This chooses white for selectColor if the
 # background color is light, or black if it is dark.
 proc setui {c} {
+    if {[tk windowingsystem] eq "win32"} { return }
     set bg [winfo rgb . $c]
     set selc black
     if {[lindex $bg 0] + 1.5 * [lindex $bg 1] + 0.5 * [lindex $bg 2] > 100000} {
@@ -10941,7 +11040,7 @@ proc prefsok {} {
 proc formatdate {d} {
     global datetimeformat
     if {$d ne {}} {
-       set d [clock format $d -format $datetimeformat]
+       set d [clock format [lindex $d 0] -format $datetimeformat]
     }
     return $d
 }
@@ -11348,6 +11447,7 @@ set showlocalchanges 1
 set limitdiffs 1
 set datetimeformat "%Y-%m-%d %H:%M:%S"
 set autoselect 1
+set autosellen 40
 set perfile_attrs 0
 set want_ttk 1
 
@@ -11372,6 +11472,7 @@ if {[tk windowingsystem] eq "win32"} {
 set diffcolors {red "#00a000" blue}
 set diffcontext 3
 set ignorespace 0
+set worddiff ""
 set markbgcolor "#e0e0ff"
 
 set circlecolors {white blue gray blue blue}
@@ -11500,7 +11601,12 @@ if {![info exists have_ttk]} {
 set use_ttk [expr {$have_ttk && $want_ttk}]
 set NS [expr {$use_ttk ? "ttk" : ""}]
 
-set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
+regexp {^git version ([\d.]*\d)} [exec git version] _ git_version
+
+set show_notes {}
+if {[package vcompare $git_version "1.6.6.2"] >= 0} {
+    set show_notes "--show-notes"
+}
 
 set runq {}
 set history {}
@@ -11539,6 +11645,11 @@ set stuffsaved 0
 set patchnum 0
 set lserial 0
 set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
+set cdup {}
+if {$isworktree} {
+    set cdup [exec git rev-parse --show-cdup]
+}
+set worktree [exec git rev-parse --show-toplevel]
 setcoords
 makewindow
 catch {
@@ -11604,3 +11715,9 @@ if {[tk windowingsystem] eq "win32"} {
 }
 
 getcommits {}
+
+# Local variables:
+# mode: tcl
+# indent-tabs-mode: t
+# tab-width: 8
+# End: