Merge pull request #35249 from terminalmage/issue35214

Fix regression in git.latest
This commit is contained in:
Mike Place 2016-08-06 16:52:15 +09:00 committed by GitHub
commit d65a5c7134
2 changed files with 78 additions and 26 deletions

View file

@ -809,16 +809,11 @@ def latest(name,
elif remote_rev_type == 'sha1':
has_remote_rev = True
# If has_remote_rev is False, then either the remote rev could not
# be found with git ls-remote (in which case we won't know more
# until fetching) or we're going to be checking out a new branch
# and don't have to worry about fast-forwarding. So, we will set
# fast_forward to None (to signify uncertainty) unless there are
# local changes, in which case we will set it to False.
# If fast_forward is not boolean, then we don't know if this will
# be a fast forward or not, because a fetch is requirde.
fast_forward = None if not local_changes else False
if has_remote_rev:
# Remote rev already present
if (not revs_match and not update_head) \
and (branch is None or branch == local_branch):
ret['comment'] = remote_loc.capitalize() \
@ -831,25 +826,26 @@ def latest(name,
)
return ret
# No need to check if this is a fast_forward if we already know
# that it won't be (due to local changes).
if fast_forward is not False:
if base_rev is None:
# If we're here, the remote_rev exists in the local
# checkout but there is still no HEAD locally. A possible
# reason for this is that an empty repository existed there
# and a remote was added and fetched, but the repository
# was not fast-forwarded. Regardless, going from no HEAD to
# a locally-present rev is considered a fast-forward
# update, unless there are local changes.
fast_forward = not bool(local_changes)
else:
fast_forward = __salt__['git.merge_base'](
target,
refs=[base_rev, remote_rev],
is_ancestor=True,
user=user,
ignore_retcode=True)
# No need to check if this is a fast_forward if we already know
# that it won't be (due to local changes).
if fast_forward is not False:
if base_rev is None:
# If we're here, the remote_rev exists in the local
# checkout but there is still no HEAD locally. A
# possible reason for this is that an empty repository
# existed there and a remote was added and fetched, but
# the repository was not fast-forwarded. Regardless,
# going from no HEAD to a locally-present rev is
# considered a fast-forward update, unless there are
# local changes.
fast_forward = not bool(local_changes)
else:
fast_forward = __salt__['git.merge_base'](
target,
refs=[base_rev, remote_rev],
is_ancestor=True,
user=user,
ignore_retcode=True)
if fast_forward is False:
if not force_reset:

View file

@ -197,6 +197,62 @@ class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
finally:
shutil.rmtree(name, ignore_errors=True)
def test_latest_fast_forward(self):
'''
Test running git.latest state a second time after changes have been
made to the remote repo.
'''
def _head(cwd):
return self.run_function('git.rev_parse', [cwd, 'HEAD'])
repo_url = 'https://{0}/saltstack/salt-test-repo.git'.format(self.__domain)
mirror_dir = os.path.join(integration.TMP, 'salt_repo_mirror')
mirror_url = 'file://' + mirror_dir
admin_dir = os.path.join(integration.TMP, 'salt_repo_admin')
clone_dir = os.path.join(integration.TMP, 'salt_repo')
try:
# Mirror the repo
self.run_function('git.clone',
[mirror_dir, repo_url, None, '--mirror'])
# Make sure the directory for the mirror now exists
self.assertTrue(os.path.exists(mirror_dir))
# Clone the mirror twice, once to the admin location and once to
# the clone_dir
ret = self.run_state('git.latest', name=mirror_url, target=admin_dir)
self.assertSaltTrueReturn(ret)
ret = self.run_state('git.latest', name=mirror_url, target=clone_dir)
self.assertSaltTrueReturn(ret)
# Make a change to the repo by editing the file in the admin copy
# of the repo and committing.
head_pre = _head(admin_dir)
with open(os.path.join(admin_dir, 'LICENSE'), 'a') as fp_:
fp_.write('Hello world!')
self.run_function('git.commit', [admin_dir, 'Added a line', '-a'])
# Make sure HEAD is pointing to a new SHA so we know we properly
# committed our change.
head_post = _head(admin_dir)
self.assertNotEqual(head_pre, head_post)
# Push the change to the mirror
# NOTE: the test will fail if the salt-test-repo's default branch
# is changed.
self.run_function('git.push', [admin_dir, 'origin', 'develop'])
# Re-run the git.latest state on the clone_dir
ret = self.run_state('git.latest', name=mirror_url, target=clone_dir)
self.assertSaltTrueReturn(ret)
# Make sure that the clone_dir now has the correct SHA
self.assertEqual(head_post, _head(clone_dir))
finally:
for path in (mirror_dir, admin_dir, clone_dir):
shutil.rmtree(path, ignore_errors=True)
def test_present(self):
'''
git.present