stash: prefer plumbing over git-diff
authorJeff King <peff@peff.net>
Tue, 6 Dec 2016 20:25:21 +0000 (15:25 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 6 Dec 2016 22:16:53 +0000 (14:16 -0800)
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>
git-stash.sh
t/t3903-stash.sh
index c7509e8da47cf296143e3fa53a7f431f7672d78e..09344819132c82ffafb76cb79bf912252bda0118 100755 (executable)
@@ -116,7 +116,7 @@ create_stash () {
                        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"
index 2142c1fa92017bc47cfc4ccb1f25e16fc0eec1a4..ca2a6c1bccfc02a7c7a8b4b7963b80316258ed77 100755 (executable)
@@ -731,4 +731,13 @@ test_expect_success 'stash list --cc shows combined diff' '
        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