Fix race condition in git.latest

The git.latest state runs a `git ls-remote` on the remote repo to
discover which SHA it should end up at, and whether or not it needs to
fetch from the repo to get the commit it needs. However, since we
fast-forward using a `git merge` to the branch specified in the `rev`
argument, this leaves the state susceptible to a race condition when
someone pushes to the remote repo between when we run the `git
ls-remote` and when we fetch the remote repo. We will successfully
fast-forward to the head of the branch, but that branch will be pointing
to a different commit than the one identified in the `git ls-remote`, so
we will report the state as having failed.

This commit fixes that race condition by fast-forwarding to the commit
identified in the `git ls-remote`, rather than to the branch named by
`rev`.

NOTE: This means that in these edge cases, we will report a `True`
result despite the head of the branch having advanced past the commit to
which we fast-forwarded, but that seems like a reasonable trade-off for
avoiding a race condition. If we repeated the `git ls-remote` after
fetching, we'd just be opening up a window (albeit a smaller one) for
another race condition.
This commit is contained in:
Erik Johnson 2017-08-18 16:19:40 -05:00
parent 96e8e836d1
commit 093c0c2f77

View file

@ -1472,8 +1472,6 @@ def latest(name,
user=user,
password=password,
ignore_retcode=True):
merge_rev = remote_rev if rev == 'HEAD' \
else desired_upstream
if git_ver >= _LooseVersion('1.8.1.6'):
# --ff-only added in version 1.8.1.6. It's not
@ -1490,7 +1488,7 @@ def latest(name,
__salt__['git.merge'](
target,
rev=merge_rev,
rev=remote_rev,
opts=merge_opts,
user=user,
password=password)