updateref: Fix indeterminate state when locking refs
When using the updateref package, one would typically first queue updates, then prepare the transaction and finally commit it. At prepare time, the expectation is that all refs will be locked after the function call has succeeded. But because git-update-ref(1) had a bug which kept us from reading the status report, we couldn't assert that this is the case and just went ahead after requesting the state transition. The result is that callers may act on supposedly-locked refs while locking either hasn't finished yet or failed already. In the context of Gitaly Cluster this means that we may cast votes on already-failed updates.
Now that we have backported the upstreamed patch to properly flush out
status reports we can finally fix this bug by waiting for the status
report before returning from Prepare()
. This fixes the possibility for
races and will cause us to abort early in case we can already determine
that the update will fail anyway. Furthermore, it fixes a set of flaky
tests in the updateref package which hit this exact race.
Closes #3702 (closed)
Closes #3761 (closed)