send-pack: support push negotiation
[git] / t / t5571-pre-push-hook.sh
1 #!/bin/sh
2
3 test_description='check pre-push hooks'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8
9 # Setup hook that always succeeds
10 HOOKDIR="$(git rev-parse --git-dir)/hooks"
11 HOOK="$HOOKDIR/pre-push"
12 mkdir -p "$HOOKDIR"
13 write_script "$HOOK" <<EOF
14 cat >/dev/null
15 exit 0
16 EOF
17
18 test_expect_success 'setup' '
19         git config push.default upstream &&
20         git init --bare repo1 &&
21         git remote add parent1 repo1 &&
22         test_commit one &&
23         git push parent1 HEAD:foreign
24 '
25 write_script "$HOOK" <<EOF
26 cat >/dev/null
27 exit 1
28 EOF
29
30 COMMIT1="$(git rev-parse HEAD)"
31 export COMMIT1
32
33 test_expect_success 'push with failing hook' '
34         test_commit two &&
35         test_must_fail git push parent1 HEAD
36 '
37
38 test_expect_success '--no-verify bypasses hook' '
39         git push --no-verify parent1 HEAD
40 '
41
42 COMMIT2="$(git rev-parse HEAD)"
43 export COMMIT2
44
45 write_script "$HOOK" <<'EOF'
46 echo "$1" >actual
47 echo "$2" >>actual
48 cat >>actual
49 EOF
50
51 cat >expected <<EOF
52 parent1
53 repo1
54 refs/heads/main $COMMIT2 refs/heads/foreign $COMMIT1
55 EOF
56
57 test_expect_success 'push with hook' '
58         git push parent1 main:foreign &&
59         diff expected actual
60 '
61
62 test_expect_success 'add a branch' '
63         git checkout -b other parent1/foreign &&
64         test_commit three
65 '
66
67 COMMIT3="$(git rev-parse HEAD)"
68 export COMMIT3
69
70 cat >expected <<EOF
71 parent1
72 repo1
73 refs/heads/other $COMMIT3 refs/heads/foreign $COMMIT2
74 EOF
75
76 test_expect_success 'push to default' '
77         git push &&
78         diff expected actual
79 '
80
81 cat >expected <<EOF
82 parent1
83 repo1
84 refs/tags/one $COMMIT1 refs/tags/tag1 $ZERO_OID
85 HEAD~ $COMMIT2 refs/heads/prev $ZERO_OID
86 EOF
87
88 test_expect_success 'push non-branches' '
89         git push parent1 one:tag1 HEAD~:refs/heads/prev &&
90         diff expected actual
91 '
92
93 cat >expected <<EOF
94 parent1
95 repo1
96 (delete) $ZERO_OID refs/heads/prev $COMMIT2
97 EOF
98
99 test_expect_success 'push delete' '
100         git push parent1 :prev &&
101         diff expected actual
102 '
103
104 cat >expected <<EOF
105 repo1
106 repo1
107 HEAD $COMMIT3 refs/heads/other $ZERO_OID
108 EOF
109
110 test_expect_success 'push to URL' '
111         git push repo1 HEAD &&
112         diff expected actual
113 '
114
115 test_expect_success 'set up many-ref tests' '
116         {
117                 nr=1000
118                 while test $nr -lt 2000
119                 do
120                         nr=$(( $nr + 1 ))
121                         echo "create refs/heads/b/$nr $COMMIT3"
122                 done
123         } | git update-ref --stdin
124 '
125
126 test_expect_success 'sigpipe does not cause pre-push hook failure' '
127         echo "exit 0" | write_script "$HOOK" &&
128         git push parent1 "refs/heads/b/*:refs/heads/b/*"
129 '
130
131 test_done