]>
Commit | Line | Data |
---|---|---|
ad35ecab SB |
1 | #!/bin/sh |
2 | ||
3 | test_description='pushing to a repository using the atomic push option' | |
4 | ||
028cb644 | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
ad35ecab SB |
8 | . ./test-lib.sh |
9 | ||
10 | mk_repo_pair () { | |
11 | rm -rf workbench upstream && | |
12 | test_create_repo upstream && | |
13 | test_create_repo workbench && | |
14 | ( | |
15 | cd upstream && | |
16 | git config receive.denyCurrentBranch warn | |
17 | ) && | |
18 | ( | |
19 | cd workbench && | |
20 | git remote add up ../upstream | |
21 | ) | |
22 | } | |
23 | ||
24 | # Compare the ref ($1) in upstream with a ref value from workbench ($2) | |
25 | # i.e. test_refs second HEAD@{2} | |
26 | test_refs () { | |
27 | test $# = 2 && | |
28 | git -C upstream rev-parse --verify "$1" >expect && | |
29 | git -C workbench rev-parse --verify "$2" >actual && | |
30 | test_cmp expect actual | |
31 | } | |
32 | ||
865e23f5 JX |
33 | fmt_status_report () { |
34 | sed -n \ | |
35 | -e "/^To / { s/ */ /g; p; }" \ | |
36 | -e "/^ ! / { s/ */ /g; p; }" | |
37 | } | |
38 | ||
ad35ecab SB |
39 | test_expect_success 'atomic push works for a single branch' ' |
40 | mk_repo_pair && | |
41 | ( | |
42 | cd workbench && | |
43 | test_commit one && | |
44 | git push --mirror up && | |
45 | test_commit two && | |
028cb644 | 46 | git push --atomic up main |
ad35ecab | 47 | ) && |
028cb644 | 48 | test_refs main main |
ad35ecab SB |
49 | ' |
50 | ||
51 | test_expect_success 'atomic push works for two branches' ' | |
52 | mk_repo_pair && | |
53 | ( | |
54 | cd workbench && | |
55 | test_commit one && | |
56 | git branch second && | |
57 | git push --mirror up && | |
58 | test_commit two && | |
59 | git checkout second && | |
60 | test_commit three && | |
028cb644 | 61 | git push --atomic up main second |
ad35ecab | 62 | ) && |
028cb644 | 63 | test_refs main main && |
ad35ecab SB |
64 | test_refs second second |
65 | ' | |
66 | ||
67 | test_expect_success 'atomic push works in combination with --mirror' ' | |
68 | mk_repo_pair && | |
69 | ( | |
70 | cd workbench && | |
71 | test_commit one && | |
72 | git checkout -b second && | |
73 | test_commit two && | |
74 | git push --atomic --mirror up | |
75 | ) && | |
028cb644 | 76 | test_refs main main && |
ad35ecab SB |
77 | test_refs second second |
78 | ' | |
79 | ||
80 | test_expect_success 'atomic push works in combination with --force' ' | |
81 | mk_repo_pair && | |
82 | ( | |
83 | cd workbench && | |
84 | test_commit one && | |
028cb644 | 85 | git branch second main && |
ad35ecab SB |
86 | test_commit two_a && |
87 | git checkout second && | |
88 | test_commit two_b && | |
89 | test_commit three_b && | |
90 | test_commit four && | |
91 | git push --mirror up && | |
92 | # The actual test is below | |
028cb644 | 93 | git checkout main && |
ad35ecab SB |
94 | test_commit three_a && |
95 | git checkout second && | |
96 | git reset --hard HEAD^ && | |
028cb644 | 97 | git push --force --atomic up main second |
ad35ecab | 98 | ) && |
028cb644 | 99 | test_refs main main && |
ad35ecab SB |
100 | test_refs second second |
101 | ' | |
102 | ||
028cb644 | 103 | # set up two branches where main can be pushed but second can not |
ad35ecab | 104 | # (non-fast-forward). Since second can not be pushed the whole operation |
028cb644 | 105 | # will fail and leave main untouched. |
ad35ecab SB |
106 | test_expect_success 'atomic push fails if one branch fails' ' |
107 | mk_repo_pair && | |
108 | ( | |
109 | cd workbench && | |
110 | test_commit one && | |
028cb644 | 111 | git checkout -b second main && |
ad35ecab SB |
112 | test_commit two && |
113 | test_commit three && | |
114 | test_commit four && | |
115 | git push --mirror up && | |
116 | git reset --hard HEAD~2 && | |
117 | test_commit five && | |
028cb644 | 118 | git checkout main && |
ad35ecab | 119 | test_commit six && |
425b4d7f TL |
120 | test_must_fail git push --atomic --all up >output-all 2>&1 && |
121 | # --all and --branches have the same behavior when be combined with --atomic | |
122 | test_must_fail git push --atomic --branches up >output-branches 2>&1 && | |
123 | test_cmp output-all output-branches | |
ad35ecab | 124 | ) && |
028cb644 | 125 | test_refs main HEAD@{7} && |
ad35ecab SB |
126 | test_refs second HEAD@{4} |
127 | ' | |
128 | ||
129 | test_expect_success 'atomic push fails if one tag fails remotely' ' | |
130 | # prepare the repo | |
131 | mk_repo_pair && | |
132 | ( | |
133 | cd workbench && | |
134 | test_commit one && | |
028cb644 | 135 | git checkout -b second main && |
ad35ecab SB |
136 | test_commit two && |
137 | git push --mirror up | |
138 | ) && | |
139 | # a third party modifies the server side: | |
140 | ( | |
141 | cd upstream && | |
142 | git checkout second && | |
143 | git tag test_tag second | |
144 | ) && | |
145 | # see if we can now push both branches. | |
146 | ( | |
147 | cd workbench && | |
028cb644 | 148 | git checkout main && |
ad35ecab SB |
149 | test_commit three && |
150 | git checkout second && | |
151 | test_commit four && | |
152 | git tag test_tag && | |
028cb644 | 153 | test_must_fail git push --tags --atomic up main second |
ad35ecab | 154 | ) && |
028cb644 | 155 | test_refs main HEAD@{3} && |
ad35ecab SB |
156 | test_refs second HEAD@{1} |
157 | ' | |
158 | ||
159 | test_expect_success 'atomic push obeys update hook preventing a branch to be pushed' ' | |
160 | mk_repo_pair && | |
161 | ( | |
162 | cd workbench && | |
163 | test_commit one && | |
028cb644 | 164 | git checkout -b second main && |
ad35ecab SB |
165 | test_commit two && |
166 | git push --mirror up | |
167 | ) && | |
66865d12 ÆAB |
168 | test_hook -C upstream update <<-\EOF && |
169 | # only allow update to main from now on | |
170 | test "$1" = "refs/heads/main" | |
171 | EOF | |
ad35ecab SB |
172 | ( |
173 | cd workbench && | |
028cb644 | 174 | git checkout main && |
ad35ecab SB |
175 | test_commit three && |
176 | git checkout second && | |
177 | test_commit four && | |
028cb644 | 178 | test_must_fail git push --atomic up main second |
ad35ecab | 179 | ) && |
028cb644 | 180 | test_refs main HEAD@{3} && |
ad35ecab SB |
181 | test_refs second HEAD@{1} |
182 | ' | |
183 | ||
184 | test_expect_success 'atomic push is not advertised if configured' ' | |
185 | mk_repo_pair && | |
186 | ( | |
51b85471 | 187 | cd upstream && |
ad35ecab SB |
188 | git config receive.advertiseatomic 0 |
189 | ) && | |
190 | ( | |
191 | cd workbench && | |
192 | test_commit one && | |
193 | git push --mirror up && | |
194 | test_commit two && | |
028cb644 | 195 | test_must_fail git push --atomic up main |
ad35ecab | 196 | ) && |
028cb644 | 197 | test_refs main HEAD@{1} |
ad35ecab SB |
198 | ' |
199 | ||
028cb644 JS |
200 | # References in upstream : main(1) one(1) foo(1) |
201 | # References in workbench: main(2) foo(1) two(2) bar(2) | |
202 | # Atomic push : main(2) two(2) bar(2) | |
46701bde | 203 | test_expect_success 'atomic push reports (reject by update hook)' ' |
865e23f5 JX |
204 | mk_repo_pair && |
205 | ( | |
206 | cd workbench && | |
207 | test_commit one && | |
208 | git branch foo && | |
028cb644 | 209 | git push up main one foo && |
865e23f5 JX |
210 | git tag -d one |
211 | ) && | |
212 | ( | |
213 | mkdir -p upstream/.git/hooks && | |
214 | cat >upstream/.git/hooks/update <<-EOF && | |
215 | #!/bin/sh | |
216 | ||
217 | if test "\$1" = "refs/heads/bar" | |
218 | then | |
219 | echo >&2 "Pusing to branch bar is prohibited" | |
220 | exit 1 | |
221 | fi | |
222 | EOF | |
223 | chmod a+x upstream/.git/hooks/update | |
224 | ) && | |
225 | ( | |
226 | cd workbench && | |
227 | test_commit two && | |
228 | git branch bar | |
229 | ) && | |
230 | test_must_fail git -C workbench \ | |
028cb644 | 231 | push --atomic up main two bar >out 2>&1 && |
865e23f5 JX |
232 | fmt_status_report <out >actual && |
233 | cat >expect <<-EOF && | |
234 | To ../upstream | |
028cb644 | 235 | ! [remote rejected] main -> main (atomic push failure) |
865e23f5 JX |
236 | ! [remote rejected] two -> two (atomic push failure) |
237 | ! [remote rejected] bar -> bar (hook declined) | |
238 | EOF | |
239 | test_cmp expect actual | |
240 | ' | |
241 | ||
028cb644 JS |
242 | # References in upstream : main(1) one(1) foo(1) |
243 | # References in workbench: main(2) foo(1) two(2) bar(2) | |
46701bde | 244 | test_expect_success 'atomic push reports (mirror, but reject by update hook)' ' |
865e23f5 JX |
245 | ( |
246 | cd workbench && | |
247 | git remote remove up && | |
248 | git remote add up ../upstream | |
249 | ) && | |
250 | test_must_fail git -C workbench \ | |
251 | push --atomic --mirror up >out 2>&1 && | |
252 | fmt_status_report <out >actual && | |
253 | cat >expect <<-EOF && | |
254 | To ../upstream | |
028cb644 | 255 | ! [remote rejected] main -> main (atomic push failure) |
865e23f5 JX |
256 | ! [remote rejected] one (atomic push failure) |
257 | ! [remote rejected] bar -> bar (hook declined) | |
258 | ! [remote rejected] two -> two (atomic push failure) | |
259 | EOF | |
260 | test_cmp expect actual | |
261 | ' | |
262 | ||
028cb644 JS |
263 | # References in upstream : main(2) one(1) foo(1) |
264 | # References in workbench: main(1) foo(1) two(2) bar(2) | |
46701bde | 265 | test_expect_success 'atomic push reports (reject by non-ff)' ' |
865e23f5 JX |
266 | rm upstream/.git/hooks/update && |
267 | ( | |
268 | cd workbench && | |
028cb644 | 269 | git push up main && |
865e23f5 JX |
270 | git reset --hard HEAD^ |
271 | ) && | |
272 | test_must_fail git -C workbench \ | |
028cb644 | 273 | push --atomic up main foo bar >out 2>&1 && |
865e23f5 JX |
274 | fmt_status_report <out >actual && |
275 | cat >expect <<-EOF && | |
276 | To ../upstream | |
028cb644 | 277 | ! [rejected] main -> main (non-fast-forward) |
865e23f5 JX |
278 | ! [rejected] bar -> bar (atomic push failed) |
279 | EOF | |
280 | test_cmp expect actual | |
281 | ' | |
282 | ||
ad35ecab | 283 | test_done |