Fix: preview for clean when file names contain backslashes (#465)

This is a breaking change: flag arguments provided to forgit clean are
now passed to git ls-files instead of git clean -n. This change is
necessary because git clean does not have a -z option that would prevent
it from escaping file names containing backslashes. However, git ls-files
is way more flexible than git clean, so all use cases covered by git
clean (and more) should still be possible.
This commit is contained in:
sandr01d 2025-12-05 22:58:46 +01:00 committed by GitHub
parent 582a64ea36
commit b9ed7bc40e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 8 deletions

View file

@ -608,13 +608,8 @@ _forgit_clean_preview() {
fi
}
# git clean selector
_forgit_clean() {
_forgit_inside_work_tree || return 1
_forgit_contains_non_flags "$@" && { git clean -q "$@"; return $?; }
local files opts
_forgit_clean_git_opts=()
_forgit_parse_array _forgit_clean_git_opts "$FORGIT_CLEAN_GIT_OPTS"
_forgit_clean_select_files() {
local opts
opts="
$FORGIT_FZF_DEFAULT_OPTS
--preview=\"$FORGIT clean_preview {}\"
@ -622,7 +617,17 @@ _forgit_clean() {
$FORGIT_CLEAN_FZF_OPTS
"
# Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed.
files=$(git -c core.quotePath=false clean -xdffn "$@"| sed 's/^Would remove //' | FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##')
_forgit_list_files --others "$@" | FZF_DEFAULT_OPTS="$opts" fzf | sed 's#/$##'
}
# git clean selector
_forgit_clean() {
_forgit_inside_work_tree || return 1
_forgit_contains_non_flags "$@" && { git clean -q "$@"; return $?; }
local files
_forgit_clean_git_opts=()
_forgit_parse_array _forgit_clean_git_opts "$FORGIT_CLEAN_GIT_OPTS"
files=$(_forgit_clean_select_files "$@")
[[ -n "$files" ]] && echo "$files" | tr '\n' '\0' | xargs -0 -I% git clean "${_forgit_clean_git_opts[@]}" -xdff '%' && git status --short && return
echo 'Nothing to clean.'
}

View file

@ -0,0 +1,32 @@
#!/usr/bin/env bash
function set_up_before_script() {
source bin/git-forgit
# create a new git repository in a temp directory
cd "$(temp_dir)" || return 1
git init --quiet
# create files to test against
touch file.txt
touch file_with\\backslashes\\.txt
touch "file with spaces.txt"
touch "file_with\ttab.txt"
}
# @data_provider provider_clean_select_files
function test_forgit_clean_select_files_preview() {
mock "fzf" "sed -n ${1}p"
local file
file=$(_forgit_clean_select_files)
assert_file_exists "$file"
}
function provider_clean_select_files() {
data_set 1
data_set 2
data_set 3
data_set 4
}