# Buggy code
def find_file(path, short="base", **kwargs):
    """
    Find the first file to match the path and ref, read the file out of hg
    and send the path to the newly cached file
    """
    fnd = {"path": "", "rel": ""}
    if os.path.isabs(path):
        return fnd

    local_path = path
    path = os.path.join(__opts__["hgfs_root"], local_path)

    if __opts__["hgfs_branch_method"] != "bookmarks" and short == "base":
        short = "default"
    dest = os.path.join(__opts__["cachedir"], "hgfs/refs", short, path)
    hashes_glob = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.hash.*".format(path)
    )
    blobshadest = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.hash.blob_sha1".format(path)
    )
    lk_fn = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.lk".format(path)
    )
    destdir = os.path.dirname(dest)
    hashdir = os.path.dirname(blobshadest)
    if not os.path.isdir(destdir):
        os.makedirs(destdir)
    if not os.path.isdir(hashdir):
        os.makedirs(hashdir)
    repos = init()
    if "index" in kwargs:
        try:
            repos = [repos[int(kwargs["index"])]]
        except IndexError:
            # Invalid index param
            return fnd
        except ValueError:
            # Invalid index option
            return fnd
    for repo in repos:
        repo.open()
        ref = _get_ref(repo, short)
        if not ref:
            # Branch or tag not found in repo, try the next
            continue
        _wait_lock(lk_fn, dest)
        if os.path.isfile(blobshadest) and os.path.isfile(dest):
            with salt.utils.fopen(blobshadest, "r") as fp_:
                sha = fp_.read()
                if sha == ref[2]:
                    fnd["rel"] = local_path
                    fnd["path"] = dest
                    return fnd
        try:
            repo.cat(["path:{0}".format(local_path)], rev=ref[2], output=dest)
        except hglib.error.CommandError:
            continue
        with salt.utils.fopen(lk_fn, "w+") as fp_:
            fp_.write("")
        for filename in glob.glob(hashes_glob):
            try:
                os.remove(filename)
            except Exception:
                pass
        with salt.utils.fopen(blobshadest, "w+") as fp_:
            fp_.write(ref[2])
        try:
            os.remove(lk_fn)
        except (OSError, IOError):
            pass
        fnd["rel"] = local_path
        fnd["path"] = dest
        return fnd
    return fnd


# Traceback (AttributeError)
[ERROR   ] Error in function _master_opts:
Traceback (most recent call last):
File "/usr/lib/pymodules/python2.7/salt/master.py", line 1444, in run_func
ret = getattr(self, func)(load)
File "/usr/lib/pymodules/python2.7/salt/master.py", line 891, in _master_opts
envs = self._file_envs()
File "/usr/lib/pymodules/python2.7/salt/fileserver/__init__.py", line 153, in envs
ret.update(self.servers[fstr]())
File "/usr/lib/pymodules/python2.7/salt/fileserver/hgfs.py", line 176, in envs
tags = repo.get_tags()
AttributeError: 'hgclient' object has no attribute 'get_tags'

# Fixed code
def find_file(path, short="base", **kwargs):
    """
    Find the first file to match the path and ref, read the file out of hg
    and send the path to the newly cached file
    """
    fnd = {"path": "", "rel": ""}
    if os.path.isabs(path):
        return fnd

    local_path = path
    path = os.path.join(__opts__["hgfs_root"], local_path)

    if __opts__["hgfs_branch_method"] != "bookmarks" and short == "base":
        short = "default"
    dest = os.path.join(__opts__["cachedir"], "hgfs/refs", short, path)
    hashes_glob = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.hash.*".format(path)
    )
    blobshadest = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.hash.blob_sha1".format(path)
    )
    lk_fn = os.path.join(
        __opts__["cachedir"], "hgfs/hash", short, "{0}.lk".format(path)
    )
    destdir = os.path.dirname(dest)
    hashdir = os.path.dirname(blobshadest)
    if not os.path.isdir(destdir):
        os.makedirs(destdir)
    if not os.path.isdir(hashdir):
        os.makedirs(hashdir)
    repos = init()
    if "index" in kwargs:
        try:
            repos = [repos[int(kwargs["index"])]]
        except IndexError:
            # Invalid index param
            return fnd
        except ValueError:
            # Invalid index option
            return fnd
    for repo in repos:
        repo.open()
        ref = _get_ref(repo, short)
        if not ref:
            # Branch or tag not found in repo, try the next
            continue
        _wait_lock(lk_fn, dest)
        if os.path.isfile(blobshadest) and os.path.isfile(dest):
            with salt.utils.fopen(blobshadest, "r") as fp_:
                sha = fp_.read()
                if sha == ref[2]:
                    fnd["rel"] = local_path
                    fnd["path"] = dest
                    return fnd
        try:
            repo.cat(["path:{0}".format(path)], rev=ref[2], output=dest)
        except hglib.error.CommandError:
            continue
        with salt.utils.fopen(lk_fn, "w+") as fp_:
            fp_.write("")
        for filename in glob.glob(hashes_glob):
            try:
                os.remove(filename)
            except Exception:
                pass
        with salt.utils.fopen(blobshadest, "w+") as fp_:
            fp_.write(ref[2])
        try:
            os.remove(lk_fn)
        except (OSError, IOError):
            pass
        fnd["rel"] = local_path
        fnd["path"] = dest
        return fnd
    return fnd