repository: Fix excessive voting in CreateRepositoryFromBundle
The CreateRepositoryFromBundle()
RPC does a git-clone(1) followed by a
git-fetch(1) to obtain any references which aren't obtained via the
default refspec. While git-clone(1) creates a single reference
transaction to create all references, git-fetch(1) will by default
create one reference transaction per reference that is to be updated. In
the context of strong consistency, this can thus result in excessive
votes in case a repository has lots of references which are neither
branches nor tags.
To fix this issue, we can use the --atomic
flag for git-fetch(1) which
we have upstreamed in Git v2.31.0. This will update all references in a
single atomic tranasction and thus cause the reference-transaction hook
to only be executed twice (once for "prepare" state, and once for
"commit" state). This effectively puts a boundary of 7 on transactional
votes that CreateRepositoryFromBundle: two votes for the clone, two for
the fetch and a final one to iterate over all existing references via
git-for-each-ref(1).
Given that we cannot introduce new voting behaviour in a release and also enable it right away to allow for zero-downtime upgrades, this change is hidden behind a feature flag.
Fixes gitlab#334365 (closed)