{"thread":{"id":"45335","subject":"[PATCH] gitk: blame older file in case of copied and renamed files","startedAt":"2017-03-09T21:27:02Z","lastAt":"2017-03-09T21:27:02Z","messageCount":1,"participants":["Max Kirillov"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"313683","messageId":"20170309211831.11295-1-max@max630.net","threadId":"45335","inReplyTo":null,"subject":"[PATCH] gitk: blame older file in case of copied and renamed files","fromName":"Max Kirillov","fromEmail":"max@max630.net","sentAt":"2017-03-09T21:18:31Z","receivedAt":"2017-03-09T21:27:02Z","isPatch":true,"sender":{"key":"max@max630.net","avatar":"https://avatars.githubusercontent.com/u/381560?v=4"},"body":"If file was renamed or copied, and in the same time edited, attempt to run\n\"Show origin of this line\" or \"Run gui blame on this line\" would result in\nerror \"fatal: no such path FILE in HASH\". Reason is that it tried to use\nthe newer filename, while it should use the older one.\n\nSince ctext_file_names in diff mode only used for parent commit\nfilenames, there is no need to split it to 2 lists, just change its\nso that for diff mode it means older filename always.\n\nSigned-off-by: Max Kirillov <max@max630.net>\n---\n gitk | 19 +++++++++++++++++--\n 1 file changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex d3e9e459c3..0b8b1a4e9f 100755\n--- a/gitk\n+++ b/gitk\n@@ -8349,9 +8349,16 @@ proc setinlist {var i val} {\n     }\n }\n \n+proc add_ctext_file {fname} {\n+    global ctext_file_names\n+\n+    set fname [encoding convertfrom $fname]\n+    lset ctext_file_names end $fname\n+}\n+\n proc makediffhdr {fname ids} {\n     global ctext curdiffstart treediffs diffencoding\n-    global ctext_file_names jump_to_here targetline diffline\n+    global jump_to_here targetline diffline\n \n     set fname [encoding convertfrom $fname]\n     set diffencoding [get_path_encoding $fname]\n@@ -8359,7 +8366,6 @@ proc makediffhdr {fname ids} {\n     if {$i >= 0} {\n \tsetinlist difffilestart $i $curdiffstart\n     }\n-    lset ctext_file_names end $fname\n     set l [expr {(78 - [string length $fname]) / 2}]\n     set pad [string range \"----------------------------------------\" 1 $l]\n     $ctext insert $curdiffstart \"$pad $fname $pad\" filesep\n@@ -8454,6 +8460,7 @@ proc parseblobdiffline {ids line} {\n \t\tset fname [string range $line 2 [expr {$i - 1}]]\n \t    }\n \t}\n+\tadd_ctext_file $fname\n \tmakediffhdr $fname $ids\n \n     } elseif {![string compare -length 16 \"* Unmerged path \" $line]} {\n@@ -8492,6 +8499,7 @@ proc parseblobdiffline {ids line} {\n \tlappend ctext_file_names \"\"\n \tif {$currdiffsubmod != $fname} {\n \t    lappend ctext_file_lines $fname\n+\t    add_ctext_file $fname\n \t    makediffhdr $fname $ids\n \t    set currdiffsubmod $fname\n \t    $ctext insert end \"\\n$line\\n\" filesep\n@@ -8512,11 +8520,18 @@ proc parseblobdiffline {ids line} {\n \t    if {[string index $fname 0] eq \"\\\"\"} {\n \t\tset fname [lindex $fname 0]\n \t    }\n+\t    add_ctext_file $fname\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+\t} elseif {![string compare -length 10 $line \"copy from \"]} {\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    add_ctext_file $fname\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-- \n2.11.0.1122.gc3fec58.dirty\n\n"}]}