Raw
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