]>
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 SB |
119 | test_commit six && |
120 | test_must_fail git push --atomic --all up | |
121 | ) && | |
028cb644 | 122 | test_refs main HEAD@{7} && |
ad35ecab SB |
123 | test_refs second HEAD@{4} |
124 | ' | |
125 | ||
126 | test_expect_success 'atomic push fails if one tag fails remotely' ' | |
127 | # prepare the repo | |
128 | mk_repo_pair && | |
129 | ( | |
130 | cd workbench && | |
131 | test_commit one && | |
028cb644 | 132 | git checkout -b second main && |
ad35ecab SB |
133 | test_commit two && |
134 | git push --mirror up | |
135 | ) && | |
136 | # a third party modifies the server side: | |
137 | ( | |
138 | cd upstream && | |
139 | git checkout second && | |
140 | git tag test_tag second | |
141 | ) && | |
142 | # see if we can now push both branches. | |
143 | ( | |
144 | cd workbench && | |
028cb644 | 145 | git checkout main && |
ad35ecab SB |
146 | test_commit three && |
147 | git checkout second && | |
148 | test_commit four && | |
149 | git tag test_tag && | |
028cb644 | 150 | test_must_fail git push --tags --atomic up main second |
ad35ecab | 151 | ) && |
028cb644 | 152 | test_refs main HEAD@{3} && |
ad35ecab SB |
153 | test_refs second HEAD@{1} |
154 | ' | |
155 | ||
156 | test_expect_success 'atomic push obeys update hook preventing a branch to be pushed' ' | |
157 | mk_repo_pair && | |
158 | ( | |
159 | cd workbench && | |
160 | test_commit one && | |
028cb644 | 161 | git checkout -b second main && |
ad35ecab SB |
162 | test_commit two && |
163 | git push --mirror up | |
164 | ) && | |
165 | ( | |
166 | cd upstream && | |
167 | HOOKDIR="$(git rev-parse --git-dir)/hooks" && | |
168 | HOOK="$HOOKDIR/update" && | |
169 | mkdir -p "$HOOKDIR" && | |
170 | write_script "$HOOK" <<-\EOF | |
028cb644 JS |
171 | # only allow update to main from now on |
172 | test "$1" = "refs/heads/main" | |
ad35ecab SB |
173 | EOF |
174 | ) && | |
175 | ( | |
176 | cd workbench && | |
028cb644 | 177 | git checkout main && |
ad35ecab SB |
178 | test_commit three && |
179 | git checkout second && | |
180 | test_commit four && | |
028cb644 | 181 | test_must_fail git push --atomic up main second |
ad35ecab | 182 | ) && |
028cb644 | 183 | test_refs main HEAD@{3} && |
ad35ecab SB |
184 | test_refs second HEAD@{1} |
185 | ' | |
186 | ||
187 | test_expect_success 'atomic push is not advertised if configured' ' | |
188 | mk_repo_pair && | |
189 | ( | |
51b85471 | 190 | cd upstream && |
ad35ecab SB |
191 | git config receive.advertiseatomic 0 |
192 | ) && | |
193 | ( | |
194 | cd workbench && | |
195 | test_commit one && | |
196 | git push --mirror up && | |
197 | test_commit two && | |
028cb644 | 198 | test_must_fail git push --atomic up main |
ad35ecab | 199 | ) && |
028cb644 | 200 | test_refs main HEAD@{1} |
ad35ecab SB |
201 | ' |
202 | ||
028cb644 JS |
203 | # References in upstream : main(1) one(1) foo(1) |
204 | # References in workbench: main(2) foo(1) two(2) bar(2) | |
205 | # Atomic push : main(2) two(2) bar(2) | |
46701bde | 206 | test_expect_success 'atomic push reports (reject by update hook)' ' |
865e23f5 JX |
207 | mk_repo_pair && |
208 | ( | |
209 | cd workbench && | |
210 | test_commit one && | |
211 | git branch foo && | |
028cb644 | 212 | git push up main one foo && |
865e23f5 JX |
213 | git tag -d one |
214 | ) && | |
215 | ( | |
216 | mkdir -p upstream/.git/hooks && | |
217 | cat >upstream/.git/hooks/update <<-EOF && | |
218 | #!/bin/sh | |
219 | ||
220 | if test "\$1" = "refs/heads/bar" | |
221 | then | |
222 | echo >&2 "Pusing to branch bar is prohibited" | |
223 | exit 1 | |
224 | fi | |
225 | EOF | |
226 | chmod a+x upstream/.git/hooks/update | |
227 | ) && | |
228 | ( | |
229 | cd workbench && | |
230 | test_commit two && | |
231 | git branch bar | |
232 | ) && | |
233 | test_must_fail git -C workbench \ | |
028cb644 | 234 | push --atomic up main two bar >out 2>&1 && |
865e23f5 JX |
235 | fmt_status_report <out >actual && |
236 | cat >expect <<-EOF && | |
237 | To ../upstream | |
028cb644 | 238 | ! [remote rejected] main -> main (atomic push failure) |
865e23f5 JX |
239 | ! [remote rejected] two -> two (atomic push failure) |
240 | ! [remote rejected] bar -> bar (hook declined) | |
241 | EOF | |
242 | test_cmp expect actual | |
243 | ' | |
244 | ||
028cb644 JS |
245 | # References in upstream : main(1) one(1) foo(1) |
246 | # References in workbench: main(2) foo(1) two(2) bar(2) | |
46701bde | 247 | test_expect_success 'atomic push reports (mirror, but reject by update hook)' ' |
865e23f5 JX |
248 | ( |
249 | cd workbench && | |
250 | git remote remove up && | |
251 | git remote add up ../upstream | |
252 | ) && | |
253 | test_must_fail git -C workbench \ | |
254 | push --atomic --mirror up >out 2>&1 && | |
255 | fmt_status_report <out >actual && | |
256 | cat >expect <<-EOF && | |
257 | To ../upstream | |
028cb644 | 258 | ! [remote rejected] main -> main (atomic push failure) |
865e23f5 JX |
259 | ! [remote rejected] one (atomic push failure) |
260 | ! [remote rejected] bar -> bar (hook declined) | |
261 | ! [remote rejected] two -> two (atomic push failure) | |
262 | EOF | |
263 | test_cmp expect actual | |
264 | ' | |
265 | ||
028cb644 JS |
266 | # References in upstream : main(2) one(1) foo(1) |
267 | # References in workbench: main(1) foo(1) two(2) bar(2) | |
46701bde | 268 | test_expect_success 'atomic push reports (reject by non-ff)' ' |
865e23f5 JX |
269 | rm upstream/.git/hooks/update && |
270 | ( | |
271 | cd workbench && | |
028cb644 | 272 | git push up main && |
865e23f5 JX |
273 | git reset --hard HEAD^ |
274 | ) && | |
275 | test_must_fail git -C workbench \ | |
028cb644 | 276 | push --atomic up main foo bar >out 2>&1 && |
865e23f5 JX |
277 | fmt_status_report <out >actual && |
278 | cat >expect <<-EOF && | |
279 | To ../upstream | |
028cb644 | 280 | ! [rejected] main -> main (non-fast-forward) |
865e23f5 JX |
281 | ! [rejected] bar -> bar (atomic push failed) |
282 | EOF | |
283 | test_cmp expect actual | |
284 | ' | |
285 | ||
ad35ecab | 286 | test_done |