diff --git a/lib/git/fallback/status_shortcuts_shell.sh b/lib/git/fallback/status_shortcuts_shell.sh index 6eb7c3f..1b20df2 100644 --- a/lib/git/fallback/status_shortcuts_shell.sh +++ b/lib/git/fallback/status_shortcuts_shell.sh @@ -134,7 +134,9 @@ _gs_output_file_group() { $pad$c_dark [$c_rst$e$c_dark] $c_group$relative$c_rst" # Export numbered variables in the order they are displayed. # (Exports full path, but displays relative path) - export $git_env_char$e="$project_root/${stat_file[$i]}" + # fetch first file (in the case of oldFile -> newFile) and remove quotes + local filename=$(eval echo $(echo ${stat_file[$i]} | egrep -o '^"([^\\"]*(\\.[^"]*)*)"|^[^ ]+')) + export $git_env_char$e="$project_root/$filename" let e++ done echo -e "$c_hash#$c_rst" diff --git a/lib/git/repo_index.sh b/lib/git/repo_index.sh index 08349fa..78e2639 100644 --- a/lib/git/repo_index.sh +++ b/lib/git/repo_index.sh @@ -91,7 +91,11 @@ function git_index() { # Go to our base path if [ -n "$base_path" ]; then unset IFS - eval cd \"$base_path\" # eval turns ~ into $HOME + # evaluate ~ if necessary + if [[ "$base_path" == "~"* ]]; then + base_path=$(eval echo ${base_path%%/*})/${base_path#*/} + fi + cd "$base_path" # Run git callback (either update or show changes), if we are in the root directory if [ -z "${sub_path%/}" ]; then _git_index_update_or_status; fi else @@ -128,7 +132,7 @@ function _rebuild_git_index() { if [ "$1" != "--silent" ]; then echo -e "== Scanning $GIT_REPO_DIR for git repos & submodules..."; fi # Get repos from src dir and custom dirs, then sort by basename local IFS=$'\n' - for repo in $(echo -e "$(_find_git_repos)\n$(echo $GIT_REPOS | sed "s/:/\n/g")"); do + for repo in $(echo -e "$(_find_git_repos)\n$(echo $GIT_REPOS | sed "s/:/\\\\n/g")"); do echo $(basename $repo | sed "s/ /_/g") $repo done | sort | cut -d " " -f2- > "$GIT_REPO_DIR/.git_index" diff --git a/lib/git/status_shortcuts.rb b/lib/git/status_shortcuts.rb index 314bc49..332ff19 100644 --- a/lib/git/status_shortcuts.rb +++ b/lib/git/status_shortcuts.rb @@ -131,7 +131,12 @@ def output_file_group(group) puts "#{c_group}##{@c[:rst]} #{@c[h[:col]]}#{h[:msg]}:\ #{padding}#{@c[:dark]} [#{@c[:rst]}#{@e}#{@c[:dark]}] #{c_group}#{rel_file}#{@c[:rst]}" # Save the ordered list of output files - @output_files << h[:file] + # fetch first file (in the case of oldFile -> newFile) and remove quotes + @output_files << if h[:file] =~ /^"([^\\"]*(\\.[^"]*)*)"/ + $1.gsub(/\\(.)/,'\1') + else + h[:file].match(/^[^ ]*/)[0] + end end puts "#{c_group}##{@c[:rst]}" # Extra '#' diff --git a/lib/git/status_shortcuts.sh b/lib/git/status_shortcuts.sh index 5f94bdc..c637955 100644 --- a/lib/git/status_shortcuts.sh +++ b/lib/git/status_shortcuts.sh @@ -74,17 +74,20 @@ git_add_shortcuts() { # Does nothing if no args are given. git_silent_add_shortcuts() { if [ -n "$1" ]; then - # Expand args and process resulting set of files. - for file in $(git_expand_args "$@"); do + function process { + file=$1 # Use 'git rm' if file doesn't exist and 'ga_auto_remove' is enabled. - if [[ $ga_auto_remove == "yes" ]] && ! [ -e $file ]; then + if [[ $ga_auto_remove == "yes" ]] && ! [ -e "$file" ]; then echo -n "# " - git rm $file + git rm "$file" else - git add $file + git add "$file" echo -e "# add '$file'" fi - done + } + + # Expand args and process resulting set of files. + eval for file in $(git_expand_args "$@")\; do process "\$file"\; done echo "#" fi } @@ -109,9 +112,10 @@ git_add_patch_shortcuts() { git_silent_add_patch_shortcuts() { if [ -n "$1" ]; then # Expand args and process resulting set of files. - for file in $(git_expand_args "$@"); do - git add -p $file - echo -e "# add '$file'" + local IFS=$'\n' + eval for file in $(git_expand_args "$@")\; do\ + git add -p "\$file"\;\ + echo -e "# add '\$file'"\;\ done echo "#" fi @@ -136,21 +140,36 @@ git_show_affected_files(){ # * git_status_shortcuts() - git status implementation # * git_show_affected_files() - shows files affected by a given SHA1, etc. git_expand_args() { - files="" + first=1 for arg in "$@"; do if [[ "$arg" =~ ^[0-9]+$ ]] ; then # Substitute $e{*} variables for any integers - files="$files $(eval echo \$$git_env_char$arg)" - elif [[ $arg =~ ^[0-9]+\.\.[0-9]+$ ]]; then # Expand ranges into $e{*} variables - files="$files $(eval echo \$$git_env_char{$arg})" + if [ "$first" -eq 1 ]; then + first=0 + else + echo -n " " + fi + eval printf '%q' "\$$git_env_char$arg" + elif [[ "$arg" =~ ^[0-9]+\.\.[0-9]+$ ]]; then # Expand ranges into $e{*} variables + for i in $(eval echo {$arg}); do + if [ "$first" -eq 1 ]; then + first=0 + else + echo -n " " + fi + eval printf '%q' "\$$git_env_char$i" + done else # Otherwise, treat $arg as a normal string. - # If arg contains any spaces, (re)wrap it in double quotes - if echo $arg | grep -q " "; then arg="\"$arg\""; fi - files="$files $arg" + if [ "$first" -eq 1 ]; then + first=0 + else + echo -n " " + fi + printf '%q' "$arg" fi done - echo $files } # Execute a command with expanded args, e.g. Delete files 6 to 12: $ ge rm 6..12 +# Fails if command is a number or range (probably not worth fixing) exec_git_expand_args() { $(git_expand_args "$@"); } # Clear numbered env variables @@ -164,8 +183,8 @@ git_clear_vars() { # Shortcuts for resolving merge conflicts. -ours(){ local files=$(git_expand_args "$@"); git checkout --ours $files; git add $files; } -theirs(){ local files=$(git_expand_args "$@"); git checkout --theirs $files; git add $files; } +ours(){ local files=$(git_expand_args "$@"); git checkout --ours "$files"; git add "$files"; } +theirs(){ local files=$(git_expand_args "$@"); git checkout --theirs "$files"; git add "$files"; } # Git commit prompts diff --git a/test/lib/git/repo_index_test.sh b/test/lib/git/repo_index_test.sh index 005ca56..85d679a 100755 --- a/test/lib/git/repo_index_test.sh +++ b/test/lib/git/repo_index_test.sh @@ -23,7 +23,7 @@ if [ -n "${ZSH_VERSION:-}" ]; then shell="zsh"; SHUNIT_PARENT=$0; setopt shwords # Setup and tear down #----------------------------------------------------------------------------- oneTimeSetUp() { - GIT_REPO_DIR=$(mktemp -d) + GIT_REPO_DIR=$(mktemp -d -t scm_breeze.XXXXXXXXXX) GIT_REPOS="/tmp/test_repo_1:/tmp/test_repo_11" git_status_command="git status" diff --git a/test/lib/git/status_shortcuts_test.sh b/test/lib/git/status_shortcuts_test.sh index 1776a17..7d35973 100755 --- a/test/lib/git/status_shortcuts_test.sh +++ b/test/lib/git/status_shortcuts_test.sh @@ -28,7 +28,7 @@ oneTimeSetUp() { export gs_max_changes="20" export ga_auto_remove="yes" - testRepo=$(mktemp -d) + testRepo=$(mktemp -d -t scm_breeze.XXXXXXXXXX) } oneTimeTearDown() { @@ -55,8 +55,8 @@ test_git_expand_args() { assertEquals "$error" "seven two three four five one" "$(git_expand_args seven 2..5 1)" # Test that any args with spaces remain quoted - assertEquals "$error" "-m \"Test Commit Message\" one" "$(git_expand_args -m \"Test Commit Message\" 1)" - assertEquals "$error" "-ma \"Test Commit Message\" Unquoted"\ + assertEquals "$error" "-m Test\ Commit\ Message one" "$(git_expand_args -m "Test Commit Message" 1)" + assertEquals "$error" "-ma Test\ Commit\ Message Unquoted"\ "$(git_expand_args -ma "Test Commit Message" "Unquoted")" } @@ -95,7 +95,7 @@ test_git_status_shortcuts() { assertNotIncludes "$git_status3" "Untracked files" # Run command in shell, load output from temp file into variable - temp_file=$(mktemp) + temp_file=$(mktemp -t scm_breeze.XXXXXXXXXX) git_status_shortcuts > $temp_file git_status=$(cat $temp_file | strip_colors) @@ -232,7 +232,7 @@ test_git_commit_prompt() { commit_msg="\"Nathan's git commit prompt function!\"" dbl_escaped_msg="\\\\\"Nathan's git commit prompt function\"'"'!'"'\"\\\\\"" # Create temporary history file - HISTFILE=$(mktemp) + HISTFILE=$(mktemp -t scm_breeze.XXXXXXXXXX) HISTFILESIZE=1000 HISTSIZE=1000