# Copyright (c) 2006 Junio C Hamano
#
-test_description='git-checkout tests.
+test_description='git checkout tests.
Creates master, forks renamer and side branches from it.
Test switching across them.
fill 0 1 2 3 4 5 6 7 8 >same &&
cp same kept
git checkout side >messages &&
- diff -u same kept
+ test_cmp same kept
(cat > messages.expect <<EOF
M same
EOF
) &&
touch messages.expect &&
- diff -u messages.expect messages
+ test_cmp messages.expect messages
'
test_expect_success "checkout -m with dirty tree" '
M one
EOF
) &&
- diff -u expect.messages messages &&
+ test_cmp expect.messages messages &&
fill "M one" "A three" "D two" >expect.master &&
git diff --name-status master >current.master &&
- diff -u expect.master current.master &&
+ test_cmp expect.master current.master &&
fill "M one" >expect.side &&
git diff --name-status side >current.side &&
- diff -u expect.side current.side &&
+ test_cmp expect.side current.side &&
: >expect.index &&
git diff --cached >current.index &&
- diff -u expect.index current.index
+ test_cmp expect.index current.index
'
test_expect_success "checkout -m with dirty tree, renamed" '
git checkout -m renamer &&
fill 1 3 4 5 7 8 >expect &&
- diff -u expect uno &&
+ test_cmp expect uno &&
! test -f one &&
git diff --cached >current &&
! test -s current
git diff master:one :3:uno |
sed -e "1,/^@@/d" -e "/^ /d" -e "s/^-/d/" -e "s/^+/a/" >current &&
fill d2 aT d7 aS >expect &&
- diff -u current expect &&
+ test_cmp current expect &&
git diff --cached two >current &&
! test -s current
'
HEAD is now at 7329388... Initial A one, A two
EOF
) &&
- diff -u messages.expect messages &&
+ test_cmp messages.expect messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
fi
'
+test_expect_success 'checkout to detach HEAD with :/message' '
+
+ git checkout -f master && git clean -f &&
+ git checkout ":/Initial" &&
+ H=$(git rev-parse --verify HEAD) &&
+ M=$(git show-ref -s --verify refs/heads/master) &&
+ test "z$H" = "z$M" &&
+ if git symbolic-ref HEAD >/dev/null 2>&1
+ then
+ echo "OOPS, HEAD is still symbolic???"
+ false
+ else
+ : happy
+ fi
+'
+
test_expect_success 'checkout to detach HEAD with HEAD^0' '
git checkout -f master && git clean -f &&
'
+test_expect_success \
+ 'checkout w/--track sets up tracking' '
+ git config branch.autosetupmerge false &&
+ git checkout master &&
+ git checkout --track -b track1 &&
+ test "$(git config branch.track1.remote)" &&
+ test "$(git config branch.track1.merge)"'
+
+test_expect_success \
+ 'checkout w/autosetupmerge=always sets up tracking' '
+ git config branch.autosetupmerge always &&
+ git checkout master &&
+ git checkout -b track2 &&
+ test "$(git config branch.track2.remote)" &&
+ test "$(git config branch.track2.merge)"
+ git config branch.autosetupmerge false'
+
+test_expect_success 'checkout w/--track from non-branch HEAD fails' '
+ git checkout master^0 &&
+ test_must_fail git symbolic-ref HEAD &&
+ test_must_fail git checkout --track -b track &&
+ test_must_fail git rev-parse --verify track &&
+ test_must_fail git symbolic-ref HEAD &&
+ test "z$(git rev-parse master^0)" = "z$(git rev-parse HEAD)"
+'
+
+test_expect_success 'detach a symbolic link HEAD' '
+ git checkout master &&
+ git config --bool core.prefersymlinkrefs yes &&
+ git checkout side &&
+ git checkout master &&
+ it=$(git symbolic-ref HEAD) &&
+ test "z$it" = zrefs/heads/master &&
+ here=$(git rev-parse --verify refs/heads/master) &&
+ git checkout side^ &&
+ test "z$(git rev-parse --verify refs/heads/master)" = "z$here"
+'
+
+test_expect_success \
+ 'checkout with --track fakes a sensible -b <name>' '
+ git update-ref refs/remotes/origin/koala/bear renamer &&
+ git update-ref refs/new/koala/bear renamer &&
+
+ git checkout --track origin/koala/bear &&
+ test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+ git checkout master && git branch -D koala/bear &&
+
+ git checkout --track refs/remotes/origin/koala/bear &&
+ test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+ git checkout master && git branch -D koala/bear &&
+
+ git checkout --track remotes/origin/koala/bear &&
+ test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" &&
+
+ git checkout master && git branch -D koala/bear &&
+
+ git checkout --track refs/new/koala/bear &&
+ test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" &&
+ test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)"
+'
+
+test_expect_success \
+ 'checkout with --track, but without -b, fails with too short tracked name' '
+ test_must_fail git checkout --track renamer'
+
+setup_conflicting_index () {
+ rm -f .git/index &&
+ O=$(echo original | git hash-object -w --stdin) &&
+ A=$(echo ourside | git hash-object -w --stdin) &&
+ B=$(echo theirside | git hash-object -w --stdin) &&
+ (
+ echo "100644 $A 0 fild" &&
+ echo "100644 $O 1 file" &&
+ echo "100644 $A 2 file" &&
+ echo "100644 $B 3 file" &&
+ echo "100644 $A 0 filf"
+ ) | git update-index --index-info
+}
+
+test_expect_success 'checkout an unmerged path should fail' '
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ test_must_fail git checkout fild file filf &&
+ test_cmp sample fild &&
+ test_cmp sample filf &&
+ test_cmp sample file
+'
+
+test_expect_success 'checkout with an unmerged path can be ignored' '
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout -f fild file filf &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp sample file
+'
+
+test_expect_success 'checkout unmerged stage' '
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout --ours . &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp expect file &&
+ git checkout --theirs file &&
+ test ztheirside = "z$(cat file)"
+'
+
+test_expect_success 'checkout with --merge' '
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout -m -- fild file filf &&
+ (
+ echo "<<<<<<< ours"
+ echo ourside
+ echo "======="
+ echo theirside
+ echo ">>>>>>> theirs"
+ ) >merged &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp merged file
+'
+
+test_expect_success 'checkout with --merge, in diff3 -m style' '
+ git config merge.conflictstyle diff3 &&
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout -m -- fild file filf &&
+ (
+ echo "<<<<<<< ours"
+ echo ourside
+ echo "|||||||"
+ echo original
+ echo "======="
+ echo theirside
+ echo ">>>>>>> theirs"
+ ) >merged &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp merged file
+'
+
+test_expect_success 'checkout --conflict=merge, overriding config' '
+ git config merge.conflictstyle diff3 &&
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout --conflict=merge -- fild file filf &&
+ (
+ echo "<<<<<<< ours"
+ echo ourside
+ echo "======="
+ echo theirside
+ echo ">>>>>>> theirs"
+ ) >merged &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp merged file
+'
+
+test_expect_success 'checkout --conflict=diff3' '
+ git config --unset merge.conflictstyle
+ setup_conflicting_index &&
+ echo "none of the above" >sample &&
+ echo ourside >expect &&
+ cat sample >fild &&
+ cat sample >file &&
+ cat sample >filf &&
+ git checkout --conflict=diff3 -- fild file filf &&
+ (
+ echo "<<<<<<< ours"
+ echo ourside
+ echo "|||||||"
+ echo original
+ echo "======="
+ echo theirside
+ echo ">>>>>>> theirs"
+ ) >merged &&
+ test_cmp expect fild &&
+ test_cmp expect filf &&
+ test_cmp merged file
+'
+
+test_expect_success 'failing checkout -b should not break working tree' '
+ git reset --hard master &&
+ git symbolic-ref HEAD refs/heads/master &&
+ test_must_fail git checkout -b renamer side^ &&
+ test $(git symbolic-ref HEAD) = refs/heads/master &&
+ git diff --exit-code &&
+ git diff --cached --exit-code
+
+'
+
test_done