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