refactor: extract _forgit_worktree_changes from _forgit_add

This commit is contained in:
sandroid 2026-03-15 16:43:56 +01:00 committed by sandr01d
parent 12ec178093
commit 1bc93a2c3a
2 changed files with 76 additions and 10 deletions

View file

@ -213,6 +213,22 @@ _forgit_list_files() {
git ls-files -z "$@" "$rootdir" | tr '\0' '\n' | uniq
}
# Print changed files in the worktree
#
# Always includes modified and unmerged files. Includes untracked files when
# status.showUntrackedFiles is true or unset. Never includes staged files.
_forgit_worktree_changes() {
local changed unmerged untracked show_untracked
changed=$(git config --get-color color.status.changed red)
unmerged=$(git config --get-color color.status.unmerged red)
untracked=$(git config --get-color color.status.untracked red)
show_untracked=$(git config status.showUntrackedFiles)
git -c color.status=always -c status.relativePaths=true -c core.quotePath=false status -s --untracked="${show_untracked:-all}" |
grep -F -e "$changed" -e "$unmerged" -e "$untracked" |
sed -E 's/^(..[^[:space:]]*)[[:space:]]+(.*)$/[\1] \2/'
}
_forgit_is_submodule() {
git submodule --quiet status "$1"
}
@ -516,13 +532,10 @@ _forgit_edit_add_file() {
# git add selector
_forgit_add() {
_forgit_inside_work_tree || return 1
local changed unmerged untracked files opts show_untracked
local files opts
# Add files if passed as arguments
_forgit_contains_non_flags "$@" && { _forgit_git_add "$@" && git status -s; return $?; }
changed=$(git config --get-color color.status.changed red)
unmerged=$(git config --get-color color.status.unmerged red)
untracked=$(git config --get-color color.status.untracked red)
opts="
$FORGIT_FZF_DEFAULT_OPTS
-0 -m --nth 2..,..
@ -531,14 +544,9 @@ _forgit_add() {
$FORGIT_ADD_FZF_OPTS
"
files=()
show_untracked=$(git config status.showUntrackedFiles)
while IFS='' read -r file; do
files+=("$file")
done < <(git -c color.status=always -c status.relativePaths=true -c core.quotePath=false status -s --untracked="${show_untracked:-all}" |
grep -F -e "$changed" -e "$unmerged" -e "$untracked" |
sed -E 's/^(..[^[:space:]]*)[[:space:]]+(.*)$/[\1] \2/' |
FZF_DEFAULT_OPTS="$opts" fzf |
_forgit_get_single_file_from_add_line)
done < <(_forgit_worktree_changes | FZF_DEFAULT_OPTS="$opts" fzf | _forgit_get_single_file_from_add_line)
[[ "${#files[@]}" -gt 0 ]] && _forgit_git_add "$@" "${files[@]}" && git status -s && return
echo 'Nothing to add.'
}

View file

@ -0,0 +1,58 @@
#!/usr/bin/env bash
function set_up_before_script() {
source bin/git-forgit
# Ignore global git config files
export GIT_CONFIG_SYSTEM=/dev/null
export GIT_CONFIG_GLOBAL=/dev/null
cd "$(bashunit::temp_dir)" || return 1
git init --quiet
git config user.name "Test User"
git config user.email "test@example.com"
touch "tracked file.txt"
touch "modified file.txt"
git add .
git commit -m "init" --quiet
echo modified > "modified file.txt"
touch "staged file.txt"
git add "staged file.txt"
touch "untracked_file.txt"
}
function test_forgit_worktree_changes_contains_modified() {
local output
output=$(_forgit_worktree_changes)
assert_contains "modified file.txt" "$output"
}
function test_forgit_worktree_changes_contains_untracked() {
local output
output=$(_forgit_worktree_changes)
assert_contains "untracked_file.txt" "$output"
}
function test_forgit_worktree_changes_excludes_staged() {
local output
output=$(_forgit_worktree_changes)
assert_not_contains "staged file.txt" "$output"
}
function test_forgit_worktree_changes_excludes_tracked() {
local output
output=$(_forgit_worktree_changes)
assert_not_contains "tracked file.txt" "$output"
}