diff options
Diffstat (limited to 't/t2018-checkout-branch.sh')
-rwxr-xr-x | t/t2018-checkout-branch.sh | 107 |
1 files changed, 83 insertions, 24 deletions
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 822381dd9d..5f761bc616 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -1,50 +1,76 @@ #!/bin/sh -test_description='checkout ' +test_description='checkout' . ./test-lib.sh -# Arguments: <branch> <sha> [<checkout options>] +# Arguments: [!] <branch> <oid> [<checkout options>] # # Runs "git checkout" to switch to <branch>, testing that # # 1) we are on the specified branch, <branch>; -# 2) HEAD is <sha>; if <sha> is not specified, the old HEAD is used. +# 2) HEAD is <oid>; if <oid> is not specified, the old HEAD is used. # # If <checkout options> is not specified, "git checkout" is run with -b. -do_checkout() { +# +# If the first argument is `!`, "git checkout" is expected to fail when +# it is run. +do_checkout () { + should_fail= && + if test "x$1" = "x!" + then + should_fail=yes && + shift + fi && exp_branch=$1 && exp_ref="refs/heads/$exp_branch" && - # if <sha> is not specified, use HEAD. - exp_sha=${2:-$(git rev-parse --verify HEAD)} && + # if <oid> is not specified, use HEAD. + exp_oid=${2:-$(git rev-parse --verify HEAD)} && # default options for git checkout: -b - if [ -z "$3" ]; then + if test -z "$3" + then opts="-b" else opts="$3" fi - git checkout $opts $exp_branch $exp_sha && + if test -n "$should_fail" + then + test_must_fail git checkout $opts $exp_branch $exp_oid + else + git checkout $opts $exp_branch $exp_oid && + echo "$exp_ref" >ref.expect && + git rev-parse --symbolic-full-name HEAD >ref.actual && + test_cmp ref.expect ref.actual && + echo "$exp_oid" >oid.expect && + git rev-parse --verify HEAD >oid.actual && + test_cmp oid.expect oid.actual + fi +} - test $exp_ref = $(git rev-parse --symbolic-full-name HEAD) && - test $exp_sha = $(git rev-parse --verify HEAD) +test_dirty_unmergeable () { + test_expect_code 1 git diff --exit-code } -test_dirty_unmergeable() { - ! git diff --exit-code >/dev/null +test_dirty_unmergeable_discards_changes () { + git diff --exit-code } -setup_dirty_unmergeable() { +setup_dirty_unmergeable () { echo >>file1 change2 } -test_dirty_mergeable() { - ! git diff --cached --exit-code >/dev/null +test_dirty_mergeable () { + test_expect_code 1 git diff --cached --exit-code +} + +test_dirty_mergeable_discards_changes () { + git diff --cached --exit-code } -setup_dirty_mergeable() { +setup_dirty_mergeable () { echo >file2 file2 && git add file2 } @@ -82,7 +108,7 @@ test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' test_expect_success 'checkout -b to a new branch with unmergeable changes fails' ' setup_dirty_unmergeable && - test_must_fail do_checkout branch2 $HEAD1 && + do_checkout ! branch2 $HEAD1 && test_dirty_unmergeable ' @@ -93,7 +119,7 @@ test_expect_success 'checkout -f -b to a new branch with unmergeable changes dis # still dirty and on branch1 do_checkout branch2 $HEAD1 "-f -b" && - test_must_fail test_dirty_unmergeable + test_dirty_unmergeable_discards_changes ' test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' @@ -111,12 +137,12 @@ test_expect_success 'checkout -f -b to a new branch with mergeable changes disca test_when_finished git reset --hard HEAD && setup_dirty_mergeable && do_checkout branch2 $HEAD1 "-f -b" && - test_must_fail test_dirty_mergeable + test_dirty_mergeable_discards_changes ' test_expect_success 'checkout -b to an existing branch fails' ' test_when_finished git reset --hard HEAD && - test_must_fail do_checkout branch2 $HEAD2 + do_checkout ! branch2 $HEAD2 ' test_expect_success 'checkout -b to @{-1} fails with the right branch name' ' @@ -140,7 +166,8 @@ test_expect_success 'checkout -B to a merge base' ' ' test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' ' - git checkout $(git rev-parse --verify HEAD) && + head=$(git rev-parse --verify HEAD) && + git checkout "$head" && do_checkout branch2 "" -B ' @@ -155,14 +182,14 @@ test_expect_success 'checkout -B to an existing branch with unmergeable changes git checkout branch1 && setup_dirty_unmergeable && - test_must_fail do_checkout branch2 $HEAD1 -B && + do_checkout ! branch2 $HEAD1 -B && test_dirty_unmergeable ' test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' ' # still dirty and on branch1 do_checkout branch2 $HEAD1 "-f -B" && - test_must_fail test_dirty_unmergeable + test_dirty_unmergeable_discards_changes ' test_expect_success 'checkout -B to an existing branch preserves mergeable changes' ' @@ -179,7 +206,7 @@ test_expect_success 'checkout -f -B to an existing branch with mergeable changes setup_dirty_mergeable && do_checkout branch2 $HEAD1 "-f -B" && - test_must_fail test_dirty_mergeable + test_dirty_mergeable_discards_changes ' test_expect_success 'checkout -b <describe>' ' @@ -211,4 +238,36 @@ test_expect_success 'checkout -b after clone --no-checkout does a checkout of HE test_path_is_file dest/a.t ' +test_expect_success 'checkout -b to a new branch preserves mergeable changes despite sparse-checkout' ' + test_when_finished " + git reset --hard && + git checkout branch1-scratch && + test_might_fail git branch -D branch3 && + git config core.sparseCheckout false && + rm .git/info/sparse-checkout" && + + test_commit file2 && + + echo stuff >>file1 && + echo file2 >.git/info/sparse-checkout && + git config core.sparseCheckout true && + + CURHEAD=$(git rev-parse HEAD) && + do_checkout branch3 $CURHEAD && + + echo file1 >expect && + git diff --name-only >actual && + test_cmp expect actual +' + +test_expect_success 'checkout -b rejects an invalid start point' ' + test_must_fail git checkout -b branch4 file1 2>err && + test_i18ngrep "is not a commit" err +' + +test_expect_success 'checkout -b rejects an extra path argument' ' + test_must_fail git checkout -b branch5 branch1 file1 2>err && + test_i18ngrep "Cannot update paths and switch to branch" err +' + test_done |