def ls_tree(repository, ref,
            recursive=None, size=None, name_only=None,
            req_path=None, with_commit=False):
    """git ls-tree command, pygit2 wrapper.
    List the contents of a tree object.
    """

    if req_path:
        req_path = _remove_slash(req_path)

    try:
        obj = repository.revparse_single(ref)
    except (ValueError, KeyError):
        raise JagareError("Reference not found.")

    commit_obj = None

    if obj.type == GIT_OBJ_TREE:
        tree_obj = obj
    elif obj.type == GIT_OBJ_TAG:
        commit_obj = repository.revparse_single(obj.target.hex)
        tree_obj = commit_obj.tree
    elif obj.type == GIT_OBJ_BLOB:
        raise JagareError("Object is blob, doesn't contain any tree")
    elif obj.type == GIT_OBJ_COMMIT:
        commit_obj = obj
        tree_obj = obj.tree

    if req_path:
        tree_entry = tree_obj[req_path]
        tree_obj = repository[tree_entry.id]
        walker = _walk_tree(tree_obj, req_path)
    else:
        walker = _walk_tree(tree_obj)

    ret_tree = {}
    submodule_obj = None
    submodule = None
    try:
        submodule_obj = repository.revparse_single("%s:.gitmodules" % ref)
        submodule = _parse_submodule(repository, submodule_obj)
    except (ValueError, KeyError):
        # FIXME: return error
        pass
        #raise JagareError("Reference not found.")

    for index, (entry, path) in enumerate(walker):
        mode = '%06o' % entry.filemode
        if mode == '160000':
            objtype = 'submodule'  # For git submodules
        elif mode == '040000':
            objtype = 'tree'
        else:
            objtype = 'blob'
        path = "%s/%s" % (path, entry.name) if path else entry.name

        if recursive and entry.type == GIT_OBJ_TREE:
            _tree = repository[entry.id]
            _tree_list = _walk_tree(_tree, path)
            for _index, _entry in enumerate(_tree_list):
                walker.insert(index + _index + 1, _entry)
            continue

        if name_only:
            ret_tree[path] = path
            continue

        item = {
            "id": entry.hex,  # FIXME: remove this
            "mode": mode,
            "type": objtype,
            "sha": entry.hex,
            "path": path,
            "name": entry.name
        }

        if entry.type == GIT_OBJ_COMMIT:
            item['submodule'] = _format_submodule(submodule, path)

        if size:
            if objtype == 'blob':
                blob = repository[entry.id]
                item['size'] = blob.size
            else:
                item['size'] = '-'

        ret_tree[path] = item

    if name_only:
        return ret_tree.values()

    if with_commit and commit_obj:
        _format_with_last_commit(repository, ret_tree, commit_obj)

    tree_list = ret_tree.values()
    tree_list.sort(key=lambda i: (TREE_ORDER[i['type']], i['name']))
    return tree_list
dataset/ETHPy150Open douban/ellen/ellen/git/tree.py/ls_tree/original