Skip to content

gitk: add external diff file rename detection #1774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions gitk-git/gitk
Original file line number Diff line number Diff line change
Expand Up @@ -3775,6 +3775,48 @@ 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 -R]
} elseif {$diffidfrom eq $nullid2} {
set rev [list $diffidto --cached -R]
} elseif {$diffidto eq $nullid} {
set rev [list $diffidfrom]
} elseif {$diffidto eq $nullid2} {
set rev [list $diffidfrom --cached]
} else {
set rev [list $diffidfrom..$diffidto]
}

set renames [list {}]
if {[catch {eval exec git diff $rev --find-renames --stat --raw --diff-filter=R} 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
Expand Down Expand Up @@ -3805,8 +3847,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 renamed_filenames [check_for_renames_in_diff $diffidfrom $diffidto $flist_menu_file]
set rename_from_filename [lindex $renamed_filenames 1]
set rename_to_filename [lindex $renamed_filenames 2]
if { ($rename_from_filename != {}) && ($rename_to_filename != {}) } {
set difffromfile [external_diff_get_one_file $diffidfrom $rename_from_filename $diffdir]
set difftofile [external_diff_get_one_file $diffidto $rename_to_filename $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]
Expand Down
Loading