Skip to content

Commit ad4121b

Browse files
committed
gitk: add external diff file rename detection
If a file is renamed between commits and an external diff is started through gitk on the original or the renamed file name, gitk is unable to open the renamed file in the external diff editor. It fails to fetch the renamed file from git, because it fetches it using its original path in contrast to using the renamed path of the file. Detect the rename and open the external diff with the original and the renamed file instead of no file (fetch the renamed file path and name from git) no matter if the original or the renamed file is selected in gitk. Since moved or renamed file are handled the same way do this also for moved files. Signed-off-by: Tobias Boesch <[email protected]>
1 parent 14de3eb commit ad4121b

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

gitk-git/gitk

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3775,6 +3775,38 @@ proc external_diff_get_one_file {diffid filename diffdir} {
37753775
"revision $diffid"]
37763776
}
37773777
3778+
proc check_for_renames_in_diff {diffidfrom diffidto filepath} {
3779+
global nullid nullid2
3780+
3781+
if {$diffidfrom eq $nullid} {
3782+
set revision [list $diffidto -R]
3783+
} elseif {$diffidfrom eq $nullid2} {
3784+
set revision [list $diffidto --cached -R]
3785+
} elseif {$diffidto eq $nullid} {
3786+
set revision [list $diffidfrom]
3787+
} elseif {$diffidto eq $nullid2} {
3788+
set revision [list $diffidfrom --cached]
3789+
} else {
3790+
set revision [list $diffidfrom..$diffidto]
3791+
}
3792+
3793+
set renamed_filenames [list {}]
3794+
if {[catch {eval exec git diff $revision --find-renames --stat --raw --diff-filter=R} diff_tree_result]} {
3795+
error_popup "[mc "Error getting file rename info for file \"%s\" from commit %s to %s." \
3796+
$filepath $diffidfrom $diffidto] $diff_tree_result.\n\n"
3797+
}
3798+
set filename [file tail $filepath]
3799+
set reg_expr_rename {\d+\s\d+\s\S+\s\S+\s\S+\s+(\S+)\s+(\S+)}
3800+
set reg_expr_rename [subst -nobackslashes -nocommands $reg_expr_rename]
3801+
if {[regexp -line -- $reg_expr_rename $diff_tree_result unused_complete_match rename_change_from rename_change_to]} {
3802+
if { ($rename_change_from != {}) && ($rename_change_to != {}) } {
3803+
lappend renamed_filenames $rename_change_from
3804+
lappend renamed_filenames $rename_change_to
3805+
}
3806+
}
3807+
return $renamed_filenames
3808+
}
3809+
37783810
proc external_diff {} {
37793811
global nullid nullid2
37803812
global flist_menu_file
@@ -3805,8 +3837,16 @@ proc external_diff {} {
38053837
if {$diffdir eq {}} return
38063838
38073839
# gather files to diff
3808-
set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
3809-
set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir]
3840+
set renamed_filenames [check_for_renames_in_diff $diffidfrom $diffidto $flist_menu_file]
3841+
set rename_from_filename [lindex $renamed_filenames 1]
3842+
set rename_to_filename [lindex $renamed_filenames 2]
3843+
if { ($rename_from_filename != {}) && ($rename_to_filename != {}) } {
3844+
set difffromfile [external_diff_get_one_file $diffidfrom $rename_from_filename $diffdir]
3845+
set difftofile [external_diff_get_one_file $diffidto $rename_to_filename $diffdir]
3846+
} else {
3847+
set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
3848+
set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir]
3849+
}
38103850
38113851
if {$difffromfile ne {} && $difftofile ne {}} {
38123852
set cmd [list [shellsplit $extdifftool] $difffromfile $difftofile]

0 commit comments

Comments
 (0)