{"thread":{"id":"34080","subject":"[PATCH gitk 0/4] gitk support for git log -L","startedAt":"2013-06-09T19:44:11Z","lastAt":"2013-12-01T22:25:26Z","messageCount":42,"participants":["Thomas Rast","Jens Lehmann","Paul Mackerras","Junio C Hamano","Jonathan Nieder"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"220150","messageId":"cover.1370806329.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":null,"subject":"[PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-06-09T19:44:11Z","receivedAt":"2013-06-09T19:44:11Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Now that git log -L has hit master, I figure it's time to discuss the\ncorresponding change to gitk.\n\nThe hard part is that AFAICS this is the first history display\naccessible through gitk that can only be computed in one go.  The\nexisting displays all work by having git-log perform a preliminary\nsearch for the involved commits (or in some cases, only part of the\nrange while we fetch more).  log -L has to compute all the diffs\nanyway, so nothing can be saved by attempting this; it is better to\nload everything in bulk from a single git-log invocation.\n\nThus, patches 1--3 implement the infrastructure required to be able to\nwork from a single git-log command.\n\nI would have loved to instead make a feature that also generalizes to\n\n  git log --parents <whatever> | gitk --read-stdin\n\n(or some other similar option).  This would make for much easier\ntesting of new git-log options.  Unfortunately this seems much harder\nto achieve in the current structure of gitk.\n\nNote: all my Tk-ing is computationally indistinguishable from cargo\nculting.  Please review with a grain of salt.\n\n\nThomas Rast (4):\n  gitk: refactor per-line part of getblobdiffline and its support\n  gitk: split out diff part in $commitinfo\n  gitk: support showing the gathered inline diffs\n  gitk: recognize -L option\n\n gitk | 462 ++++++++++++++++++++++++++++++++++++++-----------------------------\n 1 file changed, 266 insertions(+), 196 deletions(-)\n\n-- \n1.8.3.496.g0d0267b\n"},{"id":"220153","messageId":"dfa701201191471b86eb9e375537498971dafb6a.1370806329.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":"cover.1370806329.git.trast@inf.ethz.ch","subject":"[PATCH gitk 1/4] gitk: refactor per-line part of getblobdiffline and its support","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-06-09T19:44:12Z","receivedAt":"2013-06-09T19:44:12Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"For later use with data sources other than a pipe, refactor the big\nworker part of getblobdiffline to a separate function\nparseblobdiffline.  Also refactor its initialization and wrap-up to\nseparate routines.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 408 +++++++++++++++++++++++++++++++++++--------------------------------\n 1 file changed, 213 insertions(+), 195 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 5cd00d8..81dce20 100755\n--- a/gitk\n+++ b/gitk\n@@ -7710,15 +7710,25 @@ proc changeworddiff {name ix op} {\n     reselectline\n }\n \n+proc initblobdiffvars {} {\n+    global diffencoding targetline diffnparents\n+    global diffinhdr currdiffsubmod diffseehere\n+    set targetline {}\n+    set diffnparents 0\n+    set diffinhdr 0\n+    set diffencoding [get_path_encoding {}]\n+    set currdiffsubmod \"\"\n+    set diffseehere -1\n+}\n+\n proc getblobdiffs {ids} {\n     global blobdifffd diffids env\n-    global diffinhdr treediffs\n+    global treediffs\n     global diffcontext\n     global ignorespace\n     global worddiff\n     global limitdiffs vfilelimit curview\n-    global diffencoding targetline diffnparents\n-    global git_version currdiffsubmod\n+    global git_version\n \n     set textconv {}\n     if {[package vcompare $git_version \"1.6.1\"] >= 0} {\n@@ -7742,13 +7752,9 @@ proc getblobdiffs {ids} {\n \terror_popup [mc \"Error getting diffs: %s\" $err]\n \treturn\n     }\n-    set targetline {}\n-    set diffnparents 0\n-    set diffinhdr 0\n-    set diffencoding [get_path_encoding {}]\n     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}\n     set blobdifffd($ids) $bdf\n-    set currdiffsubmod \"\"\n+    initblobdiffvars\n     filerun $bdf [list getblobdiffline $bdf $diffids]\n }\n \n@@ -7814,13 +7820,17 @@ proc makediffhdr {fname ids} {\n     set diffline 0\n }\n \n+proc blobdiffmaybeseehere {ateof} {\n+    global diffseehere\n+    if {$diffseehere >= 0} {\n+\tmark_ctext_line [lindex [split $diffseehere .] 0]\n+    }\n+    maybe_scroll_ctext ateof\n+}\n+\n proc getblobdiffline {bdf ids} {\n-    global diffids blobdifffd ctext curdiffstart\n-    global diffnexthead diffnextnote difffilestart\n-    global ctext_file_names ctext_file_lines\n-    global diffinhdr treediffs mergemax diffnparents\n-    global diffencoding jump_to_here targetline diffline currdiffsubmod\n-    global worddiff\n+    global diffids blobdifffd\n+    global ctext\n \n     set nr 0\n     $ctext conf -state normal\n@@ -7829,212 +7839,220 @@ proc getblobdiffline {bdf ids} {\n \t    catch {close $bdf}\n \t    return 0\n \t}\n-\tif {![string compare -length 5 \"diff \" $line]} {\n-\t    if {![regexp {^diff (--cc|--git) } $line m type]} {\n-\t\tset line [encoding convertfrom $line]\n-\t\t$ctext insert end \"$line\\n\" hunksep\n-\t\tcontinue\n+\tparseblobdiffline $ids $line\n+    }\n+    $ctext conf -state disabled\n+    blobdiffmaybeseehere [eof $bdf]\n+    if {[eof $bdf]} {\n+\tcatch {close $bdf}\n+\treturn 0\n+    }\n+    return [expr {$nr >= 1000? 2: 1}]\n+}\n+\n+proc parseblobdiffline {ids line} {\n+    global ctext curdiffstart\n+    global diffnexthead diffnextnote difffilestart\n+    global ctext_file_names ctext_file_lines\n+    global diffinhdr treediffs mergemax diffnparents\n+    global diffencoding jump_to_here targetline diffline currdiffsubmod\n+    global worddiff diffseehere\n+\n+    if {![string compare -length 5 \"diff \" $line]} {\n+\tif {![regexp {^diff (--cc|--git) } $line m type]} {\n+\t    set line [encoding convertfrom $line]\n+\t    $ctext insert end \"$line\\n\" hunksep\n+\t    continue\n+\t}\n+\t# start of a new file\n+\tset diffinhdr 1\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"\\n\" filesep\n+\n+\tif {$type eq \"--cc\"} {\n+\t    # start of a new file in a merge diff\n+\t    set fname [string range $line 10 end]\n+\t    if {[lsearch -exact $treediffs($ids) $fname] < 0} {\n+\t\tlappend treediffs($ids) $fname\n+\t\tadd_flist [list $fname]\n \t    }\n-\t    # start of a new file\n-\t    set diffinhdr 1\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n-\t    $ctext insert end \"\\n\" filesep\n-\n-\t    if {$type eq \"--cc\"} {\n-\t\t# start of a new file in a merge diff\n-\t\tset fname [string range $line 10 end]\n-\t\tif {[lsearch -exact $treediffs($ids) $fname] < 0} {\n-\t\t    lappend treediffs($ids) $fname\n-\t\t    add_flist [list $fname]\n-\t\t}\n \n+\t} else {\n+\t    set line [string range $line 11 end]\n+\t    # If the name hasn't changed the length will be odd,\n+\t    # the middle char will be a space, and the two bits either\n+\t    # side will be a/name and b/name, or \"a/name\" and \"b/name\".\n+\t    # If the name has changed we'll get \"rename from\" and\n+\t    # \"rename to\" or \"copy from\" and \"copy to\" lines following\n+\t    # this, and we'll use them to get the filenames.\n+\t    # This complexity is necessary because spaces in the\n+\t    # filename(s) don't get escaped.\n+\t    set l [string length $line]\n+\t    set i [expr {$l / 2}]\n+\t    if {!(($l & 1) && [string index $line $i] eq \" \" &&\n+\t\t  [string range $line 2 [expr {$i - 1}]] eq \\\n+\t\t      [string range $line [expr {$i + 3}] end])} {\n+\t\treturn\n+\t    }\n+\t    # unescape if quoted and chop off the a/ from the front\n+\t    if {[string index $line 0] eq \"\\\"\"} {\n+\t\tset fname [string range [lindex $line 0] 2 end]\n \t    } else {\n-\t\tset line [string range $line 11 end]\n-\t\t# If the name hasn't changed the length will be odd,\n-\t\t# the middle char will be a space, and the two bits either\n-\t\t# side will be a/name and b/name, or \"a/name\" and \"b/name\".\n-\t\t# If the name has changed we'll get \"rename from\" and\n-\t\t# \"rename to\" or \"copy from\" and \"copy to\" lines following\n-\t\t# this, and we'll use them to get the filenames.\n-\t\t# This complexity is necessary because spaces in the\n-\t\t# filename(s) don't get escaped.\n-\t\tset l [string length $line]\n-\t\tset i [expr {$l / 2}]\n-\t\tif {!(($l & 1) && [string index $line $i] eq \" \" &&\n-\t\t      [string range $line 2 [expr {$i - 1}]] eq \\\n-\t\t\t  [string range $line [expr {$i + 3}] end])} {\n-\t\t    continue\n-\t\t}\n-\t\t# unescape if quoted and chop off the a/ from the front\n-\t\tif {[string index $line 0] eq \"\\\"\"} {\n-\t\t    set fname [string range [lindex $line 0] 2 end]\n-\t\t} else {\n-\t\t    set fname [string range $line 2 [expr {$i - 1}]]\n-\t\t}\n+\t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n-\t    makediffhdr $fname $ids\n+\t}\n+\tmakediffhdr $fname $ids\n \n-\t} elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n-\t    set fname [encoding convertfrom [string range $line 16 end]]\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names $fname\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+    } elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n+\tset fname [encoding convertfrom [string range $line 16 end]]\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names $fname\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"$line\\n\" filesep\n+\tset i [lsearch -exact $treediffs($ids) $fname]\n+\tif {$i >= 0} {\n+\t    setinlist difffilestart $i $curdiffstart\n+\t}\n+\n+    } elseif {![string compare -length 2 \"@@\" $line]} {\n+\tregexp {^@@+} $line ats\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" hunksep\n+\tif {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n+\t    set diffline $nl\n+\t}\n+\tset diffnparents [expr {[string length $ats] - 1}]\n+\tset diffinhdr 0\n+\n+    } elseif {![string compare -length 10 \"Submodule \" $line]} {\n+\t# start of a new submodule\n+\tif {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n+\t    set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n+\t} else {\n+\t    set fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n+\t}\n+\tif {$currdiffsubmod != $fname} {\n+\t    $ctext insert end \"\\n\";     # Add newline after commit message\n+\t}\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tif {$currdiffsubmod != $fname} {\n+\t    lappend ctext_file_lines $fname\n+\t    makediffhdr $fname $ids\n+\t    set currdiffsubmod $fname\n+\t    $ctext insert end \"\\n$line\\n\" filesep\n+\t} else {\n \t    $ctext insert end \"$line\\n\" filesep\n+\t}\n+    } elseif {![string compare -length 3 \"  >\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" dresult\n+    } elseif {![string compare -length 3 \"  <\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" d0\n+    } elseif {$diffinhdr} {\n+\tif {![string compare -length 12 \"rename from \" $line]} {\n+\t    set fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n+\t    }\n+\t    set fname [encoding convertfrom $fname]\n \t    set i [lsearch -exact $treediffs($ids) $fname]\n \t    if {$i >= 0} {\n \t\tsetinlist difffilestart $i $curdiffstart\n \t    }\n-\n-\t} elseif {![string compare -length 2 \"@@\" $line]} {\n-\t    regexp {^@@+} $line ats\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" hunksep\n-\t    if {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n-\t\tset diffline $nl\n+\t} elseif {![string compare -length 10 $line \"rename to \"] ||\n+\t\t  ![string compare -length 8 $line \"copy to \"]} {\n+\t    set fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n \t    }\n-\t    set diffnparents [expr {[string length $ats] - 1}]\n+\t    makediffhdr $fname $ids\n+\t} elseif {[string compare -length 3 $line \"---\"] == 0} {\n+\t    # do nothing\n+\t    return\n+\t} elseif {[string compare -length 3 $line \"+++\"] == 0} {\n \t    set diffinhdr 0\n+\t    return\n+\t}\n+\t$ctext insert end \"$line\\n\" filesep\n \n-\t} elseif {![string compare -length 10 \"Submodule \" $line]} {\n-\t    # start of a new submodule\n-\t    if {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n-\t\tset fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n-\t    } else {\n-\t\tset fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n-\t    }\n-\t    if {$currdiffsubmod != $fname} {\n-\t\t$ctext insert end \"\\n\";     # Add newline after commit message\n-\t    }\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    if {$currdiffsubmod != $fname} {\n-\t\tlappend ctext_file_lines $fname\n-\t\tmakediffhdr $fname $ids\n-\t\tset currdiffsubmod $fname\n-\t\t$ctext insert end \"\\n$line\\n\" filesep\n-\t    } else {\n-\t\t$ctext insert end \"$line\\n\" filesep\n-\t    }\n-\t} elseif {![string compare -length 3 \"  >\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" dresult\n-\t} elseif {![string compare -length 3 \"  <\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" d0\n-\t} elseif {$diffinhdr} {\n-\t    if {![string compare -length 12 \"rename from \" $line]} {\n-\t\tset fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n-\t\t}\n-\t\tset fname [encoding convertfrom $fname]\n-\t\tset i [lsearch -exact $treediffs($ids) $fname]\n-\t\tif {$i >= 0} {\n-\t\t    setinlist difffilestart $i $curdiffstart\n+    } else {\n+\tset line [string map {\\x1A ^Z} \\\n+\t\t      [encoding convertfrom $diffencoding $line]]\n+\t# parse the prefix - one ' ', '-' or '+' for each parent\n+\tset prefix [string range $line 0 [expr {$diffnparents - 1}]]\n+\tset tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n+\tset dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n+\tset words_pre_markup \"\"\n+\tset words_post_markup \"\"\n+\tif {[string trim $prefix \" -+\"] eq {}} {\n+\t    # prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n+\t    set num [string first \"-\" $prefix]\n+\t    if {$dowords} {\n+\t\tset line [string range $line 1 end]\n+\t    }\n+\t    if {$num >= 0} {\n+\t\t# removed line, first parent with line is $num\n+\t\tif {$num >= $mergemax} {\n+\t\t    set num \"max\"\n \t\t}\n-\t    } elseif {![string compare -length 10 $line \"rename to \"] ||\n-\t\t      ![string compare -length 8 $line \"copy to \"]} {\n-\t\tset fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"\\[-$line-\\]\" $tag$num\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tag$num\n \t\t}\n-\t\tmakediffhdr $fname $ids\n-\t    } elseif {[string compare -length 3 $line \"---\"] == 0} {\n-\t\t# do nothing\n-\t\tcontinue\n-\t    } elseif {[string compare -length 3 $line \"+++\"] == 0} {\n-\t\tset diffinhdr 0\n-\t\tcontinue\n-\t    }\n-\t    $ctext insert end \"$line\\n\" filesep\n-\n-\t} else {\n-\t    set line [string map {\\x1A ^Z} \\\n-                          [encoding convertfrom $diffencoding $line]]\n-\t    # parse the prefix - one ' ', '-' or '+' for each parent\n-\t    set prefix [string range $line 0 [expr {$diffnparents - 1}]]\n-\t    set tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n-\t    set dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n-\t    set words_pre_markup \"\"\n-\t    set words_post_markup \"\"\n-\t    if {[string trim $prefix \" -+\"] eq {}} {\n-\t\t# prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n-\t\tset num [string first \"-\" $prefix]\n-\t\tif {$dowords} {\n-\t\t    set line [string range $line 1 end]\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tag$num\n \t\t}\n-\t\tif {$num >= 0} {\n-\t\t    # removed line, first parent with line is $num\n-\t\t    if {$num >= $mergemax} {\n-\t\t\tset num \"max\"\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"\\[-$line-\\]\" $tag$num\n-\t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tag$num\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tag$num\n-\t\t    }\n-\t\t} else {\n-\t\t    set tags {}\n-\t\t    if {[string first \"+\" $prefix] >= 0} {\n-\t\t\t# added line\n-\t\t\tlappend tags ${tag}result\n-\t\t\tif {$diffnparents > 1} {\n-\t\t\t    set num [string first \" \" $prefix]\n-\t\t\t    if {$num >= 0} {\n-\t\t\t\tif {$num >= $mergemax} {\n-\t\t\t\t    set num \"max\"\n-\t\t\t\t}\n-\t\t\t\tlappend tags m$num\n+\t    } else {\n+\t\tset tags {}\n+\t\tif {[string first \"+\" $prefix] >= 0} {\n+\t\t    # added line\n+\t\t    lappend tags ${tag}result\n+\t\t    if {$diffnparents > 1} {\n+\t\t\tset num [string first \" \" $prefix]\n+\t\t\tif {$num >= 0} {\n+\t\t\t    if {$num >= $mergemax} {\n+\t\t\t\tset num \"max\"\n \t\t\t    }\n+\t\t\t    lappend tags m$num\n \t\t\t}\n-\t\t\tset words_pre_markup \"{+\"\n-\t\t\tset words_post_markup \"+}\"\n \t\t    }\n-\t\t    if {$targetline ne {}} {\n-\t\t\tif {$diffline == $targetline} {\n-\t\t\t    set seehere [$ctext index \"end - 1 chars\"]\n-\t\t\t    set targetline {}\n-\t\t\t} else {\n-\t\t\t    incr diffline\n-\t\t\t}\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t    set words_pre_markup \"{+\"\n+\t\t    set words_post_markup \"+}\"\n+\t\t}\n+\t\tif {$targetline ne {}} {\n+\t\t    if {$diffline == $targetline} {\n+\t\t\tset diffseehere [$ctext index \"end - 1 chars\"]\n+\t\t\tset targetline {}\n \t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tags\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tags\n+\t\t\tincr diffline\n \t\t    }\n \t\t}\n-\t    } elseif {$dowords && $prefix eq \"~\"} {\n-\t\t$ctext insert end \"\\n\" {}\n-\t    } else {\n-\t\t# \"\\ No newline at end of file\",\n-\t\t# or something else we don't recognize\n-\t\t$ctext insert end \"$line\\n\" hunksep\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tags\n+\t\t}\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tags\n+\t\t}\n \t    }\n+\t} elseif {$dowords && $prefix eq \"~\"} {\n+\t    $ctext insert end \"\\n\" {}\n+\t} else {\n+\t    # \"\\ No newline at end of file\",\n+\t    # or something else we don't recognize\n+\t    $ctext insert end \"$line\\n\" hunksep\n \t}\n     }\n-    if {[info exists seehere]} {\n-\tmark_ctext_line [lindex [split $seehere .] 0]\n-    }\n-    maybe_scroll_ctext [eof $bdf]\n-    $ctext conf -state disabled\n-    if {[eof $bdf]} {\n-\tcatch {close $bdf}\n-\treturn 0\n-    }\n-    return [expr {$nr >= 1000? 2: 1}]\n }\n \n proc changediffdisp {} {\n-- \n1.8.3.496.g0d0267b\n"},{"id":"220152","messageId":"d69e0570e081412e0fdc0d5cbf1ddbc32df09575.1370806329.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":"cover.1370806329.git.trast@inf.ethz.ch","subject":"[PATCH gitk 2/4] gitk: split out diff part in $commitinfo","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-06-09T19:44:13Z","receivedAt":"2013-06-09T19:44:13Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"So far we just parsed everything after the headers into the \"comment\"\nbit of $commitinfo, including notes and -- if you gave weird options\n-- the diff.\n\nSplit out the diff, if any, into a separate field.  It's easy to\nrecognize, since the log message is indented but the /^diff / that\nstarts a diff is not.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 8 +++++++-\n 1 file changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/gitk b/gitk\nindex 81dce20..261bda8 100755\n--- a/gitk\n+++ b/gitk\n@@ -1704,8 +1704,14 @@ proc parsecommit {id contents listed} {\n \tset comment $newcomment\n     }\n     set hasnote [string first \"\\nNotes:\\n\" $contents]\n+    set diff \"\"\n+    set i [string first \"\\ndiff\" $comment]\n+    if {$i >= 0} {\n+\tset diff [string range $comment $i end]\n+\tset comment [string range $comment 0 $i]\n+    }\n     set commitinfo($id) [list $headline $auname $audate \\\n-\t\t\t     $comname $comdate $comment $hasnote]\n+\t\t\t     $comname $comdate $comment $hasnote $diff]\n }\n \n proc getcommit {id} {\n-- \n1.8.3.496.g0d0267b\n"},{"id":"220154","messageId":"209fa0023dbb323e36665e37274adaefcd72c471.1370806329.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":"cover.1370806329.git.trast@inf.ethz.ch","subject":"[PATCH gitk 3/4] gitk: support showing the gathered inline diffs","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-06-09T19:44:14Z","receivedAt":"2013-06-09T19:44:14Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"The previous commit split the diffs into a separate field.  Now we\nactually want to show them.\n\nTo that end we use the stored diff, and\n\n- process it once to build a fake \"tree diff\", i.e., a list of all\n  changed files;\n\n- feed it through parseblobdiffline to actually format it into the\n  $ctext field, like the existing diff machinery would.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 38 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 38 insertions(+)\n\ndiff --git a/gitk b/gitk\nindex 261bda8..3715136 100755\n--- a/gitk\n+++ b/gitk\n@@ -156,10 +156,12 @@ proc unmerged_files {files} {\n \n proc parseviewargs {n arglist} {\n     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env\n+    global vinlinediff\n     global worddiff git_version\n \n     set vdatemode($n) 0\n     set vmergeonly($n) 0\n+    set vinlinediff($n) 0\n     set glflags {}\n     set diffargs {}\n     set nextisval 0\n@@ -7086,6 +7088,7 @@ proc selectline {l isnew {desired_loc {}}} {\n     global cmitmode showneartags allcommits\n     global targetrow targetid lastscrollrows\n     global autoselect autosellen jump_to_here\n+    global vinlinediff\n \n     catch {unset pending_select}\n     $canv delete hover\n@@ -7227,6 +7230,8 @@ proc selectline {l isnew {desired_loc {}}} {\n     init_flist [mc \"Comments\"]\n     if {$cmitmode eq \"tree\"} {\n \tgettree $id\n+    } elseif {$vinlinediff($curview) == 1} {\n+\tshowinlinediff $id\n     } elseif {[llength $olds] <= 1} {\n \tstartdiff $id\n     } else {\n@@ -7563,6 +7568,39 @@ proc startdiff {ids} {\n     }\n }\n \n+proc showinlinediff {ids} {\n+    global commitinfo commitdata ctext\n+    global treediffs\n+\n+    set info $commitinfo($ids)\n+    set diff [lindex $info 7]\n+    set difflines [split $diff \"\\n\"]\n+\n+    initblobdiffvars\n+    set treediff {}\n+\n+    set inhdr 0\n+    foreach line $difflines {\n+\tif {![string compare -length 5 \"diff \" $line]} {\n+\t    set inhdr 1\n+\t} elseif {$inhdr && ![string compare -length 4 \"+++ \" $line]} {\n+\t    # offset also accounts for the b/ prefix\n+\t    lappend treediff [string range $line 6 end]\n+\t    set inhdr 0\n+\t}\n+    }\n+\n+    set treediffs($ids) $treediff\n+    add_flist $treediff\n+\n+    $ctext conf -state normal\n+    foreach line $difflines {\n+\tparseblobdiffline $ids $line\n+    }\n+    maybe_scroll_ctext 1\n+    $ctext conf -state disabled\n+}\n+\n # If the filename (name) is under any of the passed filter paths\n # then return true to include the file in the listing.\n proc path_filter {filter name} {\n-- \n1.8.3.496.g0d0267b\n"},{"id":"220151","messageId":"a9d0af8f1266cad6edcabd4d8a54ef5d2bb87ab4.1370806329.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":"cover.1370806329.git.trast@inf.ethz.ch","subject":"[PATCH gitk 4/4] gitk: recognize -L option","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-06-09T19:44:15Z","receivedAt":"2013-06-09T19:44:15Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This gives line-log support to gitk, by exploiting the new support for\nprocessing and showing \"inline\" diffs straight from the git-log\noutput.\n\nNote that we 'set allknown 0', which is a bit counterintuitive since\nthis is a \"known\" option.  But that flag prevents gitk from thinking\nit can optimize the view by running rev-list to see the topology; in\nthe -L case that doesn't work.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/gitk b/gitk\nindex 3715136..30474be 100755\n--- a/gitk\n+++ b/gitk\n@@ -235,6 +235,14 @@ proc parseviewargs {n arglist} {\n \t\tset filtered 1\n \t\tlappend glflags $arg\n \t    }\n+\t    \"-L*\" {\n+\t\t# Line-diff: filtered, and diffs must be read as part\n+\t\t# of the log output\n+\t\tset filtered 1\n+\t\tset vinlinediff($n) 1\n+\t\tset allknown 0\n+\t\tlappend glflags $arg\n+\t    }\n \t    \"-n\" {\n \t\t# This appears to be the only one that has a value as a\n \t\t# separate word following it\n-- \n1.8.3.496.g0d0267b\n"},{"id":"223988","messageId":"874nblpamj.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"cover.1370806329.git.trast@inf.ethz.ch","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-07-23T15:19:16Z","receivedAt":"2013-07-23T15:19:16Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thomas Rast <trast@inf.ethz.ch> writes:\n\n> Now that git log -L has hit master, I figure it's time to discuss the\n> corresponding change to gitk.\n\nPaul, any news on this?  Any chance we can get it into the next release,\nsince that will also be the first release to ship with 'git log -L'?\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"224256","messageId":"874nbdnomj.fsf@hexa.v.cablecom.net","threadId":"34080","inReplyTo":"874nblpamj.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-07-29T19:37:56Z","receivedAt":"2013-07-29T19:37:56Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thomas Rast <trast@inf.ethz.ch> writes:\n\n> Thomas Rast <trast@inf.ethz.ch> writes:\n>\n>> Now that git log -L has hit master, I figure it's time to discuss the\n>> corresponding change to gitk.\n>\n> Paul, any news on this?  Any chance we can get it into the next release,\n> since that will also be the first release to ship with 'git log -L'?\n\nJens pointed out privately that the handling of unstuck -L options is\nunfortunate, to put it mildly.  I'll send a reroll.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"224263","messageId":"51F6CB7D.1070806@web.de","threadId":"34080","inReplyTo":"874nbdnomj.fsf@hexa.v.cablecom.net","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2013-07-29T20:07:25Z","receivedAt":"2013-07-29T20:07:25Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 29.07.2013 21:37, schrieb Thomas Rast:\n> Thomas Rast <trast@inf.ethz.ch> writes:\n> \n>> Thomas Rast <trast@inf.ethz.ch> writes:\n>>\n>>> Now that git log -L has hit master, I figure it's time to discuss the\n>>> corresponding change to gitk.\n>>\n>> Paul, any news on this?  Any chance we can get it into the next release,\n>> since that will also be the first release to ship with 'git log -L'?\n> \n> Jens pointed out privately that the handling of unstuck -L options is\n> unfortunate, to put it mildly.  I'll send a reroll.\n\nBut as soon as that is fixed I'd really like to see this applied, as\nI think gitk is the perfect tool to show history information.\n"},{"id":"224350","messageId":"87siyu98cq.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"51F6CB7D.1070806@web.de","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-07-31T13:17:41Z","receivedAt":"2013-07-31T13:17:41Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Jens Lehmann <Jens.Lehmann@web.de> writes:\n\n> Am 29.07.2013 21:37, schrieb Thomas Rast:\n>> Thomas Rast <trast@inf.ethz.ch> writes:\n>> \n>>> Thomas Rast <trast@inf.ethz.ch> writes:\n>>>\n>>>> Now that git log -L has hit master, I figure it's time to discuss the\n>>>> corresponding change to gitk.\n>>>\n>>> Paul, any news on this?  Any chance we can get it into the next release,\n>>> since that will also be the first release to ship with 'git log -L'?\n>> \n>> Jens pointed out privately that the handling of unstuck -L options is\n>> unfortunate, to put it mildly.  I'll send a reroll.\n>\n> But as soon as that is fixed I'd really like to see this applied, as\n> I think gitk is the perfect tool to show history information.\n\nUnfortunately it's turning out to be harder than I hoped.  gitk runs the\narguments through git-rev-parse, which only knows that -n gets an\nunstuck argument.  Consequently, gitk accepts an unstuck -n but only\nstuck forms of -S and -G.\n\nFixing it through git-rev-parse feels wrong; rev-parse is supposed to\nknow about rev-list options, but -S and -G only make sense in\ndiff-generating walks, and -L only makes any sense at all for git-log.\n\nI'm tempted to leave it at the existing patches for now.  That does mean\nthat -L can only be used in the stuck form; it's the same for -S and -G\nalready.  Then in a later series we can change gitk's argument parsing\nto properly treat the options directly, passing only the remaining\narguments through to rev-parse to use the usual revision/filename\ndistinction logic.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"225390","messageId":"20130818115456.GA6772@iris.ozlabs.ibm.com","threadId":"34080","inReplyTo":"87siyu98cq.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2013-08-18T11:54:57Z","receivedAt":"2013-08-18T11:54:57Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Hi Thomas,\n\nOn Wed, Jul 31, 2013 at 03:17:41PM +0200, Thomas Rast wrote:\n> Jens Lehmann <Jens.Lehmann@web.de> writes:\n> \n> > Am 29.07.2013 21:37, schrieb Thomas Rast:\n> >> Thomas Rast <trast@inf.ethz.ch> writes:\n> >> \n> >>> Thomas Rast <trast@inf.ethz.ch> writes:\n> >>>\n> >>>> Now that git log -L has hit master, I figure it's time to discuss the\n> >>>> corresponding change to gitk.\n> >>>\n> >>> Paul, any news on this?  Any chance we can get it into the next release,\n> >>> since that will also be the first release to ship with 'git log -L'?\n> >> \n> >> Jens pointed out privately that the handling of unstuck -L options is\n> >> unfortunate, to put it mildly.  I'll send a reroll.\n> >\n> > But as soon as that is fixed I'd really like to see this applied, as\n> > I think gitk is the perfect tool to show history information.\n\nOne thing I worry about is having gitk storing in memory not just the\nhistory graph but also all the diffs (assuming I have understood\ncorrectly what you're doing).  Gitk's memory consumption is already\npretty large.  However, I can't see an alternative at this point.\n\n> Unfortunately it's turning out to be harder than I hoped.  gitk runs the\n> arguments through git-rev-parse, which only knows that -n gets an\n> unstuck argument.  Consequently, gitk accepts an unstuck -n but only\n> stuck forms of -S and -G.\n\nExcuse my ignorance, but what do you mean by \"stuck\" vs. \"unstuck\"?\n\nThanks,\nPaul.\n"},{"id":"225449","messageId":"874namay5p.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"20130818115456.GA6772@iris.ozlabs.ibm.com","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-08-19T08:21:38Z","receivedAt":"2013-08-19T08:21:38Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Paul Mackerras <paulus@samba.org> writes:\n\n> Hi Thomas,\n>\n> On Wed, Jul 31, 2013 at 03:17:41PM +0200, Thomas Rast wrote:\n>> Jens Lehmann <Jens.Lehmann@web.de> writes:\n>> \n>> > Am 29.07.2013 21:37, schrieb Thomas Rast:\n>> >> Thomas Rast <trast@inf.ethz.ch> writes:\n>> >> \n>> >>> Thomas Rast <trast@inf.ethz.ch> writes:\n>> >>>\n>> >>>> Now that git log -L has hit master, I figure it's time to discuss the\n>> >>>> corresponding change to gitk.\n[...]\n>\n> One thing I worry about is having gitk storing in memory not just the\n> history graph but also all the diffs (assuming I have understood\n> correctly what you're doing).  Gitk's memory consumption is already\n> pretty large.  However, I can't see an alternative at this point.\n\nI don't think there is one.  log -L is pretty much an \"all or nothing\"\nthing at this point.  I suppose if we really found that the diffs are\nregularly too big to be manageable for gitk, we could invent a porcelain\nmode where 'log -L' just prints the detected commits and corresponding\nline ranges, and then have a new option to diff-tree to let it again\nfilter that range.\n\nBut note that ordinary 'git log -L' also buffers the entire set of diffs\nwithin less.  The memory consumption of gitk to hold the same diffs in\nmemory should be only a small factor of what less uses in the same\nscenario.  Furthermore, users will typically ask for a small region of\ncode (one function, or some such), so the diffs themselves are usually\nquite small, nowhere near the size of the full commit diffs.\n\n>> Unfortunately it's turning out to be harder than I hoped.  gitk runs the\n>> arguments through git-rev-parse, which only knows that -n gets an\n>> unstuck argument.  Consequently, gitk accepts an unstuck -n but only\n>> stuck forms of -S and -G.\n>\n> Excuse my ignorance, but what do you mean by \"stuck\" vs. \"unstuck\"?\n\nWhether the option value is a separate argument in argv, or directly\nstuck to the option.\n\nstuck:   gitk -L:foo:main.c\nunstuck: gitk -L :foo:main.c\n\nExisting gitk chokes on 'gitk -S foo', but works with 'git -Sfoo'.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"225469","messageId":"xmqq61v18u5s.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"874namay5p.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-08-19T17:30:55Z","receivedAt":"2013-08-19T17:30:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@inf.ethz.ch> writes:\n\n> Whether the option value is a separate argument in argv, or directly\n> stuck to the option.\n>\n> stuck:   gitk -L:foo:main.c\n> unstuck: gitk -L :foo:main.c\n>\n> Existing gitk chokes on 'gitk -S foo', but works with 'git -Sfoo'.\n\nI somehow thought that we encourage the \"stuck/sticked\" form, to\nreduce things the users need to remember to cope better with options\nwith optional value.\n"},{"id":"228893","messageId":"87k3hhadhj.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"xmqq61v18u5s.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-13T06:31:20Z","receivedAt":"2013-10-13T06:31:20Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Thomas Rast <trast@inf.ethz.ch> writes:\n>\n>> Whether the option value is a separate argument in argv, or directly\n>> stuck to the option.\n>>\n>> stuck:   gitk -L:foo:main.c\n>> unstuck: gitk -L :foo:main.c\n>>\n>> Existing gitk chokes on 'gitk -S foo', but works with 'git -Sfoo'.\n>\n> I somehow thought that we encourage the \"stuck/sticked\" form, to\n> reduce things the users need to remember to cope better with options\n> with optional value.\n\nI just looked into this again, to get it rolling.\n\nAm I reading you correctly as saying that any support for the unstuck\nform is entirely coincidental, and it's okay to support only the stuck\nversion in new gitk?\n\nNote that the support for 'git log -L' supports both, and it irks me\nthat the user can't switch back and forth between using 'gitk' and 'git\nlog' while leaving the rest of the command intact.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"228920","messageId":"20131014052547.GB25344@google.com","threadId":"34080","inReplyTo":"87k3hhadhj.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH gitk 0/4] gitk support for git log -L","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2013-10-14T05:25:48Z","receivedAt":"2013-10-14T05:25:48Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Thomas Rast wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>> Thomas Rast <trast@inf.ethz.ch> writes:\n\n>>> Existing gitk chokes on 'gitk -S foo', but works with 'git -Sfoo'.\n>>\n>> I somehow thought that we encourage the \"stuck/sticked\" form, to\n>> reduce things the users need to remember to cope better with options\n>> with optional value.\n>\n> I just looked into this again, to get it rolling.\n>\n> Am I reading you correctly as saying that any support for the unstuck\n> form is entirely coincidental, and it's okay to support only the stuck\n> version in new gitk?\n\nSort of. :)\n\ngitcli(7) says that the sticked form is to be preferred \"when you are\nscripting git\".  But most git commands use parse-options, which of\ncourse supports both forms and makes life easier for humans.\n\nSupport for just the sticked form is better than nothing, especially\nif the gitk(1) manpage gains a note about it.  In the long run I guess\nthe ideal would be to add a parse-options-like library to the tcl\nsupport.\n\nMy two cents,\nJonathan\n"},{"id":"229237","messageId":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","threadId":"34080","inReplyTo":"20131014052547.GB25344@google.com","subject":"[PATCH] Documentation: revamp gitk(1)","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-10-20T16:57:41Z","receivedAt":"2013-10-20T16:57:41Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"The gitk manpage suffers from a bit of neglect: there have been only\nminor changes, and no changes to the set of options documented, since\na2df1fb (Documentation: New GUI configuration and command-line\noptions., 2008-11-13).  In the meantime, the set of rev-list options\nhas been expanded several times by options that are useful in gitk,\ne.g., --ancestry-path and the optional globbing for --branches, --tags\nand --remotes.\n\nRestructure and expand the manpage.  List more options that the author\nperceives as useful, while remaining somewhat terse.  Ideally the user\nshould not have to look up any of the references, but we dispense with\nprecise explanations in some places and refer to git-log(1) instead.\n\nNote that the options that have an easy GUI equivalent (e.g.,\n--word-diff, -S, --grep) are deliberately not listed even in the cases\nwhere they simply fill in the GUI fields.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n\nJonathan Nieder wrote:\n> Support for just the sticked form is better than nothing, especially\n> if the gitk(1) manpage gains a note about it.  In the long run I guess\n> the ideal would be to add a parse-options-like library to the tcl\n> support.\n\nOk.  I'm generally not happy with the state of that manpage, so I took\nthe chance to improve it (and include a note about sticked forms).\nThe approach is really my own opinion; I ran a half-hearted attempt at\nan IRC survey but none of the willing victims had any 'gitk'\ninvocations in their history.\n\nI'll hold the gitk patches until we get this one sorted out, but then\njust do the sticked form as before.\n\n\n Documentation/gitk.txt | 107 ++++++++++++++++++++++++++++++++++++++-----------\n 1 file changed, 83 insertions(+), 24 deletions(-)\n\ndiff --git a/Documentation/gitk.txt b/Documentation/gitk.txt\nindex c17e760..d44e14c 100644\n--- a/Documentation/gitk.txt\n+++ b/Documentation/gitk.txt\n@@ -8,7 +8,7 @@ gitk - The Git repository browser\n SYNOPSIS\n --------\n [verse]\n-'gitk' [<option>...] [<revs>] [--] [<path>...]\n+'gitk' [<options>] [<revision range>] [\\--] [<path>...]\n \n DESCRIPTION\n -----------\n@@ -16,21 +16,38 @@ Displays changes in a repository or a selected set of commits. This includes\n visualizing the commit graph, showing information related to each commit, and\n the files in the trees of each revision.\n \n-Historically, gitk was the first repository browser. It's written in tcl/tk\n-and started off in a separate repository but was later merged into the main\n-Git repository.\n-\n OPTIONS\n -------\n-To control which revisions to show, the command takes options applicable to\n-the 'git rev-list' command (see linkgit:git-rev-list[1]).\n-This manual page describes only the most\n-frequently used options.\n \n--n <number>::\n---max-count=<number>::\n+To control which revisions to show, gitk supports most options\n+applicable to the 'git rev-list' command.  It also supports a few\n+options applicable to the 'git diff-*' commands to control how the\n+changes each commit introduces are shown.  Finally, it supports some\n+gitk-specific options.\n+\n+gitk generally only understands options with arguments in the\n+'sticked' form (see linkgit:gitcli[7]) due to limitations in the\n+command line parser.\n+\n+rev-list options and arguments\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+This manual page describes only the most frequently used options.  See\n+linkgit:git-rev-list[1] for a complete list.\n+\n+--all::\n+\n+\tShow all refs (branches, tags, etc.).\n \n-\tLimits the number of commits to show.\n+--branches[=<pattern>]::\n+--tags[=<pattern>]::\n+--remotes[=<pattern>]::\n+\n+\tPretend as if all the branches (tags, remote branches, resp.)\n+\tare listed on the command line as '<commit>'. If '<pattern>'\n+\tis given, limit refs to ones matching given shell glob. If\n+\tpattern lacks '?', '{asterisk}', or '[', '/{asterisk}' at the\n+\tend is implied.\n \n --since=<date>::\n \n@@ -40,9 +57,9 @@ frequently used options.\n \n \tShow commits older than a specific date.\n \n---all::\n+--date-order::\n \n-\tShow all branches.\n+\tSort commits by date when possible.\n \n --merge::\n \n@@ -51,19 +68,37 @@ frequently used options.\n \tthat modify the conflicted files and do not exist on all the heads\n \tbeing merged.\n \n---argscmd=<command>::\n-\tCommand to be run each time gitk has to determine the list of\n-\t<revs> to show.  The command is expected to print on its standard\n-\toutput a list of additional revs to be shown, one per line.\n-\tUse this instead of explicitly specifying <revs> if the set of\n-\tcommits to show may vary between refreshes.\n+--left-right::\n \n---select-commit=<ref>::\n+\tMark which side of a symmetric diff a commit is reachable\n+\tfrom.  Commits from the left side are prefixed with a `<`\n+\tsymbol and those from the right with a `>` symbol.\n \n-\tAutomatically select the specified commit after loading the graph.\n-\tDefault behavior is equivalent to specifying '--select-commit=HEAD'.\n+--full-history::\n+\n+\tWhen filtering history with '<path>...', does not prune some\n+\thistory.  (See \"History simplification\" in linkgit:git-log[1]\n+\tfor a more detailed explanation.)\n+\n+--simplify-merges::\n \n-<revs>::\n+\tAdditional option to '--full-history' to remove some needless\n+\tmerges from the resulting history, as there are no selected\n+\tcommits contributing to this merge.  (See \"History\n+\tsimplification\" in linkgit:git-log[1] for a more detailed\n+\texplanation.)\n+\n+--ancestry-path::\n+\n+\tWhen given a range of commits to display\n+\t(e.g. 'commit1..commit2' or 'commit2 {caret}commit1'), only\n+\tdisplay commits that exist directly on the ancestry chain\n+\tbetween the 'commit1' and 'commit2', i.e. commits that are\n+\tboth descendants of 'commit1', and ancestors of 'commit2'.\n+\t(See \"History simplification\" in linkgit:git-log[1] for a more\n+\tdetailed explanation.)\n+\n+<revision range>::\n \n \tLimit the revisions to show. This can be either a single revision\n \tmeaning show from the given revision and back, or it can be a range in\n@@ -78,6 +113,23 @@ frequently used options.\n \tavoid ambiguity with respect to revision names use \"--\" to separate the paths\n \tfrom any preceding options.\n \n+gitk-specific options\n+~~~~~~~~~~~~~~~~~~~~~\n+\n+--argscmd=<command>::\n+\n+\tCommand to be run each time gitk has to determine the revision\n+\trange to show.  The command is expected to print on its\n+\tstandard output a list of additional revisions to be shown,\n+\tone per line.  Use this instead of explicitly specifying a\n+\t'<revision range>' if the set of commits to show may vary\n+\tbetween refreshes.\n+\n+--select-commit=<ref>::\n+\n+\tSelect the specified commit after loading the graph.\n+\tDefault behavior is equivalent to specifying '--select-commit=HEAD'.\n+\n Examples\n --------\n gitk v2.6.12.. include/scsi drivers/scsi::\n@@ -101,6 +153,13 @@ Files\n Gitk creates the .gitk file in your $HOME directory to store preferences\n such as display options, font, and colors.\n \n+History\n+-------\n+Gitk was the first graphical repository browser. It's written in\n+tcl/tk and started off in a separate repository but was later merged\n+into the main Git repository.\n+\n+\n SEE ALSO\n --------\n 'qgit(1)'::\n-- \n1.8.4.1.810.g312044e\n"},{"id":"229708","messageId":"cover.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 0/7] gitk -L","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:33Z","receivedAt":"2013-10-29T07:20:33Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Thomas Rast wrote:\n> Jonathan Nieder wrote:\n> > Support for just the sticked form is better than nothing, especially\n> > if the gitk(1) manpage gains a note about it.  In the long run I guess\n> > the ideal would be to add a parse-options-like library to the tcl\n> > support.\n> \n> Ok.  I'm generally not happy with the state of that manpage, so I took\n> the chance to improve it.\n> [...]\n> I'll hold the gitk patches until we get this one sorted out, but then\n> just do the sticked form as before.\n\nOk, there weren't any comments and this patch is in 'next', so here's\ngitk -L built on top of it.\n\nI'm sending this as a single topic, but once agreement is reached, it\nhas to be applied in two parts: the gitk patches (1-5) need to be\nsubtree-rebased to match gitk.git, and then merged separately, while\nthe documentation patches (6&7) need to be applied directly.  The\nlatter depend on the patch I'm replying to.\n\nChanges since v1:\n\n* 1/7 is new; while investigating the sticked/unsticked issue, I\n  noticed that -G is not even supported by gitk.\n\n* 3/7 has improved snipping logic, to get rid of an extra empty line\n  before the diff\n\n* 5/7 has a slightly different comment pointing out that this is only\n  the sticked form of -L\n\n* 6&7 are new, to resolve the sticky issue\n\n\nThomas Rast (7):\n  gitk: support -G option from the command line\n  gitk: refactor per-line part of getblobdiffline and its support\n  gitk: split out diff part in $commitinfo\n  gitk: support showing the gathered inline diffs\n  gitk: recognize -L option\n  Documentation: put blame/log -L in sticked form\n  Documentation/gitk: document -L option\n\n Documentation/blame-options.txt |   8 +-\n Documentation/git-blame.txt     |   8 +-\n Documentation/git-log.txt       |   6 +-\n Documentation/gitk.txt          |  12 ++\n gitk-git/gitk                   | 467 +++++++++++++++++++++++-----------------\n 5 files changed, 293 insertions(+), 208 deletions(-)\n\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229702","messageId":"72ba9e0cd862a2fb014d0633802f9afbb0bea27d.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 1/7] gitk: support -G option from the command line","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:34Z","receivedAt":"2013-10-29T07:20:34Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThe -G option's usage is exactly analogous to that of -S, so\nsupporting it is easy.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk-git/gitk | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 5cd00d8..0e95814 100755\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -227,7 +227,7 @@ proc parseviewargs {n arglist} {\n \t    \"--until=*\" - \"--before=*\" - \"--max-age=*\" - \"--min-age=*\" -\n \t    \"--author=*\" - \"--committer=*\" - \"--grep=*\" - \"-[iE]\" -\n \t    \"--remove-empty\" - \"--first-parent\" - \"--cherry-pick\" -\n-\t    \"-S*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n+\t    \"-S*\" - \"-G*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n \t    \"--simplify-by-decoration\" {\n \t\t# These mean that we get a subset of the commits\n \t\tset filtered 1\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229706","messageId":"584093ef3fafbae8dfb9b99d7d9a146fb3939619.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 2/7] gitk: refactor per-line part of getblobdiffline and its support","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:35Z","receivedAt":"2013-10-29T07:20:35Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nFor later use with data sources other than a pipe, refactor the big\nworker part of getblobdiffline to a separate function\nparseblobdiffline.  Also refactor its initialization and wrap-up to\nseparate routines.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk-git/gitk | 408 ++++++++++++++++++++++++++++++----------------------------\n 1 file changed, 213 insertions(+), 195 deletions(-)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 0e95814..11e988e 100755\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -7710,15 +7710,25 @@ proc changeworddiff {name ix op} {\n     reselectline\n }\n \n+proc initblobdiffvars {} {\n+    global diffencoding targetline diffnparents\n+    global diffinhdr currdiffsubmod diffseehere\n+    set targetline {}\n+    set diffnparents 0\n+    set diffinhdr 0\n+    set diffencoding [get_path_encoding {}]\n+    set currdiffsubmod \"\"\n+    set diffseehere -1\n+}\n+\n proc getblobdiffs {ids} {\n     global blobdifffd diffids env\n-    global diffinhdr treediffs\n+    global treediffs\n     global diffcontext\n     global ignorespace\n     global worddiff\n     global limitdiffs vfilelimit curview\n-    global diffencoding targetline diffnparents\n-    global git_version currdiffsubmod\n+    global git_version\n \n     set textconv {}\n     if {[package vcompare $git_version \"1.6.1\"] >= 0} {\n@@ -7742,13 +7752,9 @@ proc getblobdiffs {ids} {\n \terror_popup [mc \"Error getting diffs: %s\" $err]\n \treturn\n     }\n-    set targetline {}\n-    set diffnparents 0\n-    set diffinhdr 0\n-    set diffencoding [get_path_encoding {}]\n     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}\n     set blobdifffd($ids) $bdf\n-    set currdiffsubmod \"\"\n+    initblobdiffvars\n     filerun $bdf [list getblobdiffline $bdf $diffids]\n }\n \n@@ -7814,13 +7820,17 @@ proc makediffhdr {fname ids} {\n     set diffline 0\n }\n \n+proc blobdiffmaybeseehere {ateof} {\n+    global diffseehere\n+    if {$diffseehere >= 0} {\n+\tmark_ctext_line [lindex [split $diffseehere .] 0]\n+    }\n+    maybe_scroll_ctext ateof\n+}\n+\n proc getblobdiffline {bdf ids} {\n-    global diffids blobdifffd ctext curdiffstart\n-    global diffnexthead diffnextnote difffilestart\n-    global ctext_file_names ctext_file_lines\n-    global diffinhdr treediffs mergemax diffnparents\n-    global diffencoding jump_to_here targetline diffline currdiffsubmod\n-    global worddiff\n+    global diffids blobdifffd\n+    global ctext\n \n     set nr 0\n     $ctext conf -state normal\n@@ -7829,212 +7839,220 @@ proc getblobdiffline {bdf ids} {\n \t    catch {close $bdf}\n \t    return 0\n \t}\n-\tif {![string compare -length 5 \"diff \" $line]} {\n-\t    if {![regexp {^diff (--cc|--git) } $line m type]} {\n-\t\tset line [encoding convertfrom $line]\n-\t\t$ctext insert end \"$line\\n\" hunksep\n-\t\tcontinue\n+\tparseblobdiffline $ids $line\n+    }\n+    $ctext conf -state disabled\n+    blobdiffmaybeseehere [eof $bdf]\n+    if {[eof $bdf]} {\n+\tcatch {close $bdf}\n+\treturn 0\n+    }\n+    return [expr {$nr >= 1000? 2: 1}]\n+}\n+\n+proc parseblobdiffline {ids line} {\n+    global ctext curdiffstart\n+    global diffnexthead diffnextnote difffilestart\n+    global ctext_file_names ctext_file_lines\n+    global diffinhdr treediffs mergemax diffnparents\n+    global diffencoding jump_to_here targetline diffline currdiffsubmod\n+    global worddiff diffseehere\n+\n+    if {![string compare -length 5 \"diff \" $line]} {\n+\tif {![regexp {^diff (--cc|--git) } $line m type]} {\n+\t    set line [encoding convertfrom $line]\n+\t    $ctext insert end \"$line\\n\" hunksep\n+\t    continue\n+\t}\n+\t# start of a new file\n+\tset diffinhdr 1\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"\\n\" filesep\n+\n+\tif {$type eq \"--cc\"} {\n+\t    # start of a new file in a merge diff\n+\t    set fname [string range $line 10 end]\n+\t    if {[lsearch -exact $treediffs($ids) $fname] < 0} {\n+\t\tlappend treediffs($ids) $fname\n+\t\tadd_flist [list $fname]\n \t    }\n-\t    # start of a new file\n-\t    set diffinhdr 1\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n-\t    $ctext insert end \"\\n\" filesep\n-\n-\t    if {$type eq \"--cc\"} {\n-\t\t# start of a new file in a merge diff\n-\t\tset fname [string range $line 10 end]\n-\t\tif {[lsearch -exact $treediffs($ids) $fname] < 0} {\n-\t\t    lappend treediffs($ids) $fname\n-\t\t    add_flist [list $fname]\n-\t\t}\n \n+\t} else {\n+\t    set line [string range $line 11 end]\n+\t    # If the name hasn't changed the length will be odd,\n+\t    # the middle char will be a space, and the two bits either\n+\t    # side will be a/name and b/name, or \"a/name\" and \"b/name\".\n+\t    # If the name has changed we'll get \"rename from\" and\n+\t    # \"rename to\" or \"copy from\" and \"copy to\" lines following\n+\t    # this, and we'll use them to get the filenames.\n+\t    # This complexity is necessary because spaces in the\n+\t    # filename(s) don't get escaped.\n+\t    set l [string length $line]\n+\t    set i [expr {$l / 2}]\n+\t    if {!(($l & 1) && [string index $line $i] eq \" \" &&\n+\t\t  [string range $line 2 [expr {$i - 1}]] eq \\\n+\t\t      [string range $line [expr {$i + 3}] end])} {\n+\t\treturn\n+\t    }\n+\t    # unescape if quoted and chop off the a/ from the front\n+\t    if {[string index $line 0] eq \"\\\"\"} {\n+\t\tset fname [string range [lindex $line 0] 2 end]\n \t    } else {\n-\t\tset line [string range $line 11 end]\n-\t\t# If the name hasn't changed the length will be odd,\n-\t\t# the middle char will be a space, and the two bits either\n-\t\t# side will be a/name and b/name, or \"a/name\" and \"b/name\".\n-\t\t# If the name has changed we'll get \"rename from\" and\n-\t\t# \"rename to\" or \"copy from\" and \"copy to\" lines following\n-\t\t# this, and we'll use them to get the filenames.\n-\t\t# This complexity is necessary because spaces in the\n-\t\t# filename(s) don't get escaped.\n-\t\tset l [string length $line]\n-\t\tset i [expr {$l / 2}]\n-\t\tif {!(($l & 1) && [string index $line $i] eq \" \" &&\n-\t\t      [string range $line 2 [expr {$i - 1}]] eq \\\n-\t\t\t  [string range $line [expr {$i + 3}] end])} {\n-\t\t    continue\n-\t\t}\n-\t\t# unescape if quoted and chop off the a/ from the front\n-\t\tif {[string index $line 0] eq \"\\\"\"} {\n-\t\t    set fname [string range [lindex $line 0] 2 end]\n-\t\t} else {\n-\t\t    set fname [string range $line 2 [expr {$i - 1}]]\n-\t\t}\n+\t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n-\t    makediffhdr $fname $ids\n+\t}\n+\tmakediffhdr $fname $ids\n \n-\t} elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n-\t    set fname [encoding convertfrom [string range $line 16 end]]\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names $fname\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+    } elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n+\tset fname [encoding convertfrom [string range $line 16 end]]\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names $fname\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"$line\\n\" filesep\n+\tset i [lsearch -exact $treediffs($ids) $fname]\n+\tif {$i >= 0} {\n+\t    setinlist difffilestart $i $curdiffstart\n+\t}\n+\n+    } elseif {![string compare -length 2 \"@@\" $line]} {\n+\tregexp {^@@+} $line ats\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" hunksep\n+\tif {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n+\t    set diffline $nl\n+\t}\n+\tset diffnparents [expr {[string length $ats] - 1}]\n+\tset diffinhdr 0\n+\n+    } elseif {![string compare -length 10 \"Submodule \" $line]} {\n+\t# start of a new submodule\n+\tif {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n+\t    set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n+\t} else {\n+\t    set fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n+\t}\n+\tif {$currdiffsubmod != $fname} {\n+\t    $ctext insert end \"\\n\";     # Add newline after commit message\n+\t}\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tif {$currdiffsubmod != $fname} {\n+\t    lappend ctext_file_lines $fname\n+\t    makediffhdr $fname $ids\n+\t    set currdiffsubmod $fname\n+\t    $ctext insert end \"\\n$line\\n\" filesep\n+\t} else {\n \t    $ctext insert end \"$line\\n\" filesep\n+\t}\n+    } elseif {![string compare -length 3 \"  >\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" dresult\n+    } elseif {![string compare -length 3 \"  <\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" d0\n+    } elseif {$diffinhdr} {\n+\tif {![string compare -length 12 \"rename from \" $line]} {\n+\t    set fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n+\t    }\n+\t    set fname [encoding convertfrom $fname]\n \t    set i [lsearch -exact $treediffs($ids) $fname]\n \t    if {$i >= 0} {\n \t\tsetinlist difffilestart $i $curdiffstart\n \t    }\n-\n-\t} elseif {![string compare -length 2 \"@@\" $line]} {\n-\t    regexp {^@@+} $line ats\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" hunksep\n-\t    if {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n-\t\tset diffline $nl\n+\t} elseif {![string compare -length 10 $line \"rename to \"] ||\n+\t\t  ![string compare -length 8 $line \"copy to \"]} {\n+\t    set fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n \t    }\n-\t    set diffnparents [expr {[string length $ats] - 1}]\n+\t    makediffhdr $fname $ids\n+\t} elseif {[string compare -length 3 $line \"---\"] == 0} {\n+\t    # do nothing\n+\t    return\n+\t} elseif {[string compare -length 3 $line \"+++\"] == 0} {\n \t    set diffinhdr 0\n+\t    return\n+\t}\n+\t$ctext insert end \"$line\\n\" filesep\n \n-\t} elseif {![string compare -length 10 \"Submodule \" $line]} {\n-\t    # start of a new submodule\n-\t    if {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n-\t\tset fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n-\t    } else {\n-\t\tset fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n-\t    }\n-\t    if {$currdiffsubmod != $fname} {\n-\t\t$ctext insert end \"\\n\";     # Add newline after commit message\n-\t    }\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    if {$currdiffsubmod != $fname} {\n-\t\tlappend ctext_file_lines $fname\n-\t\tmakediffhdr $fname $ids\n-\t\tset currdiffsubmod $fname\n-\t\t$ctext insert end \"\\n$line\\n\" filesep\n-\t    } else {\n-\t\t$ctext insert end \"$line\\n\" filesep\n-\t    }\n-\t} elseif {![string compare -length 3 \"  >\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" dresult\n-\t} elseif {![string compare -length 3 \"  <\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" d0\n-\t} elseif {$diffinhdr} {\n-\t    if {![string compare -length 12 \"rename from \" $line]} {\n-\t\tset fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n-\t\t}\n-\t\tset fname [encoding convertfrom $fname]\n-\t\tset i [lsearch -exact $treediffs($ids) $fname]\n-\t\tif {$i >= 0} {\n-\t\t    setinlist difffilestart $i $curdiffstart\n+    } else {\n+\tset line [string map {\\x1A ^Z} \\\n+\t\t      [encoding convertfrom $diffencoding $line]]\n+\t# parse the prefix - one ' ', '-' or '+' for each parent\n+\tset prefix [string range $line 0 [expr {$diffnparents - 1}]]\n+\tset tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n+\tset dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n+\tset words_pre_markup \"\"\n+\tset words_post_markup \"\"\n+\tif {[string trim $prefix \" -+\"] eq {}} {\n+\t    # prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n+\t    set num [string first \"-\" $prefix]\n+\t    if {$dowords} {\n+\t\tset line [string range $line 1 end]\n+\t    }\n+\t    if {$num >= 0} {\n+\t\t# removed line, first parent with line is $num\n+\t\tif {$num >= $mergemax} {\n+\t\t    set num \"max\"\n \t\t}\n-\t    } elseif {![string compare -length 10 $line \"rename to \"] ||\n-\t\t      ![string compare -length 8 $line \"copy to \"]} {\n-\t\tset fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"\\[-$line-\\]\" $tag$num\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tag$num\n \t\t}\n-\t\tmakediffhdr $fname $ids\n-\t    } elseif {[string compare -length 3 $line \"---\"] == 0} {\n-\t\t# do nothing\n-\t\tcontinue\n-\t    } elseif {[string compare -length 3 $line \"+++\"] == 0} {\n-\t\tset diffinhdr 0\n-\t\tcontinue\n-\t    }\n-\t    $ctext insert end \"$line\\n\" filesep\n-\n-\t} else {\n-\t    set line [string map {\\x1A ^Z} \\\n-                          [encoding convertfrom $diffencoding $line]]\n-\t    # parse the prefix - one ' ', '-' or '+' for each parent\n-\t    set prefix [string range $line 0 [expr {$diffnparents - 1}]]\n-\t    set tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n-\t    set dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n-\t    set words_pre_markup \"\"\n-\t    set words_post_markup \"\"\n-\t    if {[string trim $prefix \" -+\"] eq {}} {\n-\t\t# prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n-\t\tset num [string first \"-\" $prefix]\n-\t\tif {$dowords} {\n-\t\t    set line [string range $line 1 end]\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tag$num\n \t\t}\n-\t\tif {$num >= 0} {\n-\t\t    # removed line, first parent with line is $num\n-\t\t    if {$num >= $mergemax} {\n-\t\t\tset num \"max\"\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"\\[-$line-\\]\" $tag$num\n-\t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tag$num\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tag$num\n-\t\t    }\n-\t\t} else {\n-\t\t    set tags {}\n-\t\t    if {[string first \"+\" $prefix] >= 0} {\n-\t\t\t# added line\n-\t\t\tlappend tags ${tag}result\n-\t\t\tif {$diffnparents > 1} {\n-\t\t\t    set num [string first \" \" $prefix]\n-\t\t\t    if {$num >= 0} {\n-\t\t\t\tif {$num >= $mergemax} {\n-\t\t\t\t    set num \"max\"\n-\t\t\t\t}\n-\t\t\t\tlappend tags m$num\n+\t    } else {\n+\t\tset tags {}\n+\t\tif {[string first \"+\" $prefix] >= 0} {\n+\t\t    # added line\n+\t\t    lappend tags ${tag}result\n+\t\t    if {$diffnparents > 1} {\n+\t\t\tset num [string first \" \" $prefix]\n+\t\t\tif {$num >= 0} {\n+\t\t\t    if {$num >= $mergemax} {\n+\t\t\t\tset num \"max\"\n \t\t\t    }\n+\t\t\t    lappend tags m$num\n \t\t\t}\n-\t\t\tset words_pre_markup \"{+\"\n-\t\t\tset words_post_markup \"+}\"\n \t\t    }\n-\t\t    if {$targetline ne {}} {\n-\t\t\tif {$diffline == $targetline} {\n-\t\t\t    set seehere [$ctext index \"end - 1 chars\"]\n-\t\t\t    set targetline {}\n-\t\t\t} else {\n-\t\t\t    incr diffline\n-\t\t\t}\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t    set words_pre_markup \"{+\"\n+\t\t    set words_post_markup \"+}\"\n+\t\t}\n+\t\tif {$targetline ne {}} {\n+\t\t    if {$diffline == $targetline} {\n+\t\t\tset diffseehere [$ctext index \"end - 1 chars\"]\n+\t\t\tset targetline {}\n \t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tags\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tags\n+\t\t\tincr diffline\n \t\t    }\n \t\t}\n-\t    } elseif {$dowords && $prefix eq \"~\"} {\n-\t\t$ctext insert end \"\\n\" {}\n-\t    } else {\n-\t\t# \"\\ No newline at end of file\",\n-\t\t# or something else we don't recognize\n-\t\t$ctext insert end \"$line\\n\" hunksep\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tags\n+\t\t}\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tags\n+\t\t}\n \t    }\n+\t} elseif {$dowords && $prefix eq \"~\"} {\n+\t    $ctext insert end \"\\n\" {}\n+\t} else {\n+\t    # \"\\ No newline at end of file\",\n+\t    # or something else we don't recognize\n+\t    $ctext insert end \"$line\\n\" hunksep\n \t}\n     }\n-    if {[info exists seehere]} {\n-\tmark_ctext_line [lindex [split $seehere .] 0]\n-    }\n-    maybe_scroll_ctext [eof $bdf]\n-    $ctext conf -state disabled\n-    if {[eof $bdf]} {\n-\tcatch {close $bdf}\n-\treturn 0\n-    }\n-    return [expr {$nr >= 1000? 2: 1}]\n }\n \n proc changediffdisp {} {\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229707","messageId":"9b4daa449f4cb8228f75477f0d32826edfc401cd.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 3/7] gitk: split out diff part in $commitinfo","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:36Z","receivedAt":"2013-10-29T07:20:36Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nSo far we just parsed everything after the headers into the \"comment\"\nbit of $commitinfo, including notes and -- if you gave weird options\n-- the diff.\n\nSplit out the diff, if any, into a separate field.  It's easy to\nrecognize, since it always starts with /^diff/ and is preceded by an\nempty line.\n\nWe take care to snip away said empty line.  The display code already\nproperly spaces the end of the message from the first diff, and\nleaving another empty line at the end looks ugly.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk-git/gitk | 11 ++++++++++-\n 1 file changed, 10 insertions(+), 1 deletion(-)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 11e988e..78b4354 100755\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -1704,8 +1704,17 @@ proc parsecommit {id contents listed} {\n \tset comment $newcomment\n     }\n     set hasnote [string first \"\\nNotes:\\n\" $contents]\n+    set diff \"\"\n+    # If there is diff output shown in the git-log stream, split it\n+    # out.  But get rid of the empty line that always precedes the\n+    # diff.\n+    set i [string first \"\\n\\ndiff\" $comment]\n+    if {$i >= 0} {\n+\tset diff [string range $comment $i+1 end]\n+\tset comment [string range $comment 0 $i-1]\n+    }\n     set commitinfo($id) [list $headline $auname $audate \\\n-\t\t\t     $comname $comdate $comment $hasnote]\n+\t\t\t     $comname $comdate $comment $hasnote $diff]\n }\n \n proc getcommit {id} {\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229709","messageId":"67b991439fe06519e69cf6594497ac1d2cf06228.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 4/7] gitk: support showing the gathered inline diffs","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:37Z","receivedAt":"2013-10-29T07:20:37Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThe previous commit split the diffs into a separate field.  Now we\nactually want to show them.\n\nTo that end we use the stored diff, and\n\n- process it once to build a fake \"tree diff\", i.e., a list of all\n  changed files;\n\n- feed it through parseblobdiffline to actually format it into the\n  $ctext field, like the existing diff machinery would.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk-git/gitk | 38 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 38 insertions(+)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 78b4354..5ece2a1 100755\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -156,10 +156,12 @@ proc unmerged_files {files} {\n \n proc parseviewargs {n arglist} {\n     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env\n+    global vinlinediff\n     global worddiff git_version\n \n     set vdatemode($n) 0\n     set vmergeonly($n) 0\n+    set vinlinediff($n) 0\n     set glflags {}\n     set diffargs {}\n     set nextisval 0\n@@ -7089,6 +7091,7 @@ proc selectline {l isnew {desired_loc {}}} {\n     global cmitmode showneartags allcommits\n     global targetrow targetid lastscrollrows\n     global autoselect autosellen jump_to_here\n+    global vinlinediff\n \n     catch {unset pending_select}\n     $canv delete hover\n@@ -7230,6 +7233,8 @@ proc selectline {l isnew {desired_loc {}}} {\n     init_flist [mc \"Comments\"]\n     if {$cmitmode eq \"tree\"} {\n \tgettree $id\n+    } elseif {$vinlinediff($curview) == 1} {\n+\tshowinlinediff $id\n     } elseif {[llength $olds] <= 1} {\n \tstartdiff $id\n     } else {\n@@ -7566,6 +7571,39 @@ proc startdiff {ids} {\n     }\n }\n \n+proc showinlinediff {ids} {\n+    global commitinfo commitdata ctext\n+    global treediffs\n+\n+    set info $commitinfo($ids)\n+    set diff [lindex $info 7]\n+    set difflines [split $diff \"\\n\"]\n+\n+    initblobdiffvars\n+    set treediff {}\n+\n+    set inhdr 0\n+    foreach line $difflines {\n+\tif {![string compare -length 5 \"diff \" $line]} {\n+\t    set inhdr 1\n+\t} elseif {$inhdr && ![string compare -length 4 \"+++ \" $line]} {\n+\t    # offset also accounts for the b/ prefix\n+\t    lappend treediff [string range $line 6 end]\n+\t    set inhdr 0\n+\t}\n+    }\n+\n+    set treediffs($ids) $treediff\n+    add_flist $treediff\n+\n+    $ctext conf -state normal\n+    foreach line $difflines {\n+\tparseblobdiffline $ids $line\n+    }\n+    maybe_scroll_ctext 1\n+    $ctext conf -state disabled\n+}\n+\n # If the filename (name) is under any of the passed filter paths\n # then return true to include the file in the listing.\n proc path_filter {filter name} {\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229705","messageId":"41fc155e3b020e6aa899b97bc936e198865ff4f6.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 5/7] gitk: recognize -L option","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:38Z","receivedAt":"2013-10-29T07:20:38Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThis gives line-log support to gitk, by exploiting the new support for\nprocessing and showing \"inline\" diffs straight from the git-log\noutput.\n\nNote that we 'set allknown 0', which is a bit counterintuitive since\nthis is a \"known\" option.  But that flag prevents gitk from thinking\nit can optimize the view by running rev-list to see the topology; in\nthe -L case that doesn't work.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk-git/gitk | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/gitk-git/gitk b/gitk-git/gitk\nindex 5ece2a1..3679467 100755\n--- a/gitk-git/gitk\n+++ b/gitk-git/gitk\n@@ -235,6 +235,14 @@ proc parseviewargs {n arglist} {\n \t\tset filtered 1\n \t\tlappend glflags $arg\n \t    }\n+\t    \"-L*\" {\n+\t\t# Line-log with 'sticked' argument (unsticked form is\n+\t\t# not supported)\n+\t\tset filtered 1\n+\t\tset vinlinediff($n) 1\n+\t\tset allknown 0\n+\t\tlappend glflags $arg\n+\t    }\n \t    \"-n\" {\n \t\t# This appears to be the only one that has a value as a\n \t\t# separate word following it\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229703","messageId":"c41aef218951f8b0ec6a20e1dbc39712ad13afce.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:39Z","receivedAt":"2013-10-29T07:20:39Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"The next patch will document gitk -L, but gitk does not understand the\nseparated form ('gitk -L :foo:bar' results in an error).  Spell\ngit-blame and git-log -L, which are supposed to be \"the same\" option,\nwithout the spaces to prevent confusion.\n\nSigned-off-by: Thomas Rast <tr@thomasrast.ch>\n---\n Documentation/blame-options.txt | 8 ++++----\n Documentation/git-blame.txt     | 8 ++++----\n Documentation/git-log.txt       | 6 +++---\n 3 files changed, 11 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt\nindex 0cebc4f..28ca95e 100644\n--- a/Documentation/blame-options.txt\n+++ b/Documentation/blame-options.txt\n@@ -9,13 +9,13 @@\n --show-stats::\n \tInclude additional statistics at the end of blame output.\n \n--L <start>,<end>::\n--L :<regex>::\n+-L<start>,<end>::\n+-L:<regex>::\n \tAnnotate only the given line range. May be specified multiple times.\n \tOverlapping ranges are allowed.\n +\n-<start> and <end> are optional. ``-L <start>'' or ``-L <start>,'' spans from\n-<start> to end of file. ``-L ,<end>'' spans from start of file to <end>.\n+<start> and <end> are optional. ``-L<start>'' or ``-L<start>,'' spans from\n+<start> to end of file. ``-L,<end>'' spans from start of file to <end>.\n +\n include::line-range-format.txt[]\n \ndiff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt\nindex f2c85cc..085dba1 100644\n--- a/Documentation/git-blame.txt\n+++ b/Documentation/git-blame.txt\n@@ -9,7 +9,7 @@ SYNOPSIS\n --------\n [verse]\n 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]\n-\t    [-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]\n+\t    [-L<range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]\n \t    [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>\n \n DESCRIPTION\n@@ -139,12 +139,12 @@ lines 40-60 for file `foo`, you can use the `-L` option like so\n (they mean the same thing -- both ask for 21 lines starting at\n line 40):\n \n-\tgit blame -L 40,60 foo\n-\tgit blame -L 40,+21 foo\n+\tgit blame -L40,60 foo\n+\tgit blame -L40,+21 foo\n \n Also you can use a regular expression to specify the line range:\n \n-\tgit blame -L '/^sub hello {/,/^}$/' foo\n+\tgit blame -L'/^sub hello {/,/^}$/' foo\n \n which limits the annotation to the body of the `hello` subroutine.\n \ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex 34097ef..87c10fa 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -62,8 +62,8 @@ produced by --stat etc.\n \tNote that only message is considered, if also a diff is shown\n \tits size is not included.\n \n--L <start>,<end>:<file>::\n--L :<regex>:<file>::\n+-L<start>,<end>:<file>::\n+-L:<regex>:<file>::\n \n \tTrace the evolution of the line range given by \"<start>,<end>\"\n \t(or the funcname regex <regex>) within the <file>.  You may\n@@ -152,7 +152,7 @@ EXAMPLES\n \tThis makes sense only when following a strict policy of merging all\n \ttopic branches when staying on a single integration branch.\n \n-`git log -L '/int main/',/^}/:main.c`::\n+`git log -L'/int main/',/^}/:main.c`::\n \n \tShows how the function `main()` in the file 'main.c' evolved\n \tover time.\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229704","messageId":"a84be3909ad7aed43f937f7547e7f238d6ee67ea.1383031141.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"21f40508f83a9407986d29f002adf5ad366c8b88.1382287779.git.trast@inf.ethz.ch","subject":"[PATCH v2 7/7] Documentation/gitk: document -L option","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-29T07:20:40Z","receivedAt":"2013-10-29T07:20:40Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"The -L option is the same as for git-log, so the entire block is just\ncopied from git-log.txt.\n\nSigned-off-by: Thomas Rast <tr@thomasrast.ch>\n---\n Documentation/gitk.txt | 12 ++++++++++++\n 1 file changed, 12 insertions(+)\n\ndiff --git a/Documentation/gitk.txt b/Documentation/gitk.txt\nindex d44e14c..0f1c7f8 100644\n--- a/Documentation/gitk.txt\n+++ b/Documentation/gitk.txt\n@@ -98,6 +98,18 @@ linkgit:git-rev-list[1] for a complete list.\n \t(See \"History simplification\" in linkgit:git-log[1] for a more\n \tdetailed explanation.)\n \n+-L<start>,<end>:<file>::\n+-L:<regex>:<file>::\n+\n+\tTrace the evolution of the line range given by \"<start>,<end>\"\n+\t(or the funcname regex <regex>) within the <file>.  You may\n+\tnot give any pathspec limiters.  This is currently limited to\n+\ta walk starting from a single revision, i.e., you may only\n+\tgive zero or one positive revision arguments.\n+\tYou can specify this option more than once.\n++\n+include::line-range-format.txt[]\n+\n <revision range>::\n \n \tLimit the revisions to show. This can be either a single revision\n-- \n1.8.4.2.838.ga9a3e20\n"},{"id":"229750","messageId":"xmqqzjprd1ge.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"72ba9e0cd862a2fb014d0633802f9afbb0bea27d.1383031141.git.tr@thomasrast.ch","subject":"Re: [PATCH v2 1/7] gitk: support -G option from the command line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-10-30T00:52:49Z","receivedAt":"2013-10-30T00:52:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> From: Thomas Rast <trast@inf.ethz.ch>\n>\n> The -G option's usage is exactly analogous to that of -S, so\n> supporting it is easy.\n>\n> Signed-off-by: Thomas Rast <trast@inf.ethz.ch>\n> ---\n>  gitk-git/gitk | 2 +-\n\nYou CC'ed Paul, which is absolutely the right thing to do, but\nplease make patches against his tree, which does not have gitk-git/\ndirectory at the top-level.\n\nI think the patch itself makes sense.\n\nThanks.\n\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/gitk-git/gitk b/gitk-git/gitk\n> index 5cd00d8..0e95814 100755\n> --- a/gitk-git/gitk\n> +++ b/gitk-git/gitk\n> @@ -227,7 +227,7 @@ proc parseviewargs {n arglist} {\n>  \t    \"--until=*\" - \"--before=*\" - \"--max-age=*\" - \"--min-age=*\" -\n>  \t    \"--author=*\" - \"--committer=*\" - \"--grep=*\" - \"-[iE]\" -\n>  \t    \"--remove-empty\" - \"--first-parent\" - \"--cherry-pick\" -\n> -\t    \"-S*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n> +\t    \"-S*\" - \"-G*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n>  \t    \"--simplify-by-decoration\" {\n>  \t\t# These mean that we get a subset of the commits\n>  \t\tset filtered 1\n"},{"id":"229751","messageId":"xmqqvc0fd0la.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"c41aef218951f8b0ec6a20e1dbc39712ad13afce.1383031141.git.tr@thomasrast.ch","subject":"Re: [PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-10-30T01:11:29Z","receivedAt":"2013-10-30T01:11:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> The next patch will document gitk -L, but gitk does not understand the\n> separated form ('gitk -L :foo:bar' results in an error).  Spell\n> git-blame and git-log -L, which are supposed to be \"the same\" option,\n> without the spaces to prevent confusion.\n\nI agree that this patch may reduce confusion locally, but if we were\nto go in this direction, we should be consistent and enforce \"stuck\"\nform everywhere, not just the options you happened to have passed\nthru to gitk, but other options such as \"-S <revs-file>\", and also\nother commands that do not have anything to do with gitk (e.g. \"git\ncommit -C<commit>\", not \"git commit -C <commit>\".  Otherwise you\nwill give a wrong impression to readers as if they have to remember\nwhich ones need to use the stuck form and which ones do not.\n\n> Signed-off-by: Thomas Rast <tr@thomasrast.ch>\n> ---\n>  Documentation/blame-options.txt | 8 ++++----\n>  Documentation/git-blame.txt     | 8 ++++----\n>  Documentation/git-log.txt       | 6 +++---\n>  3 files changed, 11 insertions(+), 11 deletions(-)\n>\n> diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt\n> index 0cebc4f..28ca95e 100644\n> --- a/Documentation/blame-options.txt\n> +++ b/Documentation/blame-options.txt\n> @@ -9,13 +9,13 @@\n>  --show-stats::\n>  \tInclude additional statistics at the end of blame output.\n>  \n> --L <start>,<end>::\n> --L :<regex>::\n> +-L<start>,<end>::\n> +-L:<regex>::\n>  \tAnnotate only the given line range. May be specified multiple times.\n>  \tOverlapping ranges are allowed.\n>  +\n> -<start> and <end> are optional. ``-L <start>'' or ``-L <start>,'' spans from\n> -<start> to end of file. ``-L ,<end>'' spans from start of file to <end>.\n> +<start> and <end> are optional. ``-L<start>'' or ``-L<start>,'' spans from\n> +<start> to end of file. ``-L,<end>'' spans from start of file to <end>.\n>  +\n>  include::line-range-format.txt[]\n>  \n> diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt\n> index f2c85cc..085dba1 100644\n> --- a/Documentation/git-blame.txt\n> +++ b/Documentation/git-blame.txt\n> @@ -9,7 +9,7 @@ SYNOPSIS\n>  --------\n>  [verse]\n>  'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]\n> -\t    [-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]\n> +\t    [-L<range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]\n>  \t    [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>\n>  \n>  DESCRIPTION\n> @@ -139,12 +139,12 @@ lines 40-60 for file `foo`, you can use the `-L` option like so\n>  (they mean the same thing -- both ask for 21 lines starting at\n>  line 40):\n>  \n> -\tgit blame -L 40,60 foo\n> -\tgit blame -L 40,+21 foo\n> +\tgit blame -L40,60 foo\n> +\tgit blame -L40,+21 foo\n>  \n>  Also you can use a regular expression to specify the line range:\n>  \n> -\tgit blame -L '/^sub hello {/,/^}$/' foo\n> +\tgit blame -L'/^sub hello {/,/^}$/' foo\n>  \n>  which limits the annotation to the body of the `hello` subroutine.\n>  \n> diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\n> index 34097ef..87c10fa 100644\n> --- a/Documentation/git-log.txt\n> +++ b/Documentation/git-log.txt\n> @@ -62,8 +62,8 @@ produced by --stat etc.\n>  \tNote that only message is considered, if also a diff is shown\n>  \tits size is not included.\n>  \n> --L <start>,<end>:<file>::\n> --L :<regex>:<file>::\n> +-L<start>,<end>:<file>::\n> +-L:<regex>:<file>::\n>  \n>  \tTrace the evolution of the line range given by \"<start>,<end>\"\n>  \t(or the funcname regex <regex>) within the <file>.  You may\n> @@ -152,7 +152,7 @@ EXAMPLES\n>  \tThis makes sense only when following a strict policy of merging all\n>  \ttopic branches when staying on a single integration branch.\n>  \n> -`git log -L '/int main/',/^}/:main.c`::\n> +`git log -L'/int main/',/^}/:main.c`::\n>  \n>  \tShows how the function `main()` in the file 'main.c' evolved\n>  \tover time.\n"},{"id":"229779","messageId":"87bo27i85i.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"xmqqvc0fd0la.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-30T06:29:13Z","receivedAt":"2013-10-30T06:29:13Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Thomas Rast <tr@thomasrast.ch> writes:\n>\n>> The next patch will document gitk -L, but gitk does not understand the\n>> separated form ('gitk -L :foo:bar' results in an error).  Spell\n>> git-blame and git-log -L, which are supposed to be \"the same\" option,\n>> without the spaces to prevent confusion.\n>\n> I agree that this patch may reduce confusion locally, but if we were\n> to go in this direction, we should be consistent and enforce \"stuck\"\n> form everywhere, not just the options you happened to have passed\n> thru to gitk, but other options such as \"-S <revs-file>\", and also\n> other commands that do not have anything to do with gitk (e.g. \"git\n> commit -C<commit>\", not \"git commit -C <commit>\".  Otherwise you\n> will give a wrong impression to readers as if they have to remember\n> which ones need to use the stuck form and which ones do not.\n\nHmm.  Do you want to go there?\n\n(I can do it, but it'll obviously touch a lot of documentation.)\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"229780","messageId":"8738nji83k.fsf@linux-k42r.v.cablecom.net","threadId":"34080","inReplyTo":"xmqqzjprd1ge.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 1/7] gitk: support -G option from the command line","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-30T06:30:23Z","receivedAt":"2013-10-30T06:30:23Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Thomas Rast <tr@thomasrast.ch> writes:\n>\n>> From: Thomas Rast <trast@inf.ethz.ch>\n>>\n>> The -G option's usage is exactly analogous to that of -S, so\n>> supporting it is easy.\n>>\n>> Signed-off-by: Thomas Rast <trast@inf.ethz.ch>\n>> ---\n>>  gitk-git/gitk | 2 +-\n>\n> You CC'ed Paul, which is absolutely the right thing to do, but\n> please make patches against his tree, which does not have gitk-git/\n> directory at the top-level.\n\nI figured this was easier on potential testers.  As outlined in the\ncover letter, I'll do the splitting and rebasing later.\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"229828","messageId":"xmqqmwlqd827.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"8738nji83k.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH v2 1/7] gitk: support -G option from the command line","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-10-30T16:42:24Z","receivedAt":"2013-10-30T16:42:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> I figured this was easier on potential testers.  As outlined in the\n> cover letter, I'll do the splitting and rebasing later.\n\nSorry, I should have read 0/7 before responding, but the message\ncame out of order.\n"},{"id":"229832","messageId":"xmqqiowed6t3.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"87bo27i85i.fsf@linux-k42r.v.cablecom.net","subject":"Re: [PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-10-30T17:09:28Z","receivedAt":"2013-10-30T17:09:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Thomas Rast <tr@thomasrast.ch> writes:\n>>\n>>> The next patch will document gitk -L, but gitk does not understand the\n>>> separated form ('gitk -L :foo:bar' results in an error).  Spell\n>>> git-blame and git-log -L, which are supposed to be \"the same\" option,\n>>> without the spaces to prevent confusion.\n>>\n>> I agree that this patch may reduce confusion locally, but if we were\n>> to go in this direction, we should be consistent and enforce \"stuck\"\n>> form everywhere, not just the options you happened to have passed\n>> thru to gitk, but other options such as \"-S <revs-file>\", and also\n>> other commands that do not have anything to do with gitk (e.g. \"git\n>> commit -C<commit>\", not \"git commit -C <commit>\".  Otherwise you\n>> will give a wrong impression to readers as if they have to remember\n>> which ones need to use the stuck form and which ones do not.\n>\n> Hmm.  Do you want to go there?\n\nAbsolutely not ;-)\n\nBut that unpleasant place would be the logical conclusion where this\npatch leads us to, I would have to say. I was hoping that there is\nan alternative solution to avoid that.\n\nFor example, gitk's parseviewargs is very well aware of the options\nit supports, and it goes through the argument list one by one,\nacting on what option it is looking at. Couldn't it be extended to\nhandle options with stuck and unstuck form?  After all, it has to\nknow that \"-L\" and \"-S\" are supported options; it wouldn't be too\nmuch to ask for the parser to also know that \"-L\" eats the next\ntoken (i.e. pass the pair <\"-L\", next token> intact as two separate\nargs to the underlying \"log\") while it can pass \"-L?*\" as is, no?\n"},{"id":"229849","messageId":"874n7ywpnd.fsf@thomasrast.ch","threadId":"34080","inReplyTo":"xmqqiowed6t3.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-10-30T18:59:50Z","receivedAt":"2013-10-30T18:59:50Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Thomas Rast <tr@thomasrast.ch> writes:\n>\n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> I agree that this patch may reduce confusion locally, but if we were\n>>> to go in this direction, we should be consistent and enforce \"stuck\"\n>>> form everywhere,\n>>\n>> Hmm.  Do you want to go there?\n>\n> Absolutely not ;-)\n>\n> But that unpleasant place would be the logical conclusion where this\n> patch leads us to, I would have to say. I was hoping that there is\n> an alternative solution to avoid that.\n>\n> For example, gitk's parseviewargs is very well aware of the options\n> it supports, and it goes through the argument list one by one,\n> acting on what option it is looking at. Couldn't it be extended to\n> handle options with stuck and unstuck form?  After all, it has to\n> know that \"-L\" and \"-S\" are supported options; it wouldn't be too\n> much to ask for the parser to also know that \"-L\" eats the next\n> token (i.e. pass the pair <\"-L\", next token> intact as two separate\n> args to the underlying \"log\") while it can pass \"-L?*\" as is, no?\n\nIt's not quite that easy because gitk does two-stage processing, and the\nbig switch you are discussing here is only the second one.  The first\none is git-rev-parse, and while it happens to know about '-n 1', it does\nnot recognize any other unstuck option arguments.  (I haven't stared too\nlong, but I think git-rev-parse is important to distinguish revisions\nfrom paths.)\n\nI actually burned some train time today looking into this, and the\nsituation is much worse than I thought.  There is absolutely no\nconsistency in any dimension:\n\na) many commands use parse_options internally, where mandatory args can\n   be stuck or unstuck, but optional args must be stuck\n\n   a1) git branch --{contains,merged,no-merged} take a mandatory arg,\n       except if they are last on the command line, in which case the\n       option reverts to the default (HEAD).  Effectively this means the\n       argument is half-optional but the spelling seen in the wild is\n       usually unstuck.\n\n   a2) git-rev-parse (at least) still handrolls its parsing, so no\n       --default=HEAD\n\n   a3) git-commit-tree does not understand any of its short options in\n       stuck form (!)\n\nb) the perl scripts mostly seem to be using Getopt::Long which handles\n   things similarly, though I can't quote chapter&verse\n\n   b1) just to prove a point: git-add--interactive.  I'm sure there's a\n       user-facing exception somewhere too...\n\nc) shell scripts mostly go through git-sh-setup, using parseopt\n   internally\n\n   c1) git-filter-branch\n\nd) gitk doesn't do *un*stuck as explained above\n\nOn top of that, documentation is a wild mash of styles, sometimes even\nin the same manpage.  For example, git-describe(1) tells the poor user\nabout --candidates=<n> and four paragraphs further down about --match\n<pattern>.\n\nSo my short-term plan just became: document instead of fix; clean up\nmanpages towards the stuck form for long options; have gitk only parse\n-Lstuck.\n\nMedium term we can move gitk to a different option parser, resolving at\nleast that inconsistency.\n\nLonger term we can see about moving some more of the remaining craziness\ntowards parseopt, getting consistency for free.\n\n-- \nThomas Rast\ntr@thomasrast.ch\n"},{"id":"229856","messageId":"xmqqa9hqbldk.fsf@gitster.dls.corp.google.com","threadId":"34080","inReplyTo":"874n7ywpnd.fsf@thomasrast.ch","subject":"Re: [PATCH v2 6/7] Documentation: put blame/log -L in sticked form","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-10-30T19:37:43Z","receivedAt":"2013-10-30T19:37:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <tr@thomasrast.ch> writes:\n\n> So my short-term plan just became: document instead of fix; clean up\n> manpages towards the stuck form for long options; have gitk only parse\n> -Lstuck.\n>\n> Medium term we can move gitk to a different option parser, resolving at\n> least that inconsistency.\n>\n> Longer term we can see about moving some more of the remaining craziness\n> towards parseopt, getting consistency for free.\n\nIn that sensible context, the patch sounds in line with the\nshort-term step.  Thanks.\n"},{"id":"230703","messageId":"cover.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"874n7ywpnd.fsf@thomasrast.ch","subject":"[PATCH v3 gitk 0/5] gitk -L","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:39Z","receivedAt":"2013-11-16T17:37:39Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"These patches implement 'gitk -L'.  They are exactly the same as the\ngitk patches from v2 at\n\n  http://thread.gmane.org/gmane.comp.version-control.git/227151/focus=236903\n\nexcept that they apply to the gitk-git tree at\n\n  git://ozlabs.org/~paulus/gitk\n\nThe documentation change is in the parallel series that will appear at\n\n  http://mid.gmane.org/cover.1384622379.git.tr@thomasrast.ch\n\n\nThomas Rast (5):\n  gitk: support -G option from the command line\n  gitk: refactor per-line part of getblobdiffline and its support\n  gitk: split out diff part in $commitinfo\n  gitk: support showing the gathered inline diffs\n  gitk: recognize -L option\n\n gitk | 467 +++++++++++++++++++++++++++++++++++++++----------------------------\n 1 file changed, 270 insertions(+), 197 deletions(-)\n\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230701","messageId":"9e872334f7842124db313178a8f9452f56098c96.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"[PATCH v3 gitk 1/5] gitk: support -G option from the command line","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:40Z","receivedAt":"2013-11-16T17:37:40Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThe -G option's usage is exactly analogous to that of -S, so\nsupporting it is easy.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/gitk b/gitk\nindex 5cd00d8..0e95814 100755\n--- a/gitk\n+++ b/gitk\n@@ -227,7 +227,7 @@ proc parseviewargs {n arglist} {\n \t    \"--until=*\" - \"--before=*\" - \"--max-age=*\" - \"--min-age=*\" -\n \t    \"--author=*\" - \"--committer=*\" - \"--grep=*\" - \"-[iE]\" -\n \t    \"--remove-empty\" - \"--first-parent\" - \"--cherry-pick\" -\n-\t    \"-S*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n+\t    \"-S*\" - \"-G*\" - \"--pickaxe-all\" - \"--pickaxe-regex\" -\n \t    \"--simplify-by-decoration\" {\n \t\t# These mean that we get a subset of the commits\n \t\tset filtered 1\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230707","messageId":"1df186f26b35de38ca1c55034edd29fb2ddef510.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"[PATCH v3 gitk 2/5] gitk: refactor per-line part of getblobdiffline and its support","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:41Z","receivedAt":"2013-11-16T17:37:41Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nFor later use with data sources other than a pipe, refactor the big\nworker part of getblobdiffline to a separate function\nparseblobdiffline.  Also refactor its initialization and wrap-up to\nseparate routines.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 408 +++++++++++++++++++++++++++++++++++--------------------------------\n 1 file changed, 213 insertions(+), 195 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex 0e95814..11e988e 100755\n--- a/gitk\n+++ b/gitk\n@@ -7710,15 +7710,25 @@ proc changeworddiff {name ix op} {\n     reselectline\n }\n \n+proc initblobdiffvars {} {\n+    global diffencoding targetline diffnparents\n+    global diffinhdr currdiffsubmod diffseehere\n+    set targetline {}\n+    set diffnparents 0\n+    set diffinhdr 0\n+    set diffencoding [get_path_encoding {}]\n+    set currdiffsubmod \"\"\n+    set diffseehere -1\n+}\n+\n proc getblobdiffs {ids} {\n     global blobdifffd diffids env\n-    global diffinhdr treediffs\n+    global treediffs\n     global diffcontext\n     global ignorespace\n     global worddiff\n     global limitdiffs vfilelimit curview\n-    global diffencoding targetline diffnparents\n-    global git_version currdiffsubmod\n+    global git_version\n \n     set textconv {}\n     if {[package vcompare $git_version \"1.6.1\"] >= 0} {\n@@ -7742,13 +7752,9 @@ proc getblobdiffs {ids} {\n \terror_popup [mc \"Error getting diffs: %s\" $err]\n \treturn\n     }\n-    set targetline {}\n-    set diffnparents 0\n-    set diffinhdr 0\n-    set diffencoding [get_path_encoding {}]\n     fconfigure $bdf -blocking 0 -encoding binary -eofchar {}\n     set blobdifffd($ids) $bdf\n-    set currdiffsubmod \"\"\n+    initblobdiffvars\n     filerun $bdf [list getblobdiffline $bdf $diffids]\n }\n \n@@ -7814,13 +7820,17 @@ proc makediffhdr {fname ids} {\n     set diffline 0\n }\n \n+proc blobdiffmaybeseehere {ateof} {\n+    global diffseehere\n+    if {$diffseehere >= 0} {\n+\tmark_ctext_line [lindex [split $diffseehere .] 0]\n+    }\n+    maybe_scroll_ctext ateof\n+}\n+\n proc getblobdiffline {bdf ids} {\n-    global diffids blobdifffd ctext curdiffstart\n-    global diffnexthead diffnextnote difffilestart\n-    global ctext_file_names ctext_file_lines\n-    global diffinhdr treediffs mergemax diffnparents\n-    global diffencoding jump_to_here targetline diffline currdiffsubmod\n-    global worddiff\n+    global diffids blobdifffd\n+    global ctext\n \n     set nr 0\n     $ctext conf -state normal\n@@ -7829,212 +7839,220 @@ proc getblobdiffline {bdf ids} {\n \t    catch {close $bdf}\n \t    return 0\n \t}\n-\tif {![string compare -length 5 \"diff \" $line]} {\n-\t    if {![regexp {^diff (--cc|--git) } $line m type]} {\n-\t\tset line [encoding convertfrom $line]\n-\t\t$ctext insert end \"$line\\n\" hunksep\n-\t\tcontinue\n+\tparseblobdiffline $ids $line\n+    }\n+    $ctext conf -state disabled\n+    blobdiffmaybeseehere [eof $bdf]\n+    if {[eof $bdf]} {\n+\tcatch {close $bdf}\n+\treturn 0\n+    }\n+    return [expr {$nr >= 1000? 2: 1}]\n+}\n+\n+proc parseblobdiffline {ids line} {\n+    global ctext curdiffstart\n+    global diffnexthead diffnextnote difffilestart\n+    global ctext_file_names ctext_file_lines\n+    global diffinhdr treediffs mergemax diffnparents\n+    global diffencoding jump_to_here targetline diffline currdiffsubmod\n+    global worddiff diffseehere\n+\n+    if {![string compare -length 5 \"diff \" $line]} {\n+\tif {![regexp {^diff (--cc|--git) } $line m type]} {\n+\t    set line [encoding convertfrom $line]\n+\t    $ctext insert end \"$line\\n\" hunksep\n+\t    continue\n+\t}\n+\t# start of a new file\n+\tset diffinhdr 1\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"\\n\" filesep\n+\n+\tif {$type eq \"--cc\"} {\n+\t    # start of a new file in a merge diff\n+\t    set fname [string range $line 10 end]\n+\t    if {[lsearch -exact $treediffs($ids) $fname] < 0} {\n+\t\tlappend treediffs($ids) $fname\n+\t\tadd_flist [list $fname]\n \t    }\n-\t    # start of a new file\n-\t    set diffinhdr 1\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n-\t    $ctext insert end \"\\n\" filesep\n-\n-\t    if {$type eq \"--cc\"} {\n-\t\t# start of a new file in a merge diff\n-\t\tset fname [string range $line 10 end]\n-\t\tif {[lsearch -exact $treediffs($ids) $fname] < 0} {\n-\t\t    lappend treediffs($ids) $fname\n-\t\t    add_flist [list $fname]\n-\t\t}\n \n+\t} else {\n+\t    set line [string range $line 11 end]\n+\t    # If the name hasn't changed the length will be odd,\n+\t    # the middle char will be a space, and the two bits either\n+\t    # side will be a/name and b/name, or \"a/name\" and \"b/name\".\n+\t    # If the name has changed we'll get \"rename from\" and\n+\t    # \"rename to\" or \"copy from\" and \"copy to\" lines following\n+\t    # this, and we'll use them to get the filenames.\n+\t    # This complexity is necessary because spaces in the\n+\t    # filename(s) don't get escaped.\n+\t    set l [string length $line]\n+\t    set i [expr {$l / 2}]\n+\t    if {!(($l & 1) && [string index $line $i] eq \" \" &&\n+\t\t  [string range $line 2 [expr {$i - 1}]] eq \\\n+\t\t      [string range $line [expr {$i + 3}] end])} {\n+\t\treturn\n+\t    }\n+\t    # unescape if quoted and chop off the a/ from the front\n+\t    if {[string index $line 0] eq \"\\\"\"} {\n+\t\tset fname [string range [lindex $line 0] 2 end]\n \t    } else {\n-\t\tset line [string range $line 11 end]\n-\t\t# If the name hasn't changed the length will be odd,\n-\t\t# the middle char will be a space, and the two bits either\n-\t\t# side will be a/name and b/name, or \"a/name\" and \"b/name\".\n-\t\t# If the name has changed we'll get \"rename from\" and\n-\t\t# \"rename to\" or \"copy from\" and \"copy to\" lines following\n-\t\t# this, and we'll use them to get the filenames.\n-\t\t# This complexity is necessary because spaces in the\n-\t\t# filename(s) don't get escaped.\n-\t\tset l [string length $line]\n-\t\tset i [expr {$l / 2}]\n-\t\tif {!(($l & 1) && [string index $line $i] eq \" \" &&\n-\t\t      [string range $line 2 [expr {$i - 1}]] eq \\\n-\t\t\t  [string range $line [expr {$i + 3}] end])} {\n-\t\t    continue\n-\t\t}\n-\t\t# unescape if quoted and chop off the a/ from the front\n-\t\tif {[string index $line 0] eq \"\\\"\"} {\n-\t\t    set fname [string range [lindex $line 0] 2 end]\n-\t\t} else {\n-\t\t    set fname [string range $line 2 [expr {$i - 1}]]\n-\t\t}\n+\t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n-\t    makediffhdr $fname $ids\n+\t}\n+\tmakediffhdr $fname $ids\n \n-\t} elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n-\t    set fname [encoding convertfrom [string range $line 16 end]]\n-\t    $ctext insert end \"\\n\"\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names $fname\n-\t    lappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+    } elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n+\tset fname [encoding convertfrom [string range $line 16 end]]\n+\t$ctext insert end \"\\n\"\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names $fname\n+\tlappend ctext_file_lines [lindex [split $curdiffstart \".\"] 0]\n+\t$ctext insert end \"$line\\n\" filesep\n+\tset i [lsearch -exact $treediffs($ids) $fname]\n+\tif {$i >= 0} {\n+\t    setinlist difffilestart $i $curdiffstart\n+\t}\n+\n+    } elseif {![string compare -length 2 \"@@\" $line]} {\n+\tregexp {^@@+} $line ats\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" hunksep\n+\tif {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n+\t    set diffline $nl\n+\t}\n+\tset diffnparents [expr {[string length $ats] - 1}]\n+\tset diffinhdr 0\n+\n+    } elseif {![string compare -length 10 \"Submodule \" $line]} {\n+\t# start of a new submodule\n+\tif {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n+\t    set fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n+\t} else {\n+\t    set fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n+\t}\n+\tif {$currdiffsubmod != $fname} {\n+\t    $ctext insert end \"\\n\";     # Add newline after commit message\n+\t}\n+\tset curdiffstart [$ctext index \"end - 1c\"]\n+\tlappend ctext_file_names \"\"\n+\tif {$currdiffsubmod != $fname} {\n+\t    lappend ctext_file_lines $fname\n+\t    makediffhdr $fname $ids\n+\t    set currdiffsubmod $fname\n+\t    $ctext insert end \"\\n$line\\n\" filesep\n+\t} else {\n \t    $ctext insert end \"$line\\n\" filesep\n+\t}\n+    } elseif {![string compare -length 3 \"  >\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" dresult\n+    } elseif {![string compare -length 3 \"  <\" $line]} {\n+\tset $currdiffsubmod \"\"\n+\tset line [encoding convertfrom $diffencoding $line]\n+\t$ctext insert end \"$line\\n\" d0\n+    } elseif {$diffinhdr} {\n+\tif {![string compare -length 12 \"rename from \" $line]} {\n+\t    set fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n+\t    }\n+\t    set fname [encoding convertfrom $fname]\n \t    set i [lsearch -exact $treediffs($ids) $fname]\n \t    if {$i >= 0} {\n \t\tsetinlist difffilestart $i $curdiffstart\n \t    }\n-\n-\t} elseif {![string compare -length 2 \"@@\" $line]} {\n-\t    regexp {^@@+} $line ats\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" hunksep\n-\t    if {[regexp { \\+(\\d+),\\d+ @@} $line m nl]} {\n-\t\tset diffline $nl\n+\t} elseif {![string compare -length 10 $line \"rename to \"] ||\n+\t\t  ![string compare -length 8 $line \"copy to \"]} {\n+\t    set fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n+\t    if {[string index $fname 0] eq \"\\\"\"} {\n+\t\tset fname [lindex $fname 0]\n \t    }\n-\t    set diffnparents [expr {[string length $ats] - 1}]\n+\t    makediffhdr $fname $ids\n+\t} elseif {[string compare -length 3 $line \"---\"] == 0} {\n+\t    # do nothing\n+\t    return\n+\t} elseif {[string compare -length 3 $line \"+++\"] == 0} {\n \t    set diffinhdr 0\n+\t    return\n+\t}\n+\t$ctext insert end \"$line\\n\" filesep\n \n-\t} elseif {![string compare -length 10 \"Submodule \" $line]} {\n-\t    # start of a new submodule\n-\t    if {[regexp -indices \"\\[0-9a-f\\]+\\\\.\\\\.\" $line nameend]} {\n-\t\tset fname [string range $line 10 [expr [lindex $nameend 0] - 2]]\n-\t    } else {\n-\t\tset fname [string range $line 10 [expr [string first \"contains \" $line] - 2]]\n-\t    }\n-\t    if {$currdiffsubmod != $fname} {\n-\t\t$ctext insert end \"\\n\";     # Add newline after commit message\n-\t    }\n-\t    set curdiffstart [$ctext index \"end - 1c\"]\n-\t    lappend ctext_file_names \"\"\n-\t    if {$currdiffsubmod != $fname} {\n-\t\tlappend ctext_file_lines $fname\n-\t\tmakediffhdr $fname $ids\n-\t\tset currdiffsubmod $fname\n-\t\t$ctext insert end \"\\n$line\\n\" filesep\n-\t    } else {\n-\t\t$ctext insert end \"$line\\n\" filesep\n-\t    }\n-\t} elseif {![string compare -length 3 \"  >\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" dresult\n-\t} elseif {![string compare -length 3 \"  <\" $line]} {\n-\t    set $currdiffsubmod \"\"\n-\t    set line [encoding convertfrom $diffencoding $line]\n-\t    $ctext insert end \"$line\\n\" d0\n-\t} elseif {$diffinhdr} {\n-\t    if {![string compare -length 12 \"rename from \" $line]} {\n-\t\tset fname [string range $line [expr 6 + [string first \" from \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n-\t\t}\n-\t\tset fname [encoding convertfrom $fname]\n-\t\tset i [lsearch -exact $treediffs($ids) $fname]\n-\t\tif {$i >= 0} {\n-\t\t    setinlist difffilestart $i $curdiffstart\n+    } else {\n+\tset line [string map {\\x1A ^Z} \\\n+\t\t      [encoding convertfrom $diffencoding $line]]\n+\t# parse the prefix - one ' ', '-' or '+' for each parent\n+\tset prefix [string range $line 0 [expr {$diffnparents - 1}]]\n+\tset tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n+\tset dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n+\tset words_pre_markup \"\"\n+\tset words_post_markup \"\"\n+\tif {[string trim $prefix \" -+\"] eq {}} {\n+\t    # prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n+\t    set num [string first \"-\" $prefix]\n+\t    if {$dowords} {\n+\t\tset line [string range $line 1 end]\n+\t    }\n+\t    if {$num >= 0} {\n+\t\t# removed line, first parent with line is $num\n+\t\tif {$num >= $mergemax} {\n+\t\t    set num \"max\"\n \t\t}\n-\t    } elseif {![string compare -length 10 $line \"rename to \"] ||\n-\t\t      ![string compare -length 8 $line \"copy to \"]} {\n-\t\tset fname [string range $line [expr 4 + [string first \" to \" $line] ] end]\n-\t\tif {[string index $fname 0] eq \"\\\"\"} {\n-\t\t    set fname [lindex $fname 0]\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"\\[-$line-\\]\" $tag$num\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tag$num\n \t\t}\n-\t\tmakediffhdr $fname $ids\n-\t    } elseif {[string compare -length 3 $line \"---\"] == 0} {\n-\t\t# do nothing\n-\t\tcontinue\n-\t    } elseif {[string compare -length 3 $line \"+++\"] == 0} {\n-\t\tset diffinhdr 0\n-\t\tcontinue\n-\t    }\n-\t    $ctext insert end \"$line\\n\" filesep\n-\n-\t} else {\n-\t    set line [string map {\\x1A ^Z} \\\n-                          [encoding convertfrom $diffencoding $line]]\n-\t    # parse the prefix - one ' ', '-' or '+' for each parent\n-\t    set prefix [string range $line 0 [expr {$diffnparents - 1}]]\n-\t    set tag [expr {$diffnparents > 1? \"m\": \"d\"}]\n-\t    set dowords [expr {$worddiff ne [mc \"Line diff\"] && $diffnparents == 1}]\n-\t    set words_pre_markup \"\"\n-\t    set words_post_markup \"\"\n-\t    if {[string trim $prefix \" -+\"] eq {}} {\n-\t\t# prefix only has \" \", \"-\" and \"+\" in it: normal diff line\n-\t\tset num [string first \"-\" $prefix]\n-\t\tif {$dowords} {\n-\t\t    set line [string range $line 1 end]\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tag$num\n \t\t}\n-\t\tif {$num >= 0} {\n-\t\t    # removed line, first parent with line is $num\n-\t\t    if {$num >= $mergemax} {\n-\t\t\tset num \"max\"\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"\\[-$line-\\]\" $tag$num\n-\t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tag$num\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tag$num\n-\t\t    }\n-\t\t} else {\n-\t\t    set tags {}\n-\t\t    if {[string first \"+\" $prefix] >= 0} {\n-\t\t\t# added line\n-\t\t\tlappend tags ${tag}result\n-\t\t\tif {$diffnparents > 1} {\n-\t\t\t    set num [string first \" \" $prefix]\n-\t\t\t    if {$num >= 0} {\n-\t\t\t\tif {$num >= $mergemax} {\n-\t\t\t\t    set num \"max\"\n-\t\t\t\t}\n-\t\t\t\tlappend tags m$num\n+\t    } else {\n+\t\tset tags {}\n+\t\tif {[string first \"+\" $prefix] >= 0} {\n+\t\t    # added line\n+\t\t    lappend tags ${tag}result\n+\t\t    if {$diffnparents > 1} {\n+\t\t\tset num [string first \" \" $prefix]\n+\t\t\tif {$num >= 0} {\n+\t\t\t    if {$num >= $mergemax} {\n+\t\t\t\tset num \"max\"\n \t\t\t    }\n+\t\t\t    lappend tags m$num\n \t\t\t}\n-\t\t\tset words_pre_markup \"{+\"\n-\t\t\tset words_post_markup \"+}\"\n \t\t    }\n-\t\t    if {$targetline ne {}} {\n-\t\t\tif {$diffline == $targetline} {\n-\t\t\t    set seehere [$ctext index \"end - 1 chars\"]\n-\t\t\t    set targetline {}\n-\t\t\t} else {\n-\t\t\t    incr diffline\n-\t\t\t}\n-\t\t    }\n-\t\t    if {$dowords && $worddiff eq [mc \"Markup words\"]} {\n-\t\t\t$ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t    set words_pre_markup \"{+\"\n+\t\t    set words_post_markup \"+}\"\n+\t\t}\n+\t\tif {$targetline ne {}} {\n+\t\t    if {$diffline == $targetline} {\n+\t\t\tset diffseehere [$ctext index \"end - 1 chars\"]\n+\t\t\tset targetline {}\n \t\t    } else {\n-\t\t\t$ctext insert end \"$line\" $tags\n-\t\t    }\n-\t\t    if {!$dowords} {\n-\t\t\t$ctext insert end \"\\n\" $tags\n+\t\t\tincr diffline\n \t\t    }\n \t\t}\n-\t    } elseif {$dowords && $prefix eq \"~\"} {\n-\t\t$ctext insert end \"\\n\" {}\n-\t    } else {\n-\t\t# \"\\ No newline at end of file\",\n-\t\t# or something else we don't recognize\n-\t\t$ctext insert end \"$line\\n\" hunksep\n+\t\tif {$dowords && $worddiff eq [mc \"Markup words\"]} {\n+\t\t    $ctext insert end \"$words_pre_markup$line$words_post_markup\" $tags\n+\t\t} else {\n+\t\t    $ctext insert end \"$line\" $tags\n+\t\t}\n+\t\tif {!$dowords} {\n+\t\t    $ctext insert end \"\\n\" $tags\n+\t\t}\n \t    }\n+\t} elseif {$dowords && $prefix eq \"~\"} {\n+\t    $ctext insert end \"\\n\" {}\n+\t} else {\n+\t    # \"\\ No newline at end of file\",\n+\t    # or something else we don't recognize\n+\t    $ctext insert end \"$line\\n\" hunksep\n \t}\n     }\n-    if {[info exists seehere]} {\n-\tmark_ctext_line [lindex [split $seehere .] 0]\n-    }\n-    maybe_scroll_ctext [eof $bdf]\n-    $ctext conf -state disabled\n-    if {[eof $bdf]} {\n-\tcatch {close $bdf}\n-\treturn 0\n-    }\n-    return [expr {$nr >= 1000? 2: 1}]\n }\n \n proc changediffdisp {} {\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230702","messageId":"ea752daecf16e623a19432dbc2e05d07b970edcb.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"[PATCH v3 gitk 3/5] gitk: split out diff part in $commitinfo","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:42Z","receivedAt":"2013-11-16T17:37:42Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nSo far we just parsed everything after the headers into the \"comment\"\nbit of $commitinfo, including notes and -- if you gave weird options\n-- the diff.\n\nSplit out the diff, if any, into a separate field.  It's easy to\nrecognize, since it always starts with /^diff/ and is preceded by an\nempty line.\n\nWe take care to snip away said empty line.  The display code already\nproperly spaces the end of the message from the first diff, and\nleaving another empty line at the end looks ugly.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 11 ++++++++++-\n 1 file changed, 10 insertions(+), 1 deletion(-)\n\ndiff --git a/gitk b/gitk\nindex 11e988e..78b4354 100755\n--- a/gitk\n+++ b/gitk\n@@ -1704,8 +1704,17 @@ proc parsecommit {id contents listed} {\n \tset comment $newcomment\n     }\n     set hasnote [string first \"\\nNotes:\\n\" $contents]\n+    set diff \"\"\n+    # If there is diff output shown in the git-log stream, split it\n+    # out.  But get rid of the empty line that always precedes the\n+    # diff.\n+    set i [string first \"\\n\\ndiff\" $comment]\n+    if {$i >= 0} {\n+\tset diff [string range $comment $i+1 end]\n+\tset comment [string range $comment 0 $i-1]\n+    }\n     set commitinfo($id) [list $headline $auname $audate \\\n-\t\t\t     $comname $comdate $comment $hasnote]\n+\t\t\t     $comname $comdate $comment $hasnote $diff]\n }\n \n proc getcommit {id} {\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230704","messageId":"1907d29ffc703330bebcbe08ec0927a028d62edf.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"[PATCH v3 gitk 4/5] gitk: support showing the gathered inline diffs","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:43Z","receivedAt":"2013-11-16T17:37:43Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThe previous commit split the diffs into a separate field.  Now we\nactually want to show them.\n\nTo that end we use the stored diff, and\n\n- process it once to build a fake \"tree diff\", i.e., a list of all\n  changed files;\n\n- feed it through parseblobdiffline to actually format it into the\n  $ctext field, like the existing diff machinery would.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 38 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 38 insertions(+)\n\ndiff --git a/gitk b/gitk\nindex 78b4354..5ece2a1 100755\n--- a/gitk\n+++ b/gitk\n@@ -156,10 +156,12 @@ proc unmerged_files {files} {\n \n proc parseviewargs {n arglist} {\n     global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs env\n+    global vinlinediff\n     global worddiff git_version\n \n     set vdatemode($n) 0\n     set vmergeonly($n) 0\n+    set vinlinediff($n) 0\n     set glflags {}\n     set diffargs {}\n     set nextisval 0\n@@ -7089,6 +7091,7 @@ proc selectline {l isnew {desired_loc {}}} {\n     global cmitmode showneartags allcommits\n     global targetrow targetid lastscrollrows\n     global autoselect autosellen jump_to_here\n+    global vinlinediff\n \n     catch {unset pending_select}\n     $canv delete hover\n@@ -7230,6 +7233,8 @@ proc selectline {l isnew {desired_loc {}}} {\n     init_flist [mc \"Comments\"]\n     if {$cmitmode eq \"tree\"} {\n \tgettree $id\n+    } elseif {$vinlinediff($curview) == 1} {\n+\tshowinlinediff $id\n     } elseif {[llength $olds] <= 1} {\n \tstartdiff $id\n     } else {\n@@ -7566,6 +7571,39 @@ proc startdiff {ids} {\n     }\n }\n \n+proc showinlinediff {ids} {\n+    global commitinfo commitdata ctext\n+    global treediffs\n+\n+    set info $commitinfo($ids)\n+    set diff [lindex $info 7]\n+    set difflines [split $diff \"\\n\"]\n+\n+    initblobdiffvars\n+    set treediff {}\n+\n+    set inhdr 0\n+    foreach line $difflines {\n+\tif {![string compare -length 5 \"diff \" $line]} {\n+\t    set inhdr 1\n+\t} elseif {$inhdr && ![string compare -length 4 \"+++ \" $line]} {\n+\t    # offset also accounts for the b/ prefix\n+\t    lappend treediff [string range $line 6 end]\n+\t    set inhdr 0\n+\t}\n+    }\n+\n+    set treediffs($ids) $treediff\n+    add_flist $treediff\n+\n+    $ctext conf -state normal\n+    foreach line $difflines {\n+\tparseblobdiffline $ids $line\n+    }\n+    maybe_scroll_ctext 1\n+    $ctext conf -state disabled\n+}\n+\n # If the filename (name) is under any of the passed filter paths\n # then return true to include the file in the listing.\n proc path_filter {filter name} {\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230705","messageId":"8b7580c42027f5a542c0afe8c9f3109a166841be.1384622392.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"[PATCH v3 gitk 5/5] gitk: recognize -L option","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:44Z","receivedAt":"2013-11-16T17:37:44Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"From: Thomas Rast <trast@inf.ethz.ch>\n\nThis gives line-log support to gitk, by exploiting the new support for\nprocessing and showing \"inline\" diffs straight from the git-log\noutput.\n\nNote that we 'set allknown 0', which is a bit counterintuitive since\nthis is a \"known\" option.  But that flag prevents gitk from thinking\nit can optimize the view by running rev-list to see the topology; in\nthe -L case that doesn't work.\n\nSigned-off-by: Thomas Rast <trast@inf.ethz.ch>\n---\n gitk | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/gitk b/gitk\nindex 5ece2a1..3679467 100755\n--- a/gitk\n+++ b/gitk\n@@ -235,6 +235,14 @@ proc parseviewargs {n arglist} {\n \t\tset filtered 1\n \t\tlappend glflags $arg\n \t    }\n+\t    \"-L*\" {\n+\t\t# Line-log with 'sticked' argument (unsticked form is\n+\t\t# not supported)\n+\t\tset filtered 1\n+\t\tset vinlinediff($n) 1\n+\t\tset allknown 0\n+\t\tlappend glflags $arg\n+\t    }\n \t    \"-n\" {\n \t\t# This appears to be the only one that has a value as a\n \t\t# separate word following it\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230708","messageId":"cover.1384622379.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"874n7ywpnd.fsf@thomasrast.ch","subject":"[PATCH v3 0/3] Documentation: stuck arguments and gitk log -L","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:54Z","receivedAt":"2013-11-16T17:37:54Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"This gathers three rather separate patches.\n\n1/3 is an unrelated fix for a string comparison issue that I noticed\nwhile surveying the state of stickiness.\n\n\n2/3 is the \"document\" plan hinted at here:\n\n> So my short-term plan just became: document instead of fix; clean up\n> manpages towards the stuck form for long options; have gitk only parse\n> -Lstuck.\n> \n> Medium term we can move gitk to a different option parser, resolving at\n> least that inconsistency.\n> \n> Longer term we can see about moving some more of the remaining craziness\n> towards parseopt, getting consistency for free.\n\n\n3/3 is the change to gitk(1) to match the 'gitk -L' support that I'm\nsending out separately (rebased to the gitk repo) and that will appear\nhere:\n\n  http://mid.gmane.org/cover.1384622392.git.tr@thomasrast.ch\n\nOf course it should only be applied once the corresponding code change\nis in place.\n\n\nThomas Rast (3):\n  commit-tree: use prefixcmp instead of memcmp(..., N)\n  Documentation: convert to --option=arg form where possible\n  Documentation/gitk: document -L option\n\n Documentation/blame-options.txt        |  4 ++--\n Documentation/fetch-options.txt        |  2 +-\n Documentation/git-branch.txt           |  6 +++---\n Documentation/git-checkout.txt         |  2 +-\n Documentation/git-cherry-pick.txt      |  2 +-\n Documentation/git-clone.txt            | 18 +++++++++---------\n Documentation/git-config.txt           |  4 ++--\n Documentation/git-credential-cache.txt |  4 ++--\n Documentation/git-cvsserver.txt        |  2 +-\n Documentation/git-describe.txt         |  2 +-\n Documentation/git-fmt-merge-msg.txt    |  4 ++--\n Documentation/git-format-patch.txt     |  4 ++--\n Documentation/git-grep.txt             | 10 +++++-----\n Documentation/git-notes.txt            |  2 +-\n Documentation/git-p4.txt               | 14 +++++++-------\n Documentation/git-prune.txt            |  4 ++--\n Documentation/git-rebase.txt           |  4 ++--\n Documentation/git-replace.txt          |  2 +-\n Documentation/git-revert.txt           |  6 +++---\n Documentation/gitk.txt                 | 16 ++++++++++++++++\n builtin/commit-tree.c                  |  2 +-\n git-cvsserver.perl                     |  2 +-\n 22 files changed, 66 insertions(+), 50 deletions(-)\n\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230706","messageId":"7f7d8c9e211b1eb37fbfd558813fbf2828ef9921.1384622379.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622379.git.tr@thomasrast.ch","subject":"[PATCH v3 1/3] commit-tree: use prefixcmp instead of memcmp(..., N)","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:55Z","receivedAt":"2013-11-16T17:37:55Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Handrolling the prefix comparison is harder to read and overruns if\nthe argument is an empty string.  Use our prefixcmp() instead.\n\nSigned-off-by: Thomas Rast <tr@thomasrast.ch>\n---\n builtin/commit-tree.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/commit-tree.c b/builtin/commit-tree.c\nindex f641ff2..19d58f9 100644\n--- a/builtin/commit-tree.c\n+++ b/builtin/commit-tree.c\n@@ -61,7 +61,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \t\t}\n \n-\t\tif (!memcmp(arg, \"-S\", 2)) {\n+\t\tif (!prefixcmp(arg, \"-S\")) {\n \t\t\tsign_commit = arg + 2;\n \t\t\tcontinue;\n \t\t}\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230710","messageId":"db303f8f29be249d804b08f4f57cb9099860c535.1384622379.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622379.git.tr@thomasrast.ch","subject":"[PATCH v3 2/3] Documentation: convert to --option=arg form where possible","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:56Z","receivedAt":"2013-11-16T17:37:56Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"We generally encourage the stuck form (that is, -oarg or\n--option=arg), for example gitcli(7) says\n\n  when a command line option takes an argument, use the stuck form\n  [...] An option that takes optional option-argument must be written\n  in the stuck form.\n\nHowever the manpages do not express the options in this form in many\nplaces.  Switch the long option descriptions to use --option=arg where\npossible.  The short options are a more difficult choice, so this\npatch leaves them unchanged.  In particular it's not clear whether the\nreadability tradeoff is worth it for mandatory arguments, where -o foo\nis equally valid and sets 'foo' off visually from the option.\n\nI found the possible matches by running\n\n  git grep '^--[^,]* .*::'\n\nThe following are not fixed by this patch:\n\n* git-filter-branch\n* git-quiltimport\n* git-rev-parse\n\nAll of them have an ad-hoc parser that does not understand stuck\nforms.\n\nThe following are fixes beyond the pure choice of style:\n\n* git-grep actually uses parseopt to take an optional argument for\n  --open-files-in-pager.  Therefore the unstuck form was not valid to\n  begin with.\n\n* In git-revert.txt, added <...> to signal that <parent-number> is a\n  placeholder (all other options in the file already use this style).\n\nSigned-off-by: Thomas Rast <tr@thomasrast.ch>\n---\n Documentation/blame-options.txt        |  4 ++--\n Documentation/fetch-options.txt        |  2 +-\n Documentation/git-branch.txt           |  6 +++---\n Documentation/git-checkout.txt         |  2 +-\n Documentation/git-cherry-pick.txt      |  2 +-\n Documentation/git-clone.txt            | 18 +++++++++---------\n Documentation/git-config.txt           |  4 ++--\n Documentation/git-credential-cache.txt |  4 ++--\n Documentation/git-cvsserver.txt        |  2 +-\n Documentation/git-describe.txt         |  2 +-\n Documentation/git-fmt-merge-msg.txt    |  4 ++--\n Documentation/git-format-patch.txt     |  4 ++--\n Documentation/git-grep.txt             | 10 +++++-----\n Documentation/git-notes.txt            |  2 +-\n Documentation/git-p4.txt               | 14 +++++++-------\n Documentation/git-prune.txt            |  4 ++--\n Documentation/git-rebase.txt           |  4 ++--\n Documentation/git-replace.txt          |  2 +-\n Documentation/git-revert.txt           |  6 +++---\n git-cvsserver.perl                     |  2 +-\n 20 files changed, 49 insertions(+), 49 deletions(-)\n\ndiff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt\nindex 0cebc4f..3d768f1 100644\n--- a/Documentation/blame-options.txt\n+++ b/Documentation/blame-options.txt\n@@ -55,14 +55,14 @@ include::line-range-format.txt[]\n \tdiscussion about encoding in the linkgit:git-log[1]\n \tmanual page.\n \n---contents <file>::\n+--contents=<file>::\n \tWhen <rev> is not specified, the command annotates the\n \tchanges starting backwards from the working tree copy.\n \tThis flag makes the command pretend as if the working\n \ttree copy has the contents of the named file (specify\n \t`-` to make the command read from the standard input).\n \n---date <format>::\n+--date=<format>::\n \tThe value is one of the following alternatives:\n \t{relative,local,default,iso,rfc,short}. If --date is not\n \tprovided, the value of the blame.date config variable is\ndiff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt\nindex f0ef7d0..4a03e06 100644\n--- a/Documentation/fetch-options.txt\n+++ b/Documentation/fetch-options.txt\n@@ -109,7 +109,7 @@ endif::git-pull[]\n \timplementing your own Porcelain you are not supposed to\n \tuse it.\n \n---upload-pack <upload-pack>::\n+--upload-pack=<upload-pack>::\n \tWhen given, and the repository to fetch from is handled\n \tby 'git fetch-pack', '--exec=<upload-pack>' is passed to\n \tthe command to specify non-default path for the command\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 311b336..91fc23f 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -195,15 +195,15 @@ start-point is either a local or remote-tracking branch.\n \tOpen an editor and edit the text to explain what the branch is\n \tfor, to be used by various other commands (e.g. `request-pull`).\n \n---contains [<commit>]::\n+--contains[=<commit>]::\n \tOnly list branches which contain the specified commit (HEAD\n \tif not specified). Implies `--list`.\n \n---merged [<commit>]::\n+--merged[=<commit>]::\n \tOnly list branches whose tips are reachable from the\n \tspecified commit (HEAD if not specified). Implies `--list`.\n \n---no-merged [<commit>]::\n+--no-merged[=<commit>]::\n \tOnly list branches whose tips are not reachable from the\n \tspecified commit (HEAD if not specified). Implies `--list`.\n \ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 91294f8..c95aed2 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -157,7 +157,7 @@ explicitly give a name with '-b' in such a case.\n \t<commit> is not a branch name.  See the \"DETACHED HEAD\" section\n \tbelow for details.\n \n---orphan <new_branch>::\n+--orphan=<new_branch>::\n \tCreate a new 'orphan' branch, named <new_branch>, started from\n \t<start_point> and switch to it.  The first commit made on this\n \tnew branch will have no parents and it will be the root of a new\ndiff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\nindex c205d23..7b54d88 100644\n--- a/Documentation/git-cherry-pick.txt\n+++ b/Documentation/git-cherry-pick.txt\n@@ -76,7 +76,7 @@ OPTIONS\n \tdefault is not to do `-x` so this option is a no-op.\n \n -m parent-number::\n---mainline parent-number::\n+--mainline=<parent-number>::\n \tUsually you cannot cherry-pick a merge because you do not know which\n \tside of the merge should be considered the mainline.  This\n \toption specifies the parent number (starting from 1) of\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 450f158..a77f645 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -11,9 +11,9 @@ SYNOPSIS\n [verse]\n 'git clone' [--template=<template_directory>]\n \t  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]\n-\t  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]\n-\t  [--separate-git-dir <git dir>]\n-\t  [--depth <depth>] [--[no-]single-branch]\n+\t  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference=<repository>]\n+\t  [--separate-git-dir=<git dir>]\n+\t  [--depth=<depth>] [--[no-]single-branch]\n \t  [--recursive | --recurse-submodules] [--] <repository>\n \t  [<directory>]\n \n@@ -93,7 +93,7 @@ If you want to break the dependency of a repository cloned with `-s` on\n its source repository, you can simply run `git repack -a` to copy all\n objects from the source repository into a pack in the cloned repository.\n \n---reference <repository>::\n+--reference=<repository>::\n \tIf the reference repository is on the local machine,\n \tautomatically setup `.git/objects/info/alternates` to\n \tobtain objects from the reference repository.  Using\n@@ -144,12 +144,12 @@ objects from the source repository into a pack in the cloned repository.\n \tthat all these refs are overwritten by a `git remote update` in the\n \ttarget repository.\n \n---origin <name>::\n+--origin=<name>::\n -o <name>::\n \tInstead of using the remote name `origin` to keep track\n \tof the upstream repository, use `<name>`.\n \n---branch <name>::\n+--branch=<name>::\n -b <name>::\n \tInstead of pointing the newly created HEAD to the branch pointed\n \tto by the cloned repository's HEAD, point to `<name>` branch\n@@ -158,7 +158,7 @@ objects from the source repository into a pack in the cloned repository.\n \t`--branch` can also take tags and detaches the HEAD at that commit\n \tin the resulting repository.\n \n---upload-pack <upload-pack>::\n+--upload-pack=<upload-pack>::\n -u <upload-pack>::\n \tWhen given, and the repository to clone from is accessed\n \tvia ssh, this specifies a non-default path for the command\n@@ -168,7 +168,7 @@ objects from the source repository into a pack in the cloned repository.\n \tSpecify the directory from which templates will be used;\n \t(See the \"TEMPLATE DIRECTORY\" section of linkgit:git-init[1].)\n \n---config <key>=<value>::\n+--config=<key>=<value>::\n -c <key>=<value>::\n \tSet a configuration variable in the newly-created repository;\n \tthis takes effect immediately after the repository is\n@@ -179,7 +179,7 @@ objects from the source repository into a pack in the cloned repository.\n \tthe config file. This makes it safe, for example, to add\n \tadditional fetch refspecs to the origin remote.\n \n---depth <depth>::\n+--depth=<depth>::\n \tCreate a 'shallow' clone with a history truncated to the\n \tspecified number of revisions.  A shallow repository has a\n \tnumber of limitations (you cannot clone or fetch from\ndiff --git a/Documentation/git-config.txt b/Documentation/git-config.txt\nindex e9917b8..6b21a3a 100644\n--- a/Documentation/git-config.txt\n+++ b/Documentation/git-config.txt\n@@ -135,10 +135,10 @@ from all available files.\n See also <<FILES>>.\n \n -f config-file::\n---file config-file::\n+--file=config-file::\n \tUse the given config file instead of the one specified by GIT_CONFIG.\n \n---blob blob::\n+--blob=blob::\n \tSimilar to '--file' but use the given blob instead of a file. E.g.\n \tyou can use 'master:.gitmodules' to read values from the file\n \t'.gitmodules' in the master branch. See \"SPECIFYING REVISIONS\"\ndiff --git a/Documentation/git-credential-cache.txt b/Documentation/git-credential-cache.txt\nindex 89b7306..5155dd3 100644\n--- a/Documentation/git-credential-cache.txt\n+++ b/Documentation/git-credential-cache.txt\n@@ -26,11 +26,11 @@ linkgit:gitcredentials[7] or `EXAMPLES` below.\n OPTIONS\n -------\n \n---timeout <seconds>::\n+--timeout=<seconds>::\n \n \tNumber of seconds to cache credentials (default: 900).\n \n---socket <path>::\n+--socket=<path>::\n \n \tUse `<path>` to contact a running cache daemon (or start a new\n \tcache daemon if one is not started). Defaults to\ndiff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt\nindex 472f5cb..cd8fc0a 100644\n--- a/Documentation/git-cvsserver.txt\n+++ b/Documentation/git-cvsserver.txt\n@@ -31,7 +31,7 @@ All these options obviously only make sense if enforced by the server side.\n They have been implemented to resemble the linkgit:git-daemon[1] options as\n closely as possible.\n \n---base-path <path>::\n+--base-path=<path>::\n Prepend 'path' to requested CVSROOT\n \n --strict-paths::\ndiff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt\nindex d20ca40..4211c0e 100644\n--- a/Documentation/git-describe.txt\n+++ b/Documentation/git-describe.txt\n@@ -80,7 +80,7 @@ OPTIONS\n \tdescribe such a commit as v1.2-0-gdeadbee (0th commit since tag v1.2\n \tthat points at object deadbee....).\n \n---match <pattern>::\n+--match=<pattern>::\n \tOnly consider tags matching the given `glob(7)` pattern,\n \texcluding the \"refs/tags/\" prefix.  This can be used to avoid\n \tleaking private tags from the repository.\ndiff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt\nindex bb1232a..415fda3 100644\n--- a/Documentation/git-fmt-merge-msg.txt\n+++ b/Documentation/git-fmt-merge-msg.txt\n@@ -40,12 +40,12 @@ OPTIONS\n \tremoved in the future.\n \n -m <message>::\n---message <message>::\n+--message=<message>::\n \tUse <message> instead of the branch names for the first line\n \tof the log message.  For use with `--log`.\n \n -F <file>::\n---file <file>::\n+--file=<file>::\n \tTake the list of merged objects from <file> instead of\n \tstdin.\n \ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex 5c0a4ab..9ada261 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -80,7 +80,7 @@ include::diff-options.txt[]\n \tPrepare patches from the topmost <n> commits.\n \n -o <dir>::\n---output-directory <dir>::\n+--output-directory=<dir>::\n \tUse <dir> to store the resulting files, instead of the\n \tcurrent working directory.\n \n@@ -92,7 +92,7 @@ include::diff-options.txt[]\n --no-numbered::\n \tName output in '[PATCH]' format.\n \n---start-number <n>::\n+--start-number=<n>::\n \tStart numbering the patches at <n> instead of 1.\n \n --numbered-files::\ndiff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt\nindex f837334..ee474c1 100644\n--- a/Documentation/git-grep.txt\n+++ b/Documentation/git-grep.txt\n@@ -95,7 +95,7 @@ OPTIONS\n -I::\n \tDon't match the pattern in binary files.\n \n---max-depth <depth>::\n+--max-depth=<depth>::\n \tFor each <pathspec> given on command line, descend at most <depth>\n \tlevels of directories. A negative value means no limit.\n \tThis option is ignored if <pathspec> contains active wildcards.\n@@ -158,7 +158,7 @@ OPTIONS\n \tsynonym for `--files-with-matches`.\n \n -O [<pager>]::\n---open-files-in-pager [<pager>]::\n+--open-files-in-pager[=<pager>]::\n \tOpen the matching files in the pager (not the output of 'grep').\n \tIf the pager happens to be \"less\" or \"vi\", and the user\n \tspecified only one pattern, the first file is positioned at\n@@ -200,17 +200,17 @@ OPTIONS\n \n -<num>::\n -C <num>::\n---context <num>::\n+--context=<num>::\n \tShow <num> leading and trailing lines, and place a line\n \tcontaining `--` between contiguous groups of matches.\n \n -A <num>::\n---after-context <num>::\n+--after-context=<num>::\n \tShow <num> trailing lines, and place a line containing\n \t`--` between contiguous groups of matches.\n \n -B <num>::\n---before-context <num>::\n+--before-context=<num>::\n \tShow <num> leading lines, and place a line containing\n \t`--` between contiguous groups of matches.\n \ndiff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt\nindex 46ef046..0d23aaa 100644\n--- a/Documentation/git-notes.txt\n+++ b/Documentation/git-notes.txt\n@@ -155,7 +155,7 @@ OPTIONS\n \tLike '-C', but with '-c' the editor is invoked, so that\n \tthe user can further edit the note message.\n \n---ref <ref>::\n+--ref=<ref>::\n \tManipulate the notes tree in <ref>.  This overrides\n \t'GIT_NOTES_REF' and the \"core.notesRef\" configuration.  The ref\n \tis taken to be in `refs/notes/` if it is not qualified.\ndiff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt\nindex 8cba16d..04ea627 100644\n--- a/Documentation/git-p4.txt\n+++ b/Documentation/git-p4.txt\n@@ -165,7 +165,7 @@ General options\n ~~~~~~~~~~~~~~~\n All commands except clone accept these options.\n \n---git-dir <dir>::\n+--git-dir=<dir>::\n \tSet the 'GIT_DIR' environment variable.  See linkgit:git[1].\n \n --verbose, -v::\n@@ -176,7 +176,7 @@ Sync options\n These options can be used in the initial 'clone' as well as in\n subsequent 'sync' operations.\n \n---branch <ref>::\n+--branch=<ref>::\n \tImport changes into <ref> instead of refs/remotes/p4/master.\n \tIf <ref> starts with refs/, it is used as is.  Otherwise, if\n \tit does not start with p4/, that prefix is added.\n@@ -199,7 +199,7 @@ Git repository:\n \tUse the branch detection algorithm to find new paths in p4.  It is\n \tdocumented below in \"BRANCH DETECTION\".\n \n---changesfile <file>::\n+--changesfile=<file>::\n \tImport exactly the p4 change numbers listed in 'file', one per\n \tline.  Normally, 'git p4' inspects the current p4 repository\n \tstate and detects the changes it should import.\n@@ -223,7 +223,7 @@ Git repository:\n \tsync operations must specify '--import-local' as well so that\n \tthey can find the p4 branches in refs/heads.\n \n---max-changes <n>::\n+--max-changes=<n>::\n \tLimit the number of imported changes to 'n'.  Useful to\n \tlimit the amount of history when using the '@all' p4 revision\n \tspecifier.\n@@ -245,7 +245,7 @@ Clone options\n These options can be used in an initial 'clone', along with the 'sync'\n options described above.\n \n---destination <directory>::\n+--destination=<directory>::\n \tWhere to create the Git repository.  If not provided, the last\n \tcomponent in the p4 depot path is used to create a new\n \tdirectory.\n@@ -260,7 +260,7 @@ Submit options\n ~~~~~~~~~~~~~~\n These options can be used to modify 'git p4 submit' behavior.\n \n---origin <commit>::\n+--origin=<commit>::\n \tUpstream location from which commits are identified to submit to\n \tp4.  By default, this is the most recent p4 commit reachable\n \tfrom 'HEAD'.\n@@ -297,7 +297,7 @@ These options can be used to modify 'git p4 submit' behavior.\n \tto bypass the prompt, causing conflicting commits to be automatically\n \tskipped, or to quit trying to apply commits, without prompting.\n \n---branch <branch>::\n+--branch=<branch>::\n \tAfter submitting, sync this named branch instead of the default\n \tp4/master.  See the \"Sync options\" section above for more\n \tinformation.\ndiff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt\nindex bf82410..604c378 100644\n--- a/Documentation/git-prune.txt\n+++ b/Documentation/git-prune.txt\n@@ -9,7 +9,7 @@ git-prune - Prune all unreachable objects from the object database\n SYNOPSIS\n --------\n [verse]\n-'git prune' [-n] [-v] [--expire <expire>] [--] [<head>...]\n+'git prune' [-n] [-v] [--expire=<expire>] [--] [<head>...]\n \n DESCRIPTION\n -----------\n@@ -43,7 +43,7 @@ OPTIONS\n \\--::\n \tDo not interpret any more arguments as options.\n \n---expire <time>::\n+--expire=<time>::\n \tOnly expire loose objects older than <time>.\n \n <head>...::\ndiff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt\nindex 94e07fd..35d121b 100644\n--- a/Documentation/git-rebase.txt\n+++ b/Documentation/git-rebase.txt\n@@ -213,7 +213,7 @@ rebase.autostash::\n \n OPTIONS\n -------\n---onto <newbase>::\n+--onto=<newbase>::\n \tStarting point at which to create the new commits. If the\n \t--onto option is not specified, the starting point is\n \t<upstream>.  May be any valid commit, and not just an\n@@ -351,7 +351,7 @@ with the `--interactive` option explicitly is generally not a good\n idea unless you know what you are doing (see BUGS below).\n \n -x <cmd>::\n---exec <cmd>::\n+--exec=<cmd>::\n \tAppend \"exec <cmd>\" after each line creating a commit in the\n \tfinal history. <cmd> will be interpreted as one or more shell\n \tcommands.\ndiff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt\nindex f373ab4..a82a36c 100644\n--- a/Documentation/git-replace.txt\n+++ b/Documentation/git-replace.txt\n@@ -64,7 +64,7 @@ OPTIONS\n \tDelete existing replace refs for the given objects.\n \n -l <pattern>::\n---list <pattern>::\n+--list=<pattern>::\n \tList replace refs for objects that match the given pattern (or\n \tall if no pattern is given).\n \tTyping \"git replace\" without arguments, also lists all replace\ndiff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt\nindex 2de67a5..3ddd242 100644\n--- a/Documentation/git-revert.txt\n+++ b/Documentation/git-revert.txt\n@@ -8,7 +8,7 @@ git-revert - Revert some existing commits\n SYNOPSIS\n --------\n [verse]\n-'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...\n+'git revert' [--[no-]edit] [-n] [-m <parent-number>] [-s] <commit>...\n 'git revert' --continue\n 'git revert' --quit\n 'git revert' --abort\n@@ -46,8 +46,8 @@ OPTIONS\n \tmessage prior to committing the revert. This is the default if\n \tyou run the command from a terminal.\n \n--m parent-number::\n---mainline parent-number::\n+-m <parent-number>::\n+--mainline=<parent-number>::\n \tUsually you cannot revert a merge because you do not know which\n \tside of the merge should be considered the mainline.  This\n \toption specifies the parent number (starting from 1) of\ndiff --git a/git-cvsserver.perl b/git-cvsserver.perl\nindex 95e69b1..cde9cc4 100755\n--- a/git-cvsserver.perl\n+++ b/git-cvsserver.perl\n@@ -108,7 +108,7 @@\n \n my $usage =\n     \"usage: git cvsserver [options] [pserver|server] [<directory> ...]\\n\".\n-    \"    --base-path <path>  : Prepend to requested CVSROOT\\n\".\n+    \"    --base-path=<path>  : Prepend to requested CVSROOT\\n\".\n     \"                          Can be read from GIT_CVSSERVER_BASE_PATH\\n\".\n     \"    --strict-paths      : Don't allow recursing into subdirectories\\n\".\n     \"    --export-all        : Don't check for gitcvs.enabled in config\\n\".\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"230709","messageId":"d532afe2eda5d5dff2f28af33831de5d1d0492e9.1384622379.git.tr@thomasrast.ch","threadId":"34080","inReplyTo":"cover.1384622379.git.tr@thomasrast.ch","subject":"[PATCH v3 3/3] Documentation/gitk: document -L option","fromName":"Thomas Rast","fromEmail":"tr@thomasrast.ch","sentAt":"2013-11-16T17:37:57Z","receivedAt":"2013-11-16T17:37:57Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"The -L option is the same as for git-log, so the entire block is just\ncopied from git-log.txt.  However, until the parser is fixed we add a\ncaveat that gitk only understands the stuck form.\n\nSigned-off-by: Thomas Rast <tr@thomasrast.ch>\n---\n Documentation/gitk.txt | 16 ++++++++++++++++\n 1 file changed, 16 insertions(+)\n\ndiff --git a/Documentation/gitk.txt b/Documentation/gitk.txt\nindex d44e14c..1e9e38a 100644\n--- a/Documentation/gitk.txt\n+++ b/Documentation/gitk.txt\n@@ -98,6 +98,22 @@ linkgit:git-rev-list[1] for a complete list.\n \t(See \"History simplification\" in linkgit:git-log[1] for a more\n \tdetailed explanation.)\n \n+-L<start>,<end>:<file>::\n+-L:<regex>:<file>::\n+\n+\tTrace the evolution of the line range given by \"<start>,<end>\"\n+\t(or the funcname regex <regex>) within the <file>.  You may\n+\tnot give any pathspec limiters.  This is currently limited to\n+\ta walk starting from a single revision, i.e., you may only\n+\tgive zero or one positive revision arguments.\n+\tYou can specify this option more than once.\n++\n+*Note:* gitk (unlike linkgit:git-log[1]) currently only understands\n+this option if you specify it \"glued together\" with its argument.  Do\n+*not* put a space after `-L`.\n++\n+include::line-range-format.txt[]\n+\n <revision range>::\n \n \tLimit the revisions to show. This can be either a single revision\n-- \n1.8.5.rc2.348.gb73b695\n"},{"id":"231339","messageId":"20131201222526.GA12576@iris.ozlabs.ibm.com","threadId":"34080","inReplyTo":"cover.1384622392.git.tr@thomasrast.ch","subject":"Re: [PATCH v3 gitk 0/5] gitk -L","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2013-12-01T22:25:26Z","receivedAt":"2013-12-01T22:25:26Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"On Sat, Nov 16, 2013 at 06:37:39PM +0100, Thomas Rast wrote:\n> These patches implement 'gitk -L'.  They are exactly the same as the\n> gitk patches from v2 at\n> \n>   http://thread.gmane.org/gmane.comp.version-control.git/227151/focus=236903\n> \n> except that they apply to the gitk-git tree at\n> \n>   git://ozlabs.org/~paulus/gitk\n\nThanks; applied all 5 (with s/sticked/stuck/g in patch 5).\n\nPaul.\n"}]}