# Buggy code
def dir_list(self, tgt_env):
    """
    Get a list of directories for the target environment using pygit2
    """

    def _traverse(tree, blobs, prefix):
        """
        Traverse through a pygit2 Tree object recursively, accumulating all
        the empty directories within it in the "blobs" list
        """
        for entry in iter(tree):
            blob = self.repo[entry.oid]
            if not isinstance(blob, pygit2.Tree):
                continue
            blobs.append(os.path.join(prefix, entry.name))
            if len(blob):
                _traverse(blob, blobs, os.path.join(prefix, entry.name))

    ret = set()
    tree = self.get_tree(tgt_env)
    if not tree:
        return ret
    if self.root:
        try:
            oid = tree[self.root].oid
            tree = self.repo[oid]
        except KeyError:
            return ret
        if not isinstance(tree, pygit2.Tree):
            return ret
        relpath = lambda path: os.path.relpath(path, self.root)
    else:
        relpath = lambda path: path
    blobs = []
    if len(tree):
        _traverse(tree, blobs, self.root)
    add_mountpoint = lambda path: os.path.join(self.mountpoint, path)
    for blob in blobs:
        ret.add(add_mountpoint(relpath(blob)))
    if self.mountpoint:
        ret.add(self.mountpoint)
    return ret


# Traceback (KeyError)
2015-12-11 17:28:20,418 [salt.master      ][ERROR   ][1255] Error in function _file_list:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/master.py", line 1379, in run_func
ret = getattr(self, func)(load)
File "/usr/lib/python2.7/dist-packages/salt/fileserver/__init__.py", line 607, in file_list
ret.update(self.servers[fstr](load))
File "/usr/lib/python2.7/dist-packages/salt/fileserver/gitfs.py", line 180, in file_list
return gitfs.file_list(load)
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 2308, in file_list
return self._file_lists(load, 'files')
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 2285, in _file_lists
repo_files, repo_symlinks = repo.file_list(load['saltenv'])
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 1017, in file_list
_traverse(tree, blobs, self.root)
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 994, in _traverse
_traverse(obj, blobs, os.path.join(prefix, entry.name))
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 994, in _traverse
_traverse(obj, blobs, os.path.join(prefix, entry.name))
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 994, in _traverse
_traverse(obj, blobs, os.path.join(prefix, entry.name))
File "/usr/lib/python2.7/dist-packages/salt/utils/gitfs.py", line 986, in _traverse
obj = self.repo[entry.oid]
File "/usr/local/lib/python2.7/dist-packages/pygit2/repository.py", line 99, in __getitem__
raise KeyError(key)
KeyError: f16c3f1b33223c7ab82744fb00e6bbc3f48ce61b

# Fixed code
def dir_list(self, tgt_env):
    """
    Get a list of directories for the target environment using pygit2
    """

    def _traverse(tree, blobs, prefix):
        """
        Traverse through a pygit2 Tree object recursively, accumulating all
        the empty directories within it in the "blobs" list
        """
        for entry in iter(tree):
            if entry.oid not in self.repo:
                # Entry is a submodule, skip it
                continue
            blob = self.repo[entry.oid]
            if not isinstance(blob, pygit2.Tree):
                continue
            blobs.append(os.path.join(prefix, entry.name))
            if len(blob):
                _traverse(blob, blobs, os.path.join(prefix, entry.name))

    ret = set()
    tree = self.get_tree(tgt_env)
    if not tree:
        return ret
    if self.root:
        try:
            oid = tree[self.root].oid
            tree = self.repo[oid]
        except KeyError:
            return ret
        if not isinstance(tree, pygit2.Tree):
            return ret
        relpath = lambda path: os.path.relpath(path, self.root)
    else:
        relpath = lambda path: path
    blobs = []
    if len(tree):
        _traverse(tree, blobs, self.root)
    add_mountpoint = lambda path: os.path.join(self.mountpoint, path)
    for blob in blobs:
        ret.add(add_mountpoint(relpath(blob)))
    if self.mountpoint:
        ret.add(self.mountpoint)
    return ret