stash: prefer plumbing over git-diff

When creating a stash, we need to look at the diff between the working tree and HEAD, and do so using the git-diff porcelain. Because git-diff enables porcelain config like renames by default, this causes at least one problem. The --name-only format will not mention the source side of a rename, meaning we will fail to stash a deletion that is part of a rename. We could fix that case by passing --no-renames, but this is a symptom of a larger problem. We should be using the diff-index plumbing here, which does not have renames enabled by default, and also does not respect any potentially confusing config options. Reported-by: Matthew Patey <matthew.patey2167@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Dec 6, 2016 at 15:25 UTC 9d4e28ead5bf133d014dfc9e9345f6bf083eefea
2 files changed +10 -1
git-stash.sh
+1 -1
@@ -116,7 +116,7 @@ create_stash () {
116 git read-tree --index-output="$TMPindex" -m $i_tree &&
117 GIT_INDEX_FILE="$TMPindex" &&
118 export GIT_INDEX_FILE &&
119 - git diff --name-only -z HEAD -- >"$TMP-stagenames" &&
119 + git diff-index --name-only -z HEAD -- >"$TMP-stagenames" &&
120 git update-index -z --add --remove --stdin <"$TMP-stagenames" &&
121 git write-tree &&
122 rm -f "$TMPindex"
t/t3903-stash.sh
+9
@@ -731,4 +731,13 @@ test_expect_success 'stash list --cc shows combined diff' '
731 test_cmp expect actual
732 '
733
734 +test_expect_success 'stash is not confused by partial renames' '
735 + mv file renamed &&
736 + git add renamed &&
737 + git stash &&
738 + git stash apply &&
739 + test_path_is_file renamed &&
740 + test_path_is_missing file
741 +'
742 +
743 test_done