160
test_cmp expect actual
161
'
162
163
+test_expect_success 'atomic fetch with failing backfill' '
164
+ git init clone3 &&
165
+
166
+ # We want to test whether a failure when backfilling tags correctly
167
+ # aborts the complete transaction when `--atomic` is passed: we should
168
+ # neither create the branch nor should we create the tag when either
169
+ # one of both fails to update correctly.
170
+ #
171
+ # To trigger failure we simply abort when backfilling a tag.
172
+ write_script clone3/.git/hooks/reference-transaction <<-\EOF &&
173
+ while read oldrev newrev reference
174
+ do
175
+ if test "$reference" = refs/tags/tag1
176
+ then
177
+ exit 1
178
+ fi
179
+ done
180
+ EOF
181
+
182
+ test_must_fail git -C clone3 fetch --atomic .. $B:refs/heads/something &&
183
+
184
+ # Creation of the tag has failed, so ideally refs/heads/something
185
+ # should not exist. The fact that it does demonstrates that there is
186
+ # a bug in the `--atomic` flag.
187
+ test $B = "$(git -C clone3 rev-parse --verify refs/heads/something)"
188
+'
189
+
190
+test_expect_success 'atomic fetch with backfill should use single transaction' '
191
+ git init clone4 &&
192
+
193
+ # Fetching with the `--atomic` flag should update all references in a
194
+ # single transaction, including backfilled tags. We thus expect to see
195
+ # a single reference transaction for the created branch and tags.
196
+ cat >expected <<-EOF &&
197
+ prepared
198
+ $ZERO_OID $B refs/heads/something
199
+ $ZERO_OID $S refs/tags/tag2
200
+ committed
201
+ $ZERO_OID $B refs/heads/something
202
+ $ZERO_OID $S refs/tags/tag2
203
+ prepared
204
+ $ZERO_OID $T refs/tags/tag1
205
+ committed
206
+ $ZERO_OID $T refs/tags/tag1
207
+ EOF
208
+
209
+ write_script clone4/.git/hooks/reference-transaction <<-\EOF &&
210
+ ( echo "$*" && cat ) >>actual
211
+ EOF
212
+
213
+ git -C clone4 fetch --atomic .. $B:refs/heads/something &&
214
+ test_cmp expected clone4/actual
215
+'
216
+
217
+test_expect_success 'backfill failure causes command to fail' '
218
+ git init clone5 &&
219
+
220
+ write_script clone5/.git/hooks/reference-transaction <<-EOF &&
221
+ while read oldrev newrev reference
222
+ do
223
+ if test "\$reference" = refs/tags/tag1
224
+ then
225
+ # Create a nested tag below the actual tag we
226
+ # wanted to write, which causes a D/F conflict
227
+ # later when we want to commit refs/tags/tag1.
228
+ # We cannot just `exit 1` here given that this
229
+ # would cause us to die immediately.
230
+ git update-ref refs/tags/tag1/nested $B
231
+ exit \$!
232
+ fi
233
+ done
234
+ EOF
235
+
236
+ # Even though we fail to create refs/tags/tag1 the below command
237
+ # unexpectedly succeeds.
238
+ git -C clone5 fetch .. $B:refs/heads/something &&
239
+ test $B = $(git -C clone5 rev-parse --verify refs/heads/something) &&
240
+ test $S = $(git -C clone5 rev-parse --verify tag2) &&
241
+ test_must_fail git -C clone5 rev-parse --verify tag1
242
+'
243
+
244
test_done