Skip to content

Commit

Permalink
[Search git status] Preview only changes since file renamed (#263)
Browse files Browse the repository at this point in the history
Previously, the git diff preview for a renamed path shows the entire file as being added. A more useful diff is to view only the modifications made to the file content. To accomplish this, we need a special condition for renames to diff the current (post-rename) path with the original path.

In addition, this PR fixes git status previews for renamed paths, which was accidentally broken in 38896f2.
  • Loading branch information
PatrickF1 authored Oct 10, 2022
1 parent 25752b6 commit 3a430c0
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ They are always appended last to fzf's argument list. Because fzf uses the optio

### Change the commands used to preview directories and regular files

The search directory feature, by default, calls `ls` to preview directories and `bat` to preview [regular files](https://stackoverflow.com/questions/6858452/what-is-a-regular-file-on-unix).
The search directory feature, by default, calls `ls` to preview directories and `bat` to preview [regular files](https://stackoverflow.com/questions/6858452).

To change the directory preview command (e.g. to use one of the many `ls` replacements such as `exa`), set the command in the `fzf_preview_dir_cmd` variable:

Expand Down
19 changes: 15 additions & 4 deletions functions/_fzf_preview_changed_file.fish
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# arg should be a line from git status --short, e.g.
# MM functions/_fzf_preview_changed_file.fish
# D README.md
# R LICENSE.md -> LICENSE
# R LICENSE -> "New License"
function _fzf_preview_changed_file --argument-names path_status --description "Show the git diff of the given file."
# remove quotes because they'll be interpreted literally by git diff
# no need to requote when referencing $path because fish does not perform word splitting
Expand All @@ -12,8 +12,8 @@ function _fzf_preview_changed_file --argument-names path_status --description "S
# https://git-scm.com/docs/git-status/2.35.0#_short_format
set -l index_status (string sub --length 1 $path_status)
set -l working_tree_status (string sub --start 2 --length 1 $path_status)
# no-prefix because the file is always being compared to itself so is unecessary
set diff_opts --color=always --no-prefix

set diff_opts --color=always

if test $index_status = '?'
_fzf_report_diff_type Untracked
Expand All @@ -27,7 +27,18 @@ function _fzf_preview_changed_file --argument-names path_status --description "S
else
if test $index_status != ' '
_fzf_report_diff_type Staged
git diff --staged $diff_opts -- $path

# renames are only detected in the index, never working tree, so only need to test for it here
# https://stackoverflow.com/questions/73954214
if test $index_status = R
# diff the post-rename path with the original path, otherwise the diff will show the entire file as being added
set orig_and_new_path (string split --max 1 -- ' -> ' $path)
git diff --staged $diff_opts -- $orig_and_new_path[1] $orig_and_new_path[2]
# path currently has the form of "original -> current", so we need to correct it before it's used below
set path $orig_and_new_path[2]
else
git diff --staged $diff_opts -- $path
end
end

if test $working_tree_status != ' '
Expand Down
26 changes: 26 additions & 0 deletions tests/_resources/alphabet 26 lines.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
aaaaaaaaaaa
bbbbbbbbbbb
ccccccccccc
ddddddddddd
eeeeeeeeeee
fffffffffff
ggggggggggg
hhhhhhhhhhh
iiiiiiiiiii
jjjjjjjjjjj
kkkkkkkkkkk
lllllllllll
mmmmmmmmmmm
nnnnnnnnnnn
ooooooooooo
ppppppppppp
qqqqqqqqqqq
rrrrrrrrrrr
sssssssssss
ttttttttttt
uuuuuuuuuuu
vvvvvvvvvvv
wwwwwwwwwww
xxxxxxxxxxx
yyyyyyyyyyy
zzzzzzzzzzz
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ echo $expected_diff >>$path_with_space
set output (_fzf_preview_changed_file " M \"$path_with_space\"")

string match --entire --quiet $expected_diff $output
@test "git diff successfully invoked on path with space" $status -eq 0
@test "successfully previews modified path with spaces" $status -eq 0

git restore $path_with_space
15 changes: 0 additions & 15 deletions tests/preview_changed_file/renamed_in_index.fish

This file was deleted.

17 changes: 17 additions & 0 deletions tests/preview_changed_file/renamed_path_modifications.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
set orig_path "tests/_resources/alphabet 26 lines.txt"
set renamed_path "tests/_resources/alphabet lines.txt"
set added_line a-very-unique-line
git mv $orig_path $renamed_path
echo $added_line >>$renamed_path
git add $renamed_path

set output (_fzf_preview_changed_file "R \"$orig_path\" -> \"$renamed_path\"")

# test that the added line shows up in the diff but not the entire file
# "aaaaaaaaaa" is the first line in the file
string match --entire --quiet $added_line $output &&
not string match --entire aaaaaaaaaa $output
@test "shows only the modifications made to renamed file" $status -eq 0

git mv $renamed_path $orig_path
git restore --staged --worktree $orig_path

0 comments on commit 3a430c0

Please sign in to comment.