diff --git a/gitk-git/gitk b/gitk-git/gitk index 19689765cde531..457949e14d17aa 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -3775,6 +3775,53 @@ proc external_diff_get_one_file {diffid filename diffdir} { "revision $diffid"] } +proc check_for_renames_in_diff {diffidfrom diffidto filepath} { + global nullid nullid2 + + if {$diffidfrom eq $nullid} { + set rev [list $diffidto] + set cmd [list diff-index -R] + } elseif {$diffidfrom eq $nullid2} { + set rev [list $diffidto] + set cmd [list diff-index --cached -R] + } elseif {$diffidto eq $nullid} { + set rev [list $diffidfrom] + set cmd [list diff-index] + } elseif {$diffidto eq $nullid2} { + set rev [list $diffidfrom] + set cmd [list diff-index --cached] + } else { + set rev [list $diffidfrom..$diffidto] + set cmd [list diff-tree] + } + + set renames [list {}] + if {[catch {eval exec git $cmd --find-renames --stat --raw --diff-filter=R $rev} cmd_result]} { + error_popup "[mc "Error getting file rename info for file \"%s\" from commit %s to %s." \ + $filepath $diffidfrom $diffidto] $cmd_result.\n\n" + } + set filename [file tail $filepath] + set esc_chars {\\ | ? ^ * . $ \[ \] + \( \) \{ \}} + foreach char $esc_chars { + set filename [string map [list $char \\$char] $filename] + } + set regex_base {\d+\s\d+\s\S+\s\S+\s\S+\s+} + set regex_ren_from $regex_base[subst -nobackslashes -nocommands {(\S+$filename)\s+(\S+)}] + set regex_ren_to $regex_base[subst -nobackslashes -nocommands {(\S+)\s+(\S+$filename)}] + if {[regexp -line -- $regex_ren_from $cmd_result whole_match ren_from ren_to]} { + if {$ren_from ne {} && $ren_to ne {}} { + lappend renames $ren_from + lappend renames $ren_to + } + } elseif {[regexp -line -- $regex_ren_to $cmd_result whole_match ren_from ren_to]} { + if {$ren_from ne {} && $ren_to ne {}} { + lappend renames $ren_from + lappend renames $ren_to + } + } + return $renames +} + proc external_diff {} { global nullid nullid2 global flist_menu_file @@ -3805,8 +3852,16 @@ proc external_diff {} { if {$diffdir eq {}} return # gather files to diff - set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir] - set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir] + set renames [check_for_renames_in_diff $diffidfrom $diffidto $flist_menu_file] + set renamefrom [lindex $renames 1] + set renameto [lindex $renames 2] + if { ($renamefrom != {}) && ($renameto != {}) } { + set difffromfile [external_diff_get_one_file $diffidfrom $renamefrom $diffdir] + set difftofile [external_diff_get_one_file $diffidto $renameto $diffdir] + } else { + set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir] + set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir] + } if {$difffromfile ne {} && $difftofile ne {}} { set cmd [list [shellsplit $extdifftool] $difffromfile $difftofile]