gitk: Allow diff view without context lines
[git.git] / gitk
diff --git a/gitk b/gitk
index dca1741c71254175d2161c1fd58091077f6087fd..4604c831fe0c5ac9b855cdef6f71888e99dd9462 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -187,7 +187,8 @@ proc parseviewargs {n arglist} {
            "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
            "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
            "--remove-empty" - "--first-parent" - "--cherry-pick" -
-           "-S*" - "--pickaxe-all" - "--pickaxe-regex" {
+           "-S*" - "--pickaxe-all" - "--pickaxe-regex" -
+           "--simplify-by-decoration" {
                # These mean that we get a subset of the commits
                set filtered 1
                lappend glflags $arg
@@ -2145,7 +2146,7 @@ proc makewindow {} {
     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 \
-       -from 1 -increment 1 -to 10000000 \
+       -from 0 -increment 1 -to 10000000 \
        -validate all -validatecommand "diffcontextvalidate %P" \
        -textvariable diffcontextstring
     .bleft.mid.diffcontext set $diffcontext
@@ -3671,17 +3672,36 @@ proc newview {ishighlight} {
 }
 
 set known_view_options {
-    {perm    b    . {}               {mc "Remember this view"}}
-    {args    t50= + {}               {mc "Commits to include (arguments to git log):"}}
-    {all     b    * "--all"          {mc "Use all refs"}}
-    {dorder  b    . {"--date-order" "-d"}      {mc "Strictly sort by date"}}
-    {lright  b    . "--left-right"   {mc "Mark branch sides"}}
-    {since   t15  + {"--since=*" "--after=*"}  {mc "Since date:"}}
-    {until   t15  . {"--until=*" "--before=*"} {mc "Until date:"}}
-    {limit   t10  + "--max-count=*"  {mc "Max count:"}}
-    {skip    t10  . "--skip=*"       {mc "Skip:"}}
-    {first   b    . "--first-parent" {mc "Limit to first parent"}}
-    {cmd     t50= + {}               {mc "Command to generate more commits to include:"}}
+    {perm      b    .  {}               {mc "Remember this view"}}
+    {reflabel  l    +  {}               {mc "References (space separated list):"}}
+    {refs      t15  .. {}               {mc "Branches & tags:"}}
+    {allrefs   b    *. "--all"          {mc "All refs"}}
+    {branches  b    .  "--branches"     {mc "All (local) branches"}}
+    {tags      b    .  "--tags"         {mc "All tags"}}
+    {remotes   b    .  "--remotes"      {mc "All remote-tracking branches"}}
+    {commitlbl l    +  {}               {mc "Commit Info (regular expressions):"}}
+    {author    t15  .. "--author=*"     {mc "Author:"}}
+    {committer t15  .  "--committer=*"  {mc "Committer:"}}
+    {loginfo   t15  .. "--grep=*"       {mc "Commit Message:"}}
+    {allmatch  b    .. "--all-match"    {mc "Matches all Commit Info criteria"}}
+    {changes_l l    +  {}               {mc "Changes to Files:"}}
+    {pickaxe_s r0   .  {}               {mc "Fixed String"}}
+    {pickaxe_t r1   .  "--pickaxe-regex"  {mc "Regular Expression"}}
+    {pickaxe   t15  .. "-S*"            {mc "Search string:"}}
+    {datelabel l    +  {}               {mc "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 15:27:38\"):"}}
+    {since     t15  ..  {"--since=*" "--after=*"}  {mc "Since:"}}
+    {until     t15  .   {"--until=*" "--before=*"} {mc "Until:"}}
+    {limit_lbl l    +  {}               {mc "Limit and/or skip a number of revisions (positive integer):"}}
+    {limit     t10  *. "--max-count=*"  {mc "Number to show:"}}
+    {skip      t10  .  "--skip=*"       {mc "Number to skip:"}}
+    {misc_lbl  l    +  {}               {mc "Miscellaneous options:"}}
+    {dorder    b    *. {"--date-order" "-d"}      {mc "Strictly sort by date"}}
+    {lright    b    .  "--left-right"   {mc "Mark branch sides"}}
+    {first     b    .  "--first-parent" {mc "Limit to first parent"}}
+    {smplhst   b    .  "--simplify-by-decoration"   {mc "Simple history"}}
+    {args      t50  *. {}               {mc "Additional arguments to git log:"}}
+    {allpaths  path +  {}               {mc "Enter files and directories to include, one per line:"}}
+    {cmd       t50= +  {}               {mc "Command to generate more commits to include:"}}
     }
 
 proc encode_view_opts {n} {
@@ -3693,13 +3713,19 @@ proc encode_view_opts {n} {
        if {$patterns eq {}} continue
        set pattern [lindex $patterns 0]
 
-       set val $newviewopts($n,[lindex $opt 0])
-       
        if {[lindex $opt 1] eq "b"} {
+           set val $newviewopts($n,[lindex $opt 0])
            if {$val} {
                lappend rargs $pattern
            }
+       } elseif {[regexp {^r(\d+)$} [lindex $opt 1] type value]} {
+           regexp {^(.*_)} [lindex $opt 0] uselessvar button_id
+           set val $newviewopts($n,$button_id)
+           if {$val eq $value} {
+               lappend rargs $pattern
+           }
        } else {
+           set val $newviewopts($n,[lindex $opt 0])
            set val [string trim $val]
            if {$val ne {}} {
                set pfix [string range $pattern 0 end-1]
@@ -3707,6 +3733,7 @@ proc encode_view_opts {n} {
            }
        }
     }
+    set rargs [concat $rargs [shellsplit $newviewopts($n,refs)]]
     return [concat $rargs [shellsplit $newviewopts($n,args)]]
 }
 
@@ -3714,14 +3741,22 @@ proc decode_view_opts {n view_args} {
     global known_view_options newviewopts
 
     foreach opt $known_view_options {
+       set id [lindex $opt 0]
        if {[lindex $opt 1] eq "b"} {
+           # Checkboxes
+           set val 0
+        } elseif {[regexp {^r(\d+)$} [lindex $opt 1]]} {
+           # Radiobuttons
+           regexp {^(.*_)} $id uselessvar id
            set val 0
        } else {
+           # Text fields
            set val {}
        }
-       set newviewopts($n,[lindex $opt 0]) $val
+       set newviewopts($n,$id) $val
     }
     set oargs [list]
+    set refargs [list]
     foreach arg $view_args {
        if {[regexp -- {^-([0-9]+)$} $arg arg cnt]
            && ![info exists found(limit)]} {
@@ -3735,11 +3770,17 @@ proc decode_view_opts {n view_args} {
            if {[info exists found($id)]} continue
            foreach pattern [lindex $opt 3] {
                if {![string match $pattern $arg]} continue
-               if {[lindex $opt 1] ne "b"} {
+               if {[lindex $opt 1] eq "b"} {
+                   # Check buttons
+                   set val 1
+               } elseif {[regexp {^r(\d+)$} [lindex $opt 1] match num]} {
+                   # Radio buttons
+                   regexp {^(.*_)} $id uselessvar id
+                   set val $num
+               } else {
+                   # Text input fields
                    set size [string length $pattern]
                    set val [string range $arg [expr {$size-1}] end]
-               } else {
-                   set val 1
                }
                set newviewopts($n,$id) $val
                set found($id) 1
@@ -3748,8 +3789,13 @@ proc decode_view_opts {n view_args} {
            if {[info exists val]} break
        }
        if {[info exists val]} continue
-       lappend oargs $arg
+       if {[regexp {^-} $arg]} {
+           lappend oargs $arg
+       } else {
+           lappend refargs $arg
+       }
     }
+    set newviewopts($n,refs) [shellarglist $refargs]
     set newviewopts($n,args) [shellarglist $oargs]
 }
 
@@ -3785,16 +3831,16 @@ proc vieweditor {top n title} {
     global known_view_options
 
     toplevel $top
-    wm title $top $title
+    wm title $top [concat $title [mc "-- criteria for selecting revisions"]]
     make_transient $top .
 
     # View name
     frame $top.nfr
-    label $top.nl -text [mc "Name"]
+    label $top.nl -text [mc "View Name:"]
     entry $top.name -width 20 -textvariable newviewname($n)
     pack $top.nfr -in $top -fill x -pady 5 -padx 3
-    pack $top.nl -in $top.nfr -side left -padx {0 30}
-    pack $top.name -in $top.nfr -side left
+    pack $top.nl -in $top.nfr -side left -padx {0 5}
+    pack $top.name -in $top.nfr -side left -padx {0 25}
 
     # View options
     set cframe $top.nfr
@@ -3813,14 +3859,28 @@ proc vieweditor {top n title} {
            frame $cframe
            pack $cframe -in $top -fill x -pady 3 -padx 3
            set cexpand [expr {$flags eq "*"}]
+        } elseif {$flags eq ".." || $flags eq "*."} {
+           set cframe $top.fr$cnt
+           incr cnt
+           frame $cframe
+           pack $cframe -in $top -fill x -pady 3 -padx [list 15 3]
+           set cexpand [expr {$flags eq "*."}]
        } else {
            set lxpad 5
        }
 
-       if {$type eq "b"} {
+       if {$type eq "l"} {
+            label $cframe.l_$id -text $title
+            pack $cframe.l_$id -in $cframe -side left -pady [list 3 0] -anchor w
+       } elseif {$type eq "b"} {
            checkbutton $cframe.c_$id -text $title -variable newviewopts($n,$id)
            pack $cframe.c_$id -in $cframe -side left \
                -padx [list $lxpad 0] -expand $cexpand -anchor w
+       } elseif {[regexp {^r(\d+)$} $type type sz]} {
+           regexp {^(.*_)} $id uselessvar button_id
+           radiobutton $cframe.c_$id -text $title -variable newviewopts($n,$button_id) -value $sz
+           pack $cframe.c_$id -in $cframe -side left \
+               -padx [list $lxpad 0] -expand $cexpand -anchor w
        } elseif {[regexp {^t(\d+)$} $type type sz]} {
            message $cframe.l_$id -aspect 1500 -text $title
            entry $cframe.e_$id -width $sz -background $bgcolor \
@@ -3833,23 +3893,22 @@ proc vieweditor {top n title} {
                -textvariable newviewopts($n,$id)
            pack $cframe.l_$id -in $cframe -side top -pady [list 3 0] -anchor w
            pack $cframe.e_$id -in $cframe -side top -fill x
+       } elseif {$type eq "path"} {
+           message $top.l -aspect 1500 -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
+           if {[info exists viewfiles($n)]} {
+               foreach f $viewfiles($n) {
+                   $top.t insert end $f
+                   $top.t insert end "\n"
+               }
+               $top.t delete {end - 1c} end
+               $top.t mark set insert 0.0
+           }
+           pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
        }
     }
 
-    # Path list
-    message $top.l -aspect 1500 \
-       -text [mc "Enter files and directories to include, one per line:"]
-    pack $top.l -in $top -side top -pady [list 7 0] -anchor w -padx 3
-    text $top.t -width 40 -height 5 -background $bgcolor -font uifont
-    if {[info exists viewfiles($n)]} {
-       foreach f $viewfiles($n) {
-           $top.t insert end $f
-           $top.t insert end "\n"
-       }
-       $top.t delete {end - 1c} end
-       $top.t mark set insert 0.0
-    }
-    pack $top.t -in $top -side top -pady [list 0 5] -fill both -expand 1 -padx 3
     frame $top.buts
     button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n]
     button $top.buts.apply -text [mc "Apply (F5)"] -command [list newviewok $top $n 1]
@@ -6489,6 +6548,17 @@ proc setlink {id lk} {
     }
 }
 
+proc appendshortlink {id {pre {}} {post {}}} {
+    global ctext linknum
+
+    $ctext insert end $pre
+    $ctext tag delete link$linknum
+    $ctext insert end [string range $id 0 7] link$linknum
+    $ctext insert end $post
+    setlink $id link$linknum
+    incr linknum
+}
+
 proc makelink {id} {
     global pendinglinks
 
@@ -7238,7 +7308,7 @@ proc diffcontextchange {n1 n2 op} {
     global diffcontextstring diffcontext
 
     if {[string is integer -strict $diffcontextstring]} {
-       if {$diffcontextstring > 0} {
+       if {$diffcontextstring >= 0} {
            set diffcontext $diffcontextstring
            reselectline
        }
@@ -7256,8 +7326,13 @@ proc getblobdiffs {ids} {
     global ignorespace
     global limitdiffs vfilelimit curview
     global diffencoding targetline diffnparents
+    global git_version
 
-    set cmd [diffcmd $ids "-p -C --cc --no-commit-id -U$diffcontext"]
+    set textconv {}
+    if {[package vcompare $git_version "1.6.1"] >= 0} {
+       set textconv "--textconv"
+    }
+    set cmd [diffcmd $ids "-p $textconv -C --cc --no-commit-id -U$diffcontext"]
     if {$ignorespace} {
        append cmd " -w"
     }
@@ -8127,8 +8202,15 @@ proc getpatchid {id} {
     global patchids
 
     if {![info exists patchids($id)]} {
-       set x [exec git diff-tree -p --root $id | git patch-id]
-       set patchids($id) [lindex $x 0]
+       set cmd [diffcmd [list $id] {-p --root}]
+       # trim off the initial "|"
+       set cmd [lrange $cmd 1 end]
+       if {[catch {
+           set x [eval exec $cmd | git patch-id]
+           set patchids($id) [lindex $x 0]
+       }]} {
+           set patchids($id) "error"
+       }
     }
     return $patchids($id)
 }
@@ -8140,18 +8222,16 @@ proc do_cmp_commits {a b} {
     clear_ctext
     init_flist {}
     for {set i 0} {$i < 100} {incr i} {
-       set shorta [string range $a 0 7]
-       set shortb [string range $b 0 7]
        set skipa 0
        set skipb 0
        if {[llength $parents($curview,$a)] > 1} {
-           appendwithlinks [mc "Skipping merge commit %s\n" $shorta] {}
+           appendshortlink $a [mc "Skipping merge commit "] "\n"
            set skipa 1
        } else {
            set patcha [getpatchid $a]
        }
        if {[llength $parents($curview,$b)] > 1} {
-           appendwithlinks [mc "Skipping merge commit %s\n" $shortb] {}
+           appendshortlink $b [mc "Skipping merge commit "] "\n"
            set skipb 1
        } else {
            set patchb [getpatchid $b]
@@ -8159,39 +8239,51 @@ proc do_cmp_commits {a b} {
        if {!$skipa && !$skipb} {
            set heada [lindex $commitinfo($a) 0]
            set headb [lindex $commitinfo($b) 0]
+           if {$patcha eq "error"} {
+               appendshortlink $a [mc "Error getting patch ID for "] \
+                   [mc " - stopping\n"]
+               break
+           }
+           if {$patchb eq "error"} {
+               appendshortlink $b [mc "Error getting patch ID for "] \
+                   [mc " - stopping\n"]
+               break
+           }
            if {$patcha eq $patchb} {
                if {$heada eq $headb} {
-                   appendwithlinks [mc "Commit %s == %s  %s\n" \
-                                        $shorta $shortb $heada] {}
+                   appendshortlink $a [mc "Commit "]
+                   appendshortlink $b " == " "  $heada\n"
                } else {
-                   appendwithlinks [mc "Commit %s  %s\n" $shorta $heada] {}
-                   appendwithlinks [mc " is the same patch as\n"] {}
-                   appendwithlinks [mc "       %s  %s\n" $shortb $headb] {}
+                   appendshortlink $a [mc "Commit "] "  $heada\n"
+                   appendshortlink $b [mc " is the same patch as\n       "] \
+                       "  $headb\n"
                }
                set skipa 1
                set skipb 1
            } else {
                $ctext insert end "\n"
-               appendwithlinks [mc "Commit %s  %s\n" $shorta $heada] {}
-               appendwithlinks [mc " differs from\n"] {}
-               appendwithlinks [mc "       %s  %s\n" $shortb $headb] {}
-               appendwithlinks [mc "- stopping\n"]
+               appendshortlink $a [mc "Commit "] "  $heada\n"
+               appendshortlink $b [mc " differs from\n       "] \
+                   "  $headb\n"
+               $ctext insert end [mc "- stopping\n"]
                break
            }
        }
        if {$skipa} {
            if {[llength $children($curview,$a)] != 1} {
                $ctext insert end "\n"
-               appendwithlinks [mc "Commit %s has %s children - stopping\n" \
-                                   $shorta [llength $children($curview,$a)]] {}
+               appendshortlink $a [mc "Commit "] \
+                   [mc " has %s children - stopping\n" \
+                        [llength $children($curview,$a)]]
                break
            }
            set a [lindex $children($curview,$a) 0]
        }
        if {$skipb} {
            if {[llength $children($curview,$b)] != 1} {
-               appendwithlinks [mc "Commit %s has %s children - stopping\n" \
-                                   $shortb [llength $children($curview,$b)]] {}
+               appendshortlink $b [mc "Commit "] \
+                   [mc " has %s children - stopping\n" \
+                        [llength $children($curview,$b)]]
                break
            }
            set b [lindex $children($curview,$b) 0]
@@ -11062,6 +11154,7 @@ set nullid2 "0000000000000000000000000000000000000001"
 set nullfile "/dev/null"
 
 set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+set git_version [join [lrange [split [lindex [exec git version] end] .] 0 2] .]
 
 set runq {}
 set history {}