Skip to content

Commit 3a430c0

Browse files
authored
[Search git status] Preview only changes since file renamed (#263)
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.
1 parent 25752b6 commit 3a430c0

File tree

6 files changed

+60
-21
lines changed

6 files changed

+60
-21
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ They are always appended last to fzf's argument list. Because fzf uses the optio
135135

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

138-
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).
138+
The search directory feature, by default, calls `ls` to preview directories and `bat` to preview [regular files](https://stackoverflow.com/questions/6858452).
139139

140140
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:
141141

functions/_fzf_preview_changed_file.fish

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

1818
if test $index_status = '?'
1919
_fzf_report_diff_type Untracked
@@ -27,7 +27,18 @@ function _fzf_preview_changed_file --argument-names path_status --description "S
2727
else
2828
if test $index_status != ' '
2929
_fzf_report_diff_type Staged
30-
git diff --staged $diff_opts -- $path
30+
31+
# renames are only detected in the index, never working tree, so only need to test for it here
32+
# https://stackoverflow.com/questions/73954214
33+
if test $index_status = R
34+
# diff the post-rename path with the original path, otherwise the diff will show the entire file as being added
35+
set orig_and_new_path (string split --max 1 -- ' -> ' $path)
36+
git diff --staged $diff_opts -- $orig_and_new_path[1] $orig_and_new_path[2]
37+
# path currently has the form of "original -> current", so we need to correct it before it's used below
38+
set path $orig_and_new_path[2]
39+
else
40+
git diff --staged $diff_opts -- $path
41+
end
3142
end
3243

3344
if test $working_tree_status != ' '
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
aaaaaaaaaaa
2+
bbbbbbbbbbb
3+
ccccccccccc
4+
ddddddddddd
5+
eeeeeeeeeee
6+
fffffffffff
7+
ggggggggggg
8+
hhhhhhhhhhh
9+
iiiiiiiiiii
10+
jjjjjjjjjjj
11+
kkkkkkkkkkk
12+
lllllllllll
13+
mmmmmmmmmmm
14+
nnnnnnnnnnn
15+
ooooooooooo
16+
ppppppppppp
17+
qqqqqqqqqqq
18+
rrrrrrrrrrr
19+
sssssssssss
20+
ttttttttttt
21+
uuuuuuuuuuu
22+
vvvvvvvvvvv
23+
wwwwwwwwwww
24+
xxxxxxxxxxx
25+
yyyyyyyyyyy
26+
zzzzzzzzzzz

tests/preview_changed_file/path_with_spaces.fish renamed to tests/preview_changed_file/modified_path_with_spaces.fish

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ echo $expected_diff >>$path_with_space
44
set output (_fzf_preview_changed_file " M \"$path_with_space\"")
55

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

99
git restore $path_with_space

tests/preview_changed_file/renamed_in_index.fish

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
set orig_path "tests/_resources/alphabet 26 lines.txt"
2+
set renamed_path "tests/_resources/alphabet lines.txt"
3+
set added_line a-very-unique-line
4+
git mv $orig_path $renamed_path
5+
echo $added_line >>$renamed_path
6+
git add $renamed_path
7+
8+
set output (_fzf_preview_changed_file "R \"$orig_path\" -> \"$renamed_path\"")
9+
10+
# test that the added line shows up in the diff but not the entire file
11+
# "aaaaaaaaaa" is the first line in the file
12+
string match --entire --quiet $added_line $output &&
13+
not string match --entire aaaaaaaaaa $output
14+
@test "shows only the modifications made to renamed file" $status -eq 0
15+
16+
git mv $renamed_path $orig_path
17+
git restore --staged --worktree $orig_path

0 commit comments

Comments
 (0)