]> git.ipfire.org Git - thirdparty/git.git/blame - t/t5548-push-porcelain.sh
The sixth batch
[thirdparty/git.git] / t / t5548-push-porcelain.sh
CommitLineData
7dcbeaa0
JX
1#!/bin/sh
2#
3# Copyright (c) 2020 Jiang Xin
4#
5test_description='Test git push porcelain output'
6
7. ./test-lib.sh
8
9# Create commits in <repo> and assign each commit's oid to shell variables
10# given in the arguments (A, B, and C). E.g.:
11#
12# create_commits_in <repo> A B C
13#
14# NOTE: Never calling this function from a subshell since variable
15# assignments will disappear when subshell exits.
16create_commits_in () {
17 repo="$1" &&
18 if ! parent=$(git -C "$repo" rev-parse HEAD^{} --)
19 then
20 parent=
21 fi &&
22 T=$(git -C "$repo" write-tree) &&
23 shift &&
24 while test $# -gt 0
25 do
26 name=$1 &&
27 test_tick &&
28 if test -z "$parent"
29 then
30 oid=$(echo $name | git -C "$repo" commit-tree $T)
31 else
32 oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
33 fi &&
34 eval $name=$oid &&
35 parent=$oid &&
36 shift ||
37 return 1
38 done &&
39 git -C "$repo" update-ref refs/heads/master $oid
40}
41
42# Format the output of git-push, git-show-ref and other commands to make a
43# user-friendly and stable text. We can easily prepare the expect text
44# without having to worry about future changes of the commit ID and spaces
45# of the output.
46make_user_friendly_and_stable_output () {
47 sed \
48 -e "s/ *\$//" \
49 -e "s/ */ /g" \
50 -e "s/ / /g" \
51 -e "s/$A/<COMMIT-A>/g" \
52 -e "s/$B/<COMMIT-B>/g" \
53 -e "s/$ZERO_OID/<ZERO-OID>/g" \
54 -e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \
55 -e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \
56 -e "s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#"
57}
58
59setup_upstream_and_workbench () {
60 # Upstream after setup : master(B) foo(A) bar(A) baz(A)
61 # Workbench after setup : master(A)
62 test_expect_success "setup upstream repository and workbench" '
63 rm -rf upstream.git workbench &&
64 git init --bare upstream.git &&
65 git init workbench &&
66 create_commits_in workbench A B &&
67 (
68 cd workbench &&
69 # Try to make a stable fixed width for abbreviated commit ID,
70 # this fixed-width oid will be replaced with "<OID>".
71 git config core.abbrev 7 &&
72 git remote add origin ../upstream.git &&
73 git update-ref refs/heads/master $A &&
74 git push origin \
75 $B:refs/heads/master \
76 $A:refs/heads/foo \
77 $A:refs/heads/bar \
78 $A:refs/heads/baz
79 ) &&
80 git -C "workbench" config advice.pushUpdateRejected false &&
81 upstream=upstream.git
82 '
83}
84
85run_git_push_porcelain_output_test() {
86 case $1 in
87 http)
88 PROTOCOL="HTTP protocol"
89 URL_PREFIX="http://.*"
90 ;;
91 file)
92 PROTOCOL="builtin protocol"
93 URL_PREFIX="\.\."
94 ;;
95 esac
96
97 # Refs of upstream : master(B) foo(A) bar(A) baz(A)
98 # Refs of workbench: master(A) baz(A) next(A)
99 # git-push : master(A) NULL (B) baz(A) next(A)
100 test_expect_success "porcelain output of successful git-push ($PROTOCOL)" '
101 (
102 cd workbench &&
103 git update-ref refs/heads/master $A &&
104 git update-ref refs/heads/baz $A &&
105 git update-ref refs/heads/next $A &&
106 git push --porcelain --force origin \
107 master \
108 :refs/heads/foo \
109 $B:bar \
110 baz \
111 next
112 ) >out &&
113 make_user_friendly_and_stable_output <out >actual &&
114 cat >expect <<-EOF &&
115 To <URL/of/upstream.git>
116 = refs/heads/baz:refs/heads/baz [up to date]
117 <COMMIT-B>:refs/heads/bar <OID-A>..<OID-B>
118 - :refs/heads/foo [deleted]
119 + refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update)
120 * refs/heads/next:refs/heads/next [new branch]
121 Done
122 EOF
123 test_cmp expect actual &&
124
125 git -C "$upstream" show-ref >out &&
126 make_user_friendly_and_stable_output <out >actual &&
127 cat >expect <<-EOF &&
128 <COMMIT-B> refs/heads/bar
129 <COMMIT-A> refs/heads/baz
130 <COMMIT-A> refs/heads/master
131 <COMMIT-A> refs/heads/next
132 EOF
133 test_cmp expect actual
134 '
135
136 # Refs of upstream : master(A) bar(B) baz(A) next(A)
137 # Refs of workbench: master(B) bar(A) baz(A) next(A)
138 # git-push : master(B) bar(A) NULL next(A)
f38b1684 139 test_expect_success "atomic push failed ($PROTOCOL)" '
7dcbeaa0
JX
140 (
141 cd workbench &&
142 git update-ref refs/heads/master $B &&
143 git update-ref refs/heads/bar $A &&
144 test_must_fail git push --atomic --porcelain origin \
145 master \
146 bar \
147 :baz \
148 next
149 ) >out &&
150 make_user_friendly_and_stable_output <out >actual &&
151 cat >expect <<-EOF &&
152 To <URL/of/upstream.git>
f38b1684 153 = refs/heads/next:refs/heads/next [up to date]
7dcbeaa0
JX
154 ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward)
155 ! (delete):refs/heads/baz [rejected] (atomic push failed)
156 ! refs/heads/master:refs/heads/master [rejected] (atomic push failed)
7dcbeaa0
JX
157 Done
158 EOF
159 test_cmp expect actual &&
160
161 git -C "$upstream" show-ref >out &&
162 make_user_friendly_and_stable_output <out >actual &&
163 cat >expect <<-EOF &&
164 <COMMIT-B> refs/heads/bar
165 <COMMIT-A> refs/heads/baz
166 <COMMIT-A> refs/heads/master
167 <COMMIT-A> refs/heads/next
168 EOF
169 test_cmp expect actual
170 '
7dcbeaa0
JX
171 test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
172 write_script "$upstream/hooks/pre-receive" <<-EOF
173 exit 1
174 EOF
175 '
176
177 # Refs of upstream : master(A) bar(B) baz(A) next(A)
178 # Refs of workbench: master(B) bar(A) baz(A) next(A)
179 # git-push : master(B) bar(A) NULL next(A)
180 test_expect_success "pre-receive hook declined ($PROTOCOL)" '
181 (
182 cd workbench &&
183 git update-ref refs/heads/master $B &&
184 git update-ref refs/heads/bar $A &&
185 test_must_fail git push --porcelain --force origin \
186 master \
187 bar \
188 :baz \
189 next
190 ) >out &&
191 make_user_friendly_and_stable_output <out >actual &&
192 cat >expect <<-EOF &&
193 To <URL/of/upstream.git>
194 = refs/heads/next:refs/heads/next [up to date]
195 ! refs/heads/bar:refs/heads/bar [remote rejected] (pre-receive hook declined)
196 ! :refs/heads/baz [remote rejected] (pre-receive hook declined)
197 ! refs/heads/master:refs/heads/master [remote rejected] (pre-receive hook declined)
198 Done
199 EOF
200 test_cmp expect actual &&
201
202 git -C "$upstream" show-ref >out &&
203 make_user_friendly_and_stable_output <out >actual &&
204 cat >expect <<-EOF &&
205 <COMMIT-B> refs/heads/bar
206 <COMMIT-A> refs/heads/baz
207 <COMMIT-A> refs/heads/master
208 <COMMIT-A> refs/heads/next
209 EOF
210 test_cmp expect actual
211 '
212
213 test_expect_success "remove pre-receive hook ($PROTOCOL)" '
214 rm "$upstream/hooks/pre-receive"
215 '
216
217 # Refs of upstream : master(A) bar(B) baz(A) next(A)
218 # Refs of workbench: master(B) bar(A) baz(A) next(A)
219 # git-push : master(B) bar(A) NULL next(A)
220 test_expect_success "non-fastforward push ($PROTOCOL)" '
221 (
222 cd workbench &&
223 test_must_fail git push --porcelain origin \
224 master \
225 bar \
226 :baz \
227 next
228 ) >out &&
229 make_user_friendly_and_stable_output <out >actual &&
230 cat >expect <<-EOF &&
231 To <URL/of/upstream.git>
232 = refs/heads/next:refs/heads/next [up to date]
233 - :refs/heads/baz [deleted]
234 refs/heads/master:refs/heads/master <OID-A>..<OID-B>
235 ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward)
236 Done
237 EOF
238 test_cmp expect actual &&
239
240 git -C "$upstream" show-ref >out &&
241 make_user_friendly_and_stable_output <out >actual &&
242 cat >expect <<-EOF &&
243 <COMMIT-B> refs/heads/bar
244 <COMMIT-B> refs/heads/master
245 <COMMIT-A> refs/heads/next
246 EOF
247 test_cmp expect actual
248 '
249}
250
251# Initialize the upstream repository and local workbench.
252setup_upstream_and_workbench
253
254# Run git-push porcelain test on builtin protocol
255run_git_push_porcelain_output_test file
256
257ROOT_PATH="$PWD"
258. "$TEST_DIRECTORY"/lib-gpg.sh
259. "$TEST_DIRECTORY"/lib-httpd.sh
260. "$TEST_DIRECTORY"/lib-terminal.sh
261start_httpd
262
263# Re-initialize the upstream repository and local workbench.
264setup_upstream_and_workbench
265
266test_expect_success "setup for http" '
267 git -C upstream.git config http.receivepack true &&
268 upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" &&
269 mv upstream.git "$upstream" &&
270
271 git -C workbench remote set-url origin $HTTPD_URL/smart/upstream.git
272'
273
274setup_askpass_helper
275
276# Run git-push porcelain test on HTTP protocol
277run_git_push_porcelain_output_test http
278
279test_done