| 1 | #!/bin/sh |
| 2 | # |
| 3 | # Copyright (c) 2006 Josh England |
| 4 | # |
| 5 | |
| 6 | test_description='Test the post-checkout hook.' |
| 7 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 8 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 9 | |
| 10 | . ./test-lib.sh |
| 11 | |
| 12 | # Usage: check_post_checkout <file> <old-ref> <new-ref> <flag> |
| 13 | # |
| 14 | # Verify that the post-checkout hook arguments in <file> match the expected |
| 15 | # values: <old-ref> for the previous HEAD, <new-ref> for the new HEAD, and |
| 16 | # <flag> indicating whether this was a branch checkout (1) or file checkout (0). |
| 17 | check_post_checkout () { |
| 18 | test "$#" = 4 || BUG "check_post_checkout takes 4 args" |
| 19 | echo "old=$2 new=$3 flag=$4" >expect && |
| 20 | test_cmp expect "$1" |
| 21 | } |
| 22 | |
| 23 | test_expect_success setup ' |
| 24 | test_hook --setup post-checkout <<-\EOF && |
| 25 | echo "old=$1 new=$2 flag=$3" >.git/post-checkout.args |
| 26 | EOF |
| 27 | test_commit one && |
| 28 | test_commit two && |
| 29 | test_commit rebase-on-me && |
| 30 | git reset --hard HEAD^ && |
| 31 | test_commit three |
| 32 | ' |
| 33 | |
| 34 | test_expect_success 'post-checkout receives the right arguments with HEAD unchanged ' ' |
| 35 | test_when_finished "rm -f .git/post-checkout.args" && |
| 36 | git checkout main && |
| 37 | check_post_checkout .git/post-checkout.args \ |
| 38 | "$(git rev-parse HEAD)" "$(git rev-parse HEAD)" 1 |
| 39 | ' |
| 40 | |
| 41 | test_expect_success 'post-checkout args are correct with git checkout -b ' ' |
| 42 | test_when_finished "rm -f .git/post-checkout.args" && |
| 43 | git checkout -b new1 && |
| 44 | check_post_checkout .git/post-checkout.args \ |
| 45 | "$(git rev-parse HEAD)" "$(git rev-parse HEAD)" 1 |
| 46 | ' |
| 47 | |
| 48 | test_expect_success 'post-checkout receives the right args with HEAD changed ' ' |
| 49 | test_when_finished "rm -f .git/post-checkout.args" && |
| 50 | old=$(git rev-parse HEAD) && |
| 51 | git checkout two && |
| 52 | check_post_checkout .git/post-checkout.args \ |
| 53 | "$old" "$(git rev-parse HEAD)" 1 |
| 54 | ' |
| 55 | |
| 56 | test_expect_success 'post-checkout receives the right args when not switching branches ' ' |
| 57 | test_when_finished "rm -f .git/post-checkout.args" && |
| 58 | git checkout main -- three.t && |
| 59 | check_post_checkout .git/post-checkout.args \ |
| 60 | "$(git rev-parse HEAD)" "$(git rev-parse HEAD)" 0 |
| 61 | ' |
| 62 | |
| 63 | test_rebase () { |
| 64 | args="$*" && |
| 65 | test_expect_success "post-checkout is triggered on rebase $args" ' |
| 66 | test_when_finished "rm -f .git/post-checkout.args" && |
| 67 | git checkout -B rebase-test main && |
| 68 | rm -f .git/post-checkout.args && |
| 69 | git rebase $args rebase-on-me && |
| 70 | check_post_checkout .git/post-checkout.args \ |
| 71 | "$(git rev-parse main)" "$(git rev-parse rebase-on-me)" 1 |
| 72 | ' |
| 73 | |
| 74 | test_expect_success "post-checkout is triggered on rebase $args with fast-forward" ' |
| 75 | test_when_finished "rm -f .git/post-checkout.args" && |
| 76 | git checkout -B ff-rebase-test rebase-on-me^ && |
| 77 | rm -f .git/post-checkout.args && |
| 78 | git rebase $args rebase-on-me && |
| 79 | check_post_checkout .git/post-checkout.args \ |
| 80 | "$(git rev-parse rebase-on-me^)" "$(git rev-parse rebase-on-me)" 1 |
| 81 | ' |
| 82 | |
| 83 | test_expect_success "rebase $args fast-forward branch checkout runs post-checkout hook" ' |
| 84 | test_when_finished "test_might_fail git rebase --abort" && |
| 85 | test_when_finished "rm -f .git/post-checkout.args" && |
| 86 | git update-ref refs/heads/rebase-fast-forward three && |
| 87 | git checkout two && |
| 88 | rm -f .git/post-checkout.args && |
| 89 | git rebase $args HEAD rebase-fast-forward && |
| 90 | check_post_checkout .git/post-checkout.args \ |
| 91 | "$(git rev-parse two)" "$(git rev-parse three)" 1 |
| 92 | ' |
| 93 | |
| 94 | test_expect_success "rebase $args checkout does not remove untracked files" ' |
| 95 | test_when_finished "test_might_fail git rebase --abort" && |
| 96 | test_when_finished "rm -f .git/post-checkout.args" && |
| 97 | git update-ref refs/heads/rebase-fast-forward three && |
| 98 | git checkout two && |
| 99 | rm -f .git/post-checkout.args && |
| 100 | echo untracked >three.t && |
| 101 | test_when_finished "rm three.t" && |
| 102 | test_must_fail git rebase $args HEAD rebase-fast-forward 2>err && |
| 103 | grep "untracked working tree files would be overwritten by checkout" err && |
| 104 | test_path_is_missing .git/post-checkout.args |
| 105 | |
| 106 | ' |
| 107 | } |
| 108 | |
| 109 | test_rebase --apply && |
| 110 | test_rebase --merge |
| 111 | |
| 112 | test_expect_success 'post-checkout hook is triggered by clone' ' |
| 113 | mkdir -p templates/hooks && |
| 114 | write_script templates/hooks/post-checkout <<-\EOF && |
| 115 | echo "old=$1 new=$2 flag=$3" >"$GIT_DIR/post-checkout.args" |
| 116 | EOF |
| 117 | git clone --template=templates . clone3 && |
| 118 | check_post_checkout clone3/.git/post-checkout.args \ |
| 119 | "$(test_oid zero)" "$(git -C clone3 rev-parse HEAD)" 1 |
| 120 | ' |
| 121 | |
| 122 | test_done |