Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions bin/git-forgit
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,23 @@ _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 status --porcelain -zs --untracked="${show_untracked:-all}" |
tr '\0' '\n' |
grep -F -e "$changed" -e "$unmerged" -e "$untracked" |
sed -E 's/^(..[^[:space:]]*)[[:space:]]+(.*)$/[\1] \2/'
Comment thread
sandr01d marked this conversation as resolved.
}

_forgit_is_submodule() {
git submodule --quiet status "$1"
}
Expand Down Expand Up @@ -505,13 +522,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..,..
Expand All @@ -520,14 +534,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.'
}
Expand Down
67 changes: 67 additions & 0 deletions tests/working-tree-changes.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/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"
touch 'untracked_with_\backslash'
}

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"
}

function test_forgit_worktree_changes_supports_backslashes() {
local output

output=$(_forgit_worktree_changes)

assert_contains 'untracked_with_\backslash' "$output"
}