diff --git a/lib/git/shell_shortcuts.sh b/lib/git/shell_shortcuts.sh index e3ca7f5..9167787 100644 --- a/lib/git/shell_shortcuts.sh +++ b/lib/git/shell_shortcuts.sh @@ -124,11 +124,29 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && which ruby > /dev/null 2>&1; then setopt shwordsplit fi - # Parse path from args + # Get the directory that `ls` is being run relative to. + # Only allow one directory to avoid incorrect $e# variables when listing + # multiple directories (issue #274) local IFS=$'\n' + local rel_path for arg in "$@"; do - if [ -d "$arg" ]; then local rel_path="${arg%/}"; fi + if [[ -e $arg ]]; then # Path rather than option to ls + if [[ -z $rel_path ]]; then # We are seeing our first pathname + if [[ -d $arg ]]; then # It's a directory + rel_path=$arg + else # It's a file, expand the current directory + rel_path=. + fi + elif [[ -d $arg || ( -f $arg && $rel_path != . ) ]]; then + if [[ -f $arg ]]; then arg=$PWD; fi # Get directory for current argument + # We've already seen a different directory. Quit to avoid damage (issue #274) + printf 'scm_breeze: Cannot list relative to both directories:\n %s\n %s\n' "$arg" "$rel_path" >&2 + printf 'Currently only listing a single directory is supported. See issue #274.\n' >&2 + return 1 + fi + fi done + rel_path=$("${_abs_path_command[@]}" ${rel_path:-$PWD}) # Replace user/group with user symbol, if defined at ~/.user_sym # Before : -rw-rw-r-- 1 ndbroadbent ndbroadbent 1.1K Sep 19 21:39 scm_breeze.sh @@ -177,9 +195,9 @@ EOF local IFS=$'\n' for file in $ll_files; do - if [ -n "$rel_path" ]; then file="$rel_path/$file"; fi - export $git_env_char$e="$(_safe_eval "${_abs_path_command[@]}" "$file")" - if [ "${scmbDebug:-}" = "true" ]; then echo "Set \$$git_env_char$e => $file"; fi + file=$rel_path/$file + export $git_env_char$e=$("${_abs_path_command[@]}" "$file") + if [[ ${scmbDebug:-} = true ]]; then echo "Set \$$git_env_char$e => $file"; fi let e++ done diff --git a/test/lib/git/shell_shortcuts_test.sh b/test/lib/git/shell_shortcuts_test.sh index 7bab1d3..7f1f6f4 100755 --- a/test/lib/git/shell_shortcuts_test.sh +++ b/test/lib/git/shell_shortcuts_test.sh @@ -107,7 +107,7 @@ test_ls_with_file_shortcuts() { touch 'test file' 'test_file' mkdir -p "a [b]" 'a "b"' "a 'b'" - touch "a \"b\"/c" + touch 'a "b"/c' # Run command in shell, load output from temp file into variable # (This is needed so that env variables are exported in the current shell) @@ -134,11 +134,22 @@ test_ls_with_file_shortcuts() { ls_output=$(<$temp_file strip_colors) assertIncludes "$ls_output" '[1] c' F # Test that env variable is set correctly - assertEquals "$TEST_DIR/a \"b\"/c" "$e1" + assertEquals "$TEST_DIR/"'a "b"/c' "$e1" # Test arg with no quotes ls_output=$(ls_with_file_shortcuts a\ \"b\" | strip_colors) assertIncludes "$ls_output" '[1] c' F + # Listing two directories fails (see issue #275) + mkdir 1 2 + touch 1/file + assertFalse 'Only one directory supported' 'ls_with_file_shortcuts 1 2' + assertFalse 'Fails on ' 'ls_with_file_shortcuts 1 test_file' + assertFalse 'Fails on ' 'ls_with_file_shortcuts test_file 1' + assertFalse 'Fails on /' 'ls_with_file_shortcuts 1 1/file' + + # Files under the root directory + assertTrue 'Shortcuts under /' 'ls_with_file_shortcuts / > /dev/null && [[ $e1 =~ ^/[^/]+$ ]]' + cd - rm -r "$TEST_DIR" "$temp_file" }