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