mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
salt.utils.gitfs: Fix Dulwich env detection and submodule handling
I broke this indae738f
. I mistakenly thought I saw both head refs and remote refs in the fetch results, so by consolidating the code that resolves refnames into environment names I ensured that the head refs which were fetched would never be seen as fileserver environments. This commit fixes #29684 by converting the names of the fetched head refs to remote refs. Corresponding changes were also made to the get_tree() function (as the refnames are now different). Additionally, I discovered that Dulwich does not track information about submodules, resulting in a KeyError when compiling a list of files. This is the same issue that also affected Pygit2 and was fixed in8c4ea64
. I've made a similar fix for it here.
This commit is contained in:
parent
54b9641330
commit
a746014f7e
1 changed files with 38 additions and 6 deletions
|
@ -1307,7 +1307,11 @@ class Dulwich(GitProvider): # pylint: disable=abstract-method
|
|||
all the empty directories within it in the "blobs" list
|
||||
'''
|
||||
for item in six.iteritems(tree):
|
||||
obj = self.repo.get_object(item.sha)
|
||||
try:
|
||||
obj = self.repo.get_object(item.sha)
|
||||
except KeyError:
|
||||
# Entry is a submodule, skip it
|
||||
continue
|
||||
if not isinstance(obj, dulwich.objects.Tree):
|
||||
continue
|
||||
blobs.append(os.path.join(prefix, item.path))
|
||||
|
@ -1380,6 +1384,21 @@ class Dulwich(GitProvider): # pylint: disable=abstract-method
|
|||
'Unable to remove {0}: {1}'.format(self.cachedir, exc)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
# Dulwich does not write fetched references to the gitdir, that is
|
||||
# done manually below (see the "Update local refs" comment). Since
|
||||
# A) gitfs doesn't check out any local branches, B) both Pygit2 and
|
||||
# GitPython set remote refs when fetching instead of head refs, and
|
||||
# C) Dulwich is not supported for git_pillar or winrepo, there is
|
||||
# no harm in simply renaming the head refs from the fetch results
|
||||
# to remote refs. This allows the same logic (see the
|
||||
# "_get_envs_from_ref_paths()" function) to be used for all three
|
||||
# GitProvider subclasses to derive available envs.
|
||||
for ref in [x for x in refs_post if x.startswith('refs/heads/')]:
|
||||
val = refs_post.pop(ref)
|
||||
key = ref.replace('refs/heads/', 'refs/remotes/origin/', 1)
|
||||
refs_post[key] = val
|
||||
|
||||
if refs_post is None:
|
||||
# Empty repository
|
||||
log.warning(
|
||||
|
@ -1392,7 +1411,7 @@ class Dulwich(GitProvider): # pylint: disable=abstract-method
|
|||
for ref in self.get_env_refs(refs_post):
|
||||
self.repo[ref] = refs_post[ref]
|
||||
# Prune stale refs
|
||||
for ref in self.repo.get_refs():
|
||||
for ref in refs_pre:
|
||||
if ref not in refs_post:
|
||||
del self.repo[ref]
|
||||
return True
|
||||
|
@ -1408,7 +1427,11 @@ class Dulwich(GitProvider): # pylint: disable=abstract-method
|
|||
all the file paths and symlinks info in the "blobs" dict
|
||||
'''
|
||||
for item in six.iteritems(tree):
|
||||
obj = self.repo.get_object(item.sha)
|
||||
try:
|
||||
obj = self.repo.get_object(item.sha)
|
||||
except KeyError:
|
||||
# Entry is a submodule, skip it
|
||||
continue
|
||||
if isinstance(obj, dulwich.objects.Blob):
|
||||
repo_path = os.path.join(prefix, item.path)
|
||||
blobs.setdefault('files', []).append(repo_path)
|
||||
|
@ -1502,10 +1525,19 @@ class Dulwich(GitProvider): # pylint: disable=abstract-method
|
|||
refs = self.repo.get_refs()
|
||||
# Sorting ensures we check heads (branches) before tags
|
||||
for ref in sorted(self.get_env_refs(refs)):
|
||||
# ref will be something like 'refs/heads/master'
|
||||
rtype, rspec = ref[5:].split('/', 1)
|
||||
# ref will be something like 'refs/remotes/origin/master'
|
||||
try:
|
||||
rtype, rspec = re.split('^refs/(remotes/origin|tags)/',
|
||||
ref,
|
||||
1)[-2:]
|
||||
except ValueError:
|
||||
# No match was fount for the split regex, we don't care about
|
||||
# this ref. We shouldn't see any of these as the refs are being
|
||||
# filtered through self.get_env_refs(), but just in case, this
|
||||
# will avoid a traceback.
|
||||
continue
|
||||
if rspec == tgt_ref and self.env_is_exposed(tgt_env):
|
||||
if rtype == 'heads':
|
||||
if rtype == 'remotes/origin':
|
||||
commit = self.repo.get_object(refs[ref])
|
||||
elif rtype == 'tags':
|
||||
tag = self.repo.get_object(refs[ref])
|
||||
|
|
Loading…
Add table
Reference in a new issue