diff --git a/git-stash.sh b/git-stash.sh index fc8f8ae640..94793c1a91 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -39,7 +39,7 @@ fi no_changes () { git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" && git diff-files --quiet --ignore-submodules -- "$@" && - (test -z "$untracked" || test -z "$(untracked_files)") + (test -z "$untracked" || test -z "$(untracked_files "$@")") } untracked_files () { @@ -315,16 +315,18 @@ push_stash () { if test -z "$patch_mode" then test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION= - if test -n "$untracked" + if test -n "$untracked" && test $# = 0 then - git clean --force --quiet -d $CLEAN_X_OPTION -- "$@" + git clean --force --quiet -d $CLEAN_X_OPTION fi if test $# != 0 then - git add -u -- "$@" | - git checkout-index -z --force --stdin - git diff-index -p --cached --binary HEAD -- "$@" | git apply --index -R + test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION= + test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION= + git add $UPDATE_OPTION $FORCE_OPTION -- "$@" + git diff-index -p --cached --binary HEAD -- "$@" | + git apply --index -R else git reset --hard -q fi diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index bfde4057ad..3ea5b9bb3f 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -228,4 +228,56 @@ test_expect_success 'stash previously ignored file' ' test_path_is_file ignored.d/foo ' +test_expect_success 'stash -u -- doesnt print error' ' + >untracked && + git stash push -u -- untracked 2>actual && + test_path_is_missing untracked && + test_line_count = 0 actual +' + +test_expect_success 'stash -u -- leaves rest of working tree in place' ' + >tracked && + git add tracked && + >untracked && + git stash push -u -- untracked && + test_path_is_missing untracked && + test_path_is_file tracked +' + +test_expect_success 'stash -u -- clears changes in both' ' + >tracked && + git add tracked && + >untracked && + git stash push -u -- tracked untracked && + test_path_is_missing tracked && + test_path_is_missing untracked +' + +test_expect_success 'stash --all -- stashes ignored file' ' + >ignored.d/bar && + git stash push --all -- ignored.d/bar && + test_path_is_missing ignored.d/bar +' + +test_expect_success 'stash --all -- clears changes in both' ' + >tracked && + git add tracked && + >ignored.d/bar && + git stash push --all -- tracked ignored.d/bar && + test_path_is_missing tracked && + test_path_is_missing ignored.d/bar +' + +test_expect_success 'stash -u -- leaves ignored file alone' ' + >ignored.d/bar && + git stash push -u -- ignored.d/bar && + test_path_is_file ignored.d/bar +' + +test_expect_success 'stash -u -- shows no changes when there are none' ' + git stash push -u -- non-existant >actual && + echo "No local changes to save" >expect && + test_i18ncmp expect actual +' + test_done