diff options
Diffstat (limited to 't/t3903-stash.sh')
-rwxr-xr-x | t/t3903-stash.sh | 313 |
1 files changed, 237 insertions, 76 deletions
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 5f8272b6f9..ea56e85e70 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -7,23 +7,35 @@ test_description='Test git stash' . ./test-lib.sh +diff_cmp () { + for i in "$1" "$2" + do + sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \ + -e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \ + -e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \ + "$i" >"$i.compare" || return 1 + done && + test_cmp "$1.compare" "$2.compare" && + rm -f "$1.compare" "$2.compare" +} + test_expect_success 'stash some dirty working directory' ' - echo 1 > file && + echo 1 >file && git add file && echo unrelated >other-file && git add other-file && test_tick && git commit -m initial && - echo 2 > file && + echo 2 >file && git add file && - echo 3 > file && + echo 3 >file && test_tick && git stash && git diff-files --quiet && git diff-index --cached --quiet HEAD ' -cat > expect << EOF +cat >expect <<EOF diff --git a/file b/file index 0cfbf08..00750ed 100644 --- a/file @@ -35,8 +47,8 @@ EOF test_expect_success 'parents of stash' ' test $(git rev-parse stash^) = $(git rev-parse HEAD) && - git diff stash^2..stash > output && - test_cmp expect output + git diff stash^2..stash >output && + diff_cmp expect output ' test_expect_success 'applying bogus stash does nothing' ' @@ -74,7 +86,7 @@ test_expect_success 'apply stashed changes' ' test_expect_success 'apply stashed changes (including index)' ' git reset --hard HEAD^ && - echo 6 > other-file && + echo 6 >other-file && git add other-file && test_tick && git commit -m other-file && @@ -99,12 +111,12 @@ test_expect_success 'stash drop complains of extra options' ' test_expect_success 'drop top stash' ' git reset --hard && - git stash list > stashlist1 && - echo 7 > file && + git stash list >expected && + echo 7 >file && git stash && git stash drop && - git stash list > stashlist2 && - test_cmp stashlist1 stashlist2 && + git stash list >actual && + test_cmp expected actual && git stash apply && test 3 = $(cat file) && test 1 = $(git show :file) && @@ -113,9 +125,9 @@ test_expect_success 'drop top stash' ' test_expect_success 'drop middle stash' ' git reset --hard && - echo 8 > file && + echo 8 >file && git stash && - echo 9 > file && + echo 9 >file && git stash && git stash drop stash@{1} && test 2 = $(git stash list | wc -l) && @@ -160,7 +172,7 @@ test_expect_success 'stash pop' ' test 0 = $(git stash list | wc -l) ' -cat > expect << EOF +cat >expect <<EOF diff --git a/file2 b/file2 new file mode 100644 index 0000000..1fe912c @@ -170,7 +182,7 @@ index 0000000..1fe912c +bar2 EOF -cat > expect1 << EOF +cat >expect1 <<EOF diff --git a/file b/file index 257cc56..5716ca5 100644 --- a/file @@ -180,7 +192,7 @@ index 257cc56..5716ca5 100644 +bar EOF -cat > expect2 << EOF +cat >expect2 <<EOF diff --git a/file b/file index 7601807..5716ca5 100644 --- a/file @@ -198,79 +210,84 @@ index 0000000..1fe912c EOF test_expect_success 'stash branch' ' - echo foo > file && + echo foo >file && git commit file -m first && - echo bar > file && - echo bar2 > file2 && + echo bar >file && + echo bar2 >file2 && git add file2 && git stash && - echo baz > file && + echo baz >file && git commit file -m second && git stash branch stashbranch && test refs/heads/stashbranch = $(git symbolic-ref HEAD) && test $(git rev-parse HEAD) = $(git rev-parse master^) && - git diff --cached > output && - test_cmp expect output && - git diff > output && - test_cmp expect1 output && + git diff --cached >output && + diff_cmp expect output && + git diff >output && + diff_cmp expect1 output && git add file && git commit -m alternate\ second && - git diff master..stashbranch > output && - test_cmp output expect2 && + git diff master..stashbranch >output && + diff_cmp output expect2 && test 0 = $(git stash list | wc -l) ' test_expect_success 'apply -q is quiet' ' - echo foo > file && + echo foo >file && git stash && - git stash apply -q > output.out 2>&1 && + git stash apply -q >output.out 2>&1 && test_must_be_empty output.out ' test_expect_success 'save -q is quiet' ' - git stash save --quiet > output.out 2>&1 && + git stash save --quiet >output.out 2>&1 && test_must_be_empty output.out ' -test_expect_success 'pop -q is quiet' ' - git stash pop -q > output.out 2>&1 && +test_expect_success 'pop -q works and is quiet' ' + git stash pop -q >output.out 2>&1 && + echo bar >expect && + git show :file >actual && + test_cmp expect actual && test_must_be_empty output.out ' test_expect_success 'pop -q --index works and is quiet' ' - echo foo > file && + echo foo >file && git add file && git stash save --quiet && - git stash pop -q --index > output.out 2>&1 && + git stash pop -q --index >output.out 2>&1 && + git diff-files file2 >file2.diff && + test_must_be_empty file2.diff && test foo = "$(git show :file)" && test_must_be_empty output.out ' test_expect_success 'drop -q is quiet' ' git stash && - git stash drop -q > output.out 2>&1 && + git stash drop -q >output.out 2>&1 && test_must_be_empty output.out ' test_expect_success 'stash -k' ' - echo bar3 > file && - echo bar4 > file2 && + echo bar3 >file && + echo bar4 >file2 && git add file2 && git stash -k && test bar,bar4 = $(cat file),$(cat file2) ' test_expect_success 'stash --no-keep-index' ' - echo bar33 > file && - echo bar44 > file2 && + echo bar33 >file && + echo bar44 >file2 && git add file2 && git stash --no-keep-index && test bar,bar2 = $(cat file),$(cat file2) ' test_expect_success 'stash --invalid-option' ' - echo bar5 > file && - echo bar6 > file2 && + echo bar5 >file && + echo bar6 >file2 && git add file2 && test_must_fail git stash --invalid-option && test_must_fail git stash save --invalid-option && @@ -287,6 +304,14 @@ test_expect_success 'stash an added file' ' test new = "$(cat file3)" ' +test_expect_success 'stash --intent-to-add file' ' + git reset --hard && + echo new >file4 && + git add --intent-to-add file4 && + test_when_finished "git rm -f file4" && + test_must_fail git stash +' + test_expect_success 'stash rm then recreate' ' git reset --hard && git rm file && @@ -444,6 +469,36 @@ test_expect_failure 'stash file to directory' ' test foo = "$(cat file/file)" ' +test_expect_success 'giving too many ref arguments does not modify files' ' + git stash clear && + test_when_finished "git reset --hard HEAD" && + echo foo >file2 && + git stash && + echo bar >file2 && + git stash && + test-tool chmtime =123456789 file2 && + for type in apply pop "branch stash-branch" + do + test_must_fail git stash $type stash@{0} stash@{1} 2>err && + test_i18ngrep "Too many revisions" err && + test 123456789 = $(test-tool chmtime -g file2) || return 1 + done +' + +test_expect_success 'drop: too many arguments errors out (does nothing)' ' + git stash list >expect && + test_must_fail git stash drop stash@{0} stash@{1} 2>err && + test_i18ngrep "Too many revisions" err && + git stash list >actual && + test_cmp expect actual +' + +test_expect_success 'show: too many arguments errors out (does nothing)' ' + test_must_fail git stash show stash@{0} stash@{1} 2>err 1>out && + test_i18ngrep "Too many revisions" err && + test_must_be_empty out +' + test_expect_success 'stash create - no changes' ' git stash clear && test_when_finished "git reset --hard HEAD" && @@ -456,11 +511,12 @@ test_expect_success 'stash branch - no stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && STASH_ID=$(git stash create) && git reset --hard && git stash branch stash-branch ${STASH_ID} && - test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test_when_finished "git reset --hard HEAD && git checkout master && + git branch -D stash-branch" && test $(git ls-files --modified | wc -l) -eq 1 ' @@ -468,25 +524,31 @@ test_expect_success 'stash branch - stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && git stash && test_when_finished "git stash drop" && - echo bar >> file && + echo bar >>file && STASH_ID=$(git stash create) && git reset --hard && git stash branch stash-branch ${STASH_ID} && - test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" && + test_when_finished "git reset --hard HEAD && git checkout master && + git branch -D stash-branch" && test $(git ls-files --modified | wc -l) -eq 1 ' +test_expect_success 'stash branch complains with no arguments' ' + test_must_fail git stash branch 2>err && + test_i18ngrep "No branch name specified" err +' + test_expect_success 'stash show format defaults to --stat' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && git stash && test_when_finished "git stash drop" && - echo bar >> file && + echo bar >>file && STASH_ID=$(git stash create) && git reset --hard && cat >expected <<-EOF && @@ -501,10 +563,10 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && git stash && test_when_finished "git stash drop" && - echo bar >> file && + echo bar >>file && STASH_ID=$(git stash create) && git reset --hard && echo "1 0 file" >expected && @@ -516,10 +578,10 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && git stash && test_when_finished "git stash drop" && - echo bar >> file && + echo bar >>file && STASH_ID=$(git stash create) && git reset --hard && cat >expected <<-EOF && @@ -532,14 +594,14 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' ' +bar EOF git stash show -p ${STASH_ID} >actual && - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'stash show - no stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && STASH_ID=$(git stash create) && git reset --hard && echo "1 0 file" >expected && @@ -551,7 +613,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' ' git stash clear && test_when_finished "git reset --hard HEAD" && git reset --hard && - echo foo >> file && + echo foo >>file && STASH_ID=$(git stash create) && git reset --hard && cat >expected <<-EOF && @@ -564,16 +626,34 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' ' +foo EOF git stash show -p ${STASH_ID} >actual && - test_cmp expected actual + diff_cmp expected actual +' + +test_expect_success 'stash show --patience shows diff' ' + git reset --hard && + echo foo >>file && + STASH_ID=$(git stash create) && + git reset --hard && + cat >expected <<-EOF && + diff --git a/file b/file + index 7601807..71b52c4 100644 + --- a/file + +++ b/file + @@ -1 +1,2 @@ + baz + +foo + EOF + git stash show --patience ${STASH_ID} >actual && + diff_cmp expected actual ' -test_expect_success 'stash drop - fail early if specified stash is not a stash reference' ' +test_expect_success 'drop: fail early if specified stash is not a stash ref' ' git stash clear && test_when_finished "git reset --hard HEAD && git stash clear" && git reset --hard && - echo foo > file && + echo foo >file && git stash && - echo bar > file && + echo bar >file && git stash && test_must_fail git stash drop $(git rev-parse stash@{0}) && git stash pop && @@ -581,13 +661,13 @@ test_expect_success 'stash drop - fail early if specified stash is not a stash r git reset --hard HEAD ' -test_expect_success 'stash pop - fail early if specified stash is not a stash reference' ' +test_expect_success 'pop: fail early if specified stash is not a stash ref' ' git stash clear && test_when_finished "git reset --hard HEAD && git stash clear" && git reset --hard && - echo foo > file && + echo foo >file && git stash && - echo bar > file && + echo bar >file && git stash && test_must_fail git stash pop $(git rev-parse stash@{0}) && git stash pop && @@ -597,8 +677,8 @@ test_expect_success 'stash pop - fail early if specified stash is not a stash re test_expect_success 'ref with non-existent reflog' ' git stash clear && - echo bar5 > file && - echo bar6 > file2 && + echo bar5 >file && + echo bar6 >file2 && git add file2 && git stash && test_must_fail git rev-parse --quiet --verify does-not-exist && @@ -618,8 +698,8 @@ test_expect_success 'ref with non-existent reflog' ' test_expect_success 'invalid ref of the form stash@{n}, n >= N' ' git stash clear && test_must_fail git stash drop stash@{0} && - echo bar5 > file && - echo bar6 > file2 && + echo bar5 >file && + echo bar6 >file2 && git add file2 && git stash && test_must_fail git stash drop stash@{1} && @@ -645,7 +725,25 @@ test_expect_success 'invalid ref of the form "n", n >= N' ' git stash drop ' -test_expect_success 'stash branch should not drop the stash if the branch exists' ' +test_expect_success 'valid ref of the form "n", n < N' ' + git stash clear && + echo bar5 >file && + echo bar6 >file2 && + git add file2 && + git stash && + git stash show 0 && + git stash branch tmp 0 && + git checkout master && + git stash && + git stash apply 0 && + git reset --hard && + git stash pop 0 && + git stash && + git stash drop 0 && + test_must_fail git stash drop +' + +test_expect_success 'branch: do not drop the stash if the branch exists' ' git stash clear && echo foo >file && git add file && @@ -656,7 +754,7 @@ test_expect_success 'stash branch should not drop the stash if the branch exists git rev-parse stash@{0} -- ' -test_expect_success 'stash branch should not drop the stash if the apply fails' ' +test_expect_success 'branch: should not drop the stash if the apply fails' ' git stash clear && git reset HEAD~1 --hard && echo foo >file && @@ -670,7 +768,7 @@ test_expect_success 'stash branch should not drop the stash if the apply fails' git rev-parse stash@{0} -- ' -test_expect_success 'stash apply shows status same as git status (relative to current directory)' ' +test_expect_success 'apply: show same status as git status (relative to ./)' ' git stash clear && echo 1 >subdir/subfile1 && echo 2 >subdir/subfile2 && @@ -689,7 +787,7 @@ test_expect_success 'stash apply shows status same as git status (relative to cu test_i18ncmp expect actual ' -cat > expect << EOF +cat >expect <<EOF diff --git a/HEAD b/HEAD new file mode 100644 index 0000000..fe0cbee @@ -702,15 +800,15 @@ EOF test_expect_success 'stash where working directory contains "HEAD" file' ' git stash clear && git reset --hard && - echo file-not-a-ref > HEAD && + echo file-not-a-ref >HEAD && git add HEAD && test_tick && git stash && git diff-files --quiet && git diff-index --cached --quiet HEAD && test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" && - git diff stash^..stash > output && - test_cmp expect output + git diff stash^..stash >output && + diff_cmp expect output ' test_expect_success 'store called with invalid commit' ' @@ -766,7 +864,7 @@ test_expect_success 'stash list implies --first-parent -m' ' +working EOF git stash list --format=%gd -p >actual && - test_cmp expect actual + diff_cmp expect actual ' test_expect_success 'stash list --cc shows combined diff' ' @@ -783,7 +881,7 @@ test_expect_success 'stash list --cc shows combined diff' ' ++working EOF git stash list --format=%gd -p --cc >actual && - test_cmp expect actual + diff_cmp expect actual ' test_expect_success 'stash is not confused by partial renames' ' @@ -1011,7 +1109,7 @@ test_expect_success 'stash push -p with pathspec shows no changes only once' ' test_i18ncmp expect actual ' -test_expect_success 'stash push with pathspec shows no changes when there are none' ' +test_expect_success 'push <pathspec>: show no changes when there are none' ' >foo && git add foo && git commit -m "tmp" && @@ -1021,12 +1119,35 @@ test_expect_success 'stash push with pathspec shows no changes when there are no test_i18ncmp expect actual ' -test_expect_success 'stash push with pathspec not in the repository errors out' ' +test_expect_success 'push: <pathspec> not in the repository errors out' ' >untracked && test_must_fail git stash push untracked && test_path_is_file untracked ' +test_expect_success 'push: -q is quiet with changes' ' + >foo && + git add foo && + git stash push -q >output 2>&1 && + test_must_be_empty output +' + +test_expect_success 'push: -q is quiet with no changes' ' + git stash push -q >output 2>&1 && + test_must_be_empty output +' + +test_expect_success 'push: -q is quiet even if there is no initial commit' ' + git init foo_dir && + test_when_finished rm -rf foo_dir && + ( + cd foo_dir && + >bar && + test_must_fail git stash push -q >output 2>&1 && + test_must_be_empty output + ) +' + test_expect_success 'untracked files are left in place when -u is not given' ' >file && git add file && @@ -1096,6 +1217,12 @@ test_expect_success 'stash -- <subdir> works with binary files' ' test_path_is_file subdir/untracked ' +test_expect_success 'stash with user.name and user.email set works' ' + test_config user.name "A U Thor" && + test_config user.email "a.u@thor" && + git stash +' + test_expect_success 'stash works when user.name and user.email are not set' ' git reset && >1 && @@ -1124,4 +1251,38 @@ test_expect_success 'stash works when user.name and user.email are not set' ' ) ' +test_expect_success 'stash --keep-index with file deleted in index does not resurrect it on disk' ' + test_commit to-remove to-remove && + git rm to-remove && + git stash --keep-index && + test_path_is_missing to-remove +' + +test_expect_success 'stash apply should succeed with unmodified file' ' + echo base >file && + git add file && + git commit -m base && + + # now stash a modification + echo modified >file && + git stash && + + # make the file stat dirty + cp file other && + mv other file && + + git stash apply +' + +test_expect_success 'stash handles skip-worktree entries nicely' ' + test_commit A && + echo changed >A.t && + git add A.t && + git update-index --skip-worktree A.t && + rm A.t && + git stash && + + git rev-parse --verify refs/stash:A.t +' + test_done |