Skip to content
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

[Search git status] support previewing merge conflict #262

Merged
merged 10 commits into from
Sep 26, 2022
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Use `fzf.fish` to interactively find and insert the shell entities listed below

- **Search input:** the current repository's `git status`
- **Key binding and mnemonic:** <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>S</kbd> (`S` for status)
- **Preview window:** the staged and unstaged changes in the file
- **Preview window:** the git diff of the file

### Commit hashes

Expand Down
20 changes: 12 additions & 8 deletions functions/_fzf_preview_changed_file.fish
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@
# MM functions/_fzf_preview_changed_file.fish
# D README.md
# R LICENSE.md -> LICENSE
function _fzf_preview_changed_file --description "Show the untracked, staged, and/or unstaged changes in the given file."
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
# don't requote when referencing $path because fish does not perform word splitting
# no need to requote when referencing $path because fish does not perform word splitting
# https://fishshell.com/docs/current/fish_for_bash_users.html
set -l path (string unescape (string sub --start 4 $argv))
set -l path (string unescape (string sub --start 4 $path_status))
# first letter of short format shows index, second letter shows working tree
# https://git-scm.com/docs/git-status/2.35.0#_output
set -l index_status (string sub --length 1 $argv)
set -l working_tree_status (string sub --start 2 --length 1 $argv)
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

if test $index_status = '?'
_fzf_report_diff_type Untracked
_fzf_preview_file $path
else if contains {$index_status}$working_tree_status UD DU UU AA
# inferred from # https://stackoverflow.com/questions/22792906/how-do-i-produce-every-possible-git-status
# the above 4 statuses are the only possible ones for a merge conflict
_fzf_report_diff_type Unmerged
git diff $diff_opts -- $path
else
# no-prefix because the file is always being compared to itself so is unecessary
set diff_opts --color=always --no-prefix

if test $index_status != ' '
_fzf_report_diff_type Staged
git diff --staged $diff_opts -- $path
Expand Down
6 changes: 2 additions & 4 deletions tests/preview_changed_file/deleted_in_working.fish
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
mock git diff "echo \$argv"
set file dir/file.txt
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$file was only being used in one place

set output (_fzf_preview_changed_file " D out.log")

set output (_fzf_preview_changed_file " D $file")

contains -- "| Unstaged |" $output && not contains "| Staged |" $output
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains doesn't need -- because by passing in the first argument, it would never interpret a line prefixed with- in $output as an option.

contains "| Unstaged |" $output && not contains "| Staged |" $output
@test "only shows unstaged changes if file was only deleted in working tree" $status -eq 0
4 changes: 4 additions & 0 deletions tests/preview_changed_file/merge_conflict.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mock git diff "echo \$argv"
set output (_fzf_preview_changed_file "UU out.log")

@test "shows merge conflicts as unmerged" $output[2] = "| Unmerged |"
5 changes: 2 additions & 3 deletions tests/preview_changed_file/modified_in_both.fish
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
mock git diff "echo \$argv"
set file dir/file.txt
set output (_fzf_preview_changed_file "MM $file")
set output (_fzf_preview_changed_file "MM dir/file.txt")

contains -- "| Unstaged |" $output && contains "| Staged |" $output
contains "| Unstaged |" $output && contains "| Staged |" $output
@test "shows staged and unstaged changes if the file is modified in both places" $status -eq 0