Merge branch 'jk/stash-disable-renames-internally'
authorJunio C Hamano <gitster@pobox.com>
Mon, 19 Dec 2016 22:45:33 +0000 (14:45 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Dec 2016 22:45:33 +0000 (14:45 -0800)
When diff.renames configuration is on (and with Git 2.9 and later,
it is enabled by default, which made it worse), "git stash"
misbehaved if a file is removed and another file with a very
similar content is added.

* jk/stash-disable-renames-internally:
stash: prefer plumbing over git-diff

1  2 
git-stash.sh
t/t3903-stash.sh
diff --combined git-stash.sh
index 4546abaaef3dab9e0c4dc719f111682f1cb1dd57,09344819132c82ffafb76cb79bf912252bda0118..10c284d1aa2273a3dfe5cc39f1d6738830d02462
@@@ -15,6 -15,7 +15,6 @@@ SUBDIRECTORY_OK=Ye
  OPTIONS_SPEC=
  START_DIR=$(pwd)
  . git-sh-setup
 -. git-sh-i18n
  require_work_tree
  cd_to_toplevel
  
@@@ -100,7 -101,7 +100,7 @@@ create_stash () 
                                u_tree=$(git write-tree) &&
                                printf 'untracked files on %s\n' "$msg" | git commit-tree $u_tree  &&
                                rm -f "$TMPindex"
 -              ) ) || die "Cannot save the untracked files"
 +              ) ) || die "$(gettext "Cannot save the untracked files")"
  
                untracked_commit_option="-p $u_commit";
        else
                        git read-tree --index-output="$TMPindex" -m $i_tree &&
                        GIT_INDEX_FILE="$TMPindex" &&
                        export GIT_INDEX_FILE &&
-                       git diff --name-only -z HEAD -- >"$TMP-stagenames" &&
+                       git diff-index --name-only -z HEAD -- >"$TMP-stagenames" &&
                        git update-index -z --add --remove --stdin <"$TMP-stagenames" &&
                        git write-tree &&
                        rm -f "$TMPindex"
@@@ -248,7 -249,7 +248,7 @@@ save_stash () 
  
        if test -n "$patch_mode" && test -n "$untracked"
        then
 -          die "Can't use --patch and --include-untracked or --all at the same time"
 +              die "$(gettext "Can't use --patch and --include-untracked or --all at the same time")"
        fi
  
        stash_msg="$*"
        create_stash "$stash_msg" $untracked
        store_stash -m "$stash_msg" -q $w_commit ||
        die "$(gettext "Cannot save the current status")"
 -      say Saved working directory and index state "$stash_msg"
 +      say "$(eval_gettext "Saved working directory and index state \$stash_msg")"
  
        if test -z "$patch_mode"
        then
@@@ -384,8 -385,9 +384,8 @@@ parse_flags_and_rev(
        i_tree=
        u_tree=
  
 -      REV=$(git rev-parse --no-flags --symbolic --sq "$@") || exit 1
 -
        FLAGS=
 +      REV=
        for opt
        do
                case "$opt" in
                                        die "$(eval_gettext "unknown option: \$opt")"
                                FLAGS="${FLAGS}${FLAGS:+ }$opt"
                        ;;
 +                      *)
 +                              REV="${REV}${REV:+ }'$opt'"
 +                      ;;
                esac
        done
  
                ;;
        esac
  
 +      case "$1" in
 +              *[!0-9]*)
 +                      :
 +              ;;
 +              *)
 +                      set -- "${ref_stash}@{$1}"
 +              ;;
 +      esac
 +
        REV=$(git rev-parse --symbolic --verify --quiet "$1") || {
                reference="$1"
                die "$(eval_gettext "\$reference is not a valid reference")"
@@@ -505,7 -495,7 +505,7 @@@ apply_stash () 
                GIT_INDEX_FILE="$TMPindex" git-read-tree "$u_tree" &&
                GIT_INDEX_FILE="$TMPindex" git checkout-index --all &&
                rm -f "$TMPindex" ||
 -              die 'Could not restore untracked files from stash'
 +              die "$(gettext "Could not restore untracked files from stash")"
        fi
  
        eval "
@@@ -559,7 -549,7 +559,7 @@@ pop_stash() 
                drop_stash "$@"
        else
                status=$?
 -              say "The stash is kept in case you need it again."
 +              say "$(gettext "The stash is kept in case you need it again.")"
                exit $status
        fi
  }
diff --combined t/t3903-stash.sh
index e1a6ccc00c5988cfa8808bccc49a5e21703166b6,ca2a6c1bccfc02a7c7a8b4b7963b80316258ed77..2de3e18ce68a94111c8dfcca858b8515ea8919c1
@@@ -131,26 -131,6 +131,26 @@@ test_expect_success 'drop middle stash
        test 1 = $(git show HEAD:file)
  '
  
 +test_expect_success 'drop middle stash by index' '
 +      git reset --hard &&
 +      echo 8 >file &&
 +      git stash &&
 +      echo 9 >file &&
 +      git stash &&
 +      git stash drop 1 &&
 +      test 2 = $(git stash list | wc -l) &&
 +      git stash apply &&
 +      test 9 = $(cat file) &&
 +      test 1 = $(git show :file) &&
 +      test 1 = $(git show HEAD:file) &&
 +      git reset --hard &&
 +      git stash drop &&
 +      git stash apply &&
 +      test 3 = $(cat file) &&
 +      test 1 = $(git show :file) &&
 +      test 1 = $(git show HEAD:file)
 +'
 +
  test_expect_success 'stash pop' '
        git reset --hard &&
        git stash pop &&
@@@ -624,21 -604,6 +624,21 @@@ test_expect_success 'invalid ref of th
        git stash drop
  '
  
 +test_expect_success 'invalid ref of the form "n", n >= N' '
 +      git stash clear &&
 +      test_must_fail git stash drop 0 &&
 +      echo bar5 >file &&
 +      echo bar6 >file2 &&
 +      git add file2 &&
 +      git stash &&
 +      test_must_fail git stash drop 1 &&
 +      test_must_fail git stash pop 1 &&
 +      test_must_fail git stash apply 1 &&
 +      test_must_fail git stash show 1 &&
 +      test_must_fail git stash branch tmp 1 &&
 +      git stash drop
 +'
 +
  test_expect_success 'stash branch should not drop the stash if the branch exists' '
        git stash clear &&
        echo foo >file &&
@@@ -766,4 -731,13 +766,13 @@@ test_expect_success 'stash list --cc sh
        test_cmp expect actual
  '
  
+ test_expect_success 'stash is not confused by partial renames' '
+       mv file renamed &&
+       git add renamed &&
+       git stash &&
+       git stash apply &&
+       test_path_is_file renamed &&
+       test_path_is_missing file
+ '
  test_done