示例#1
0
def diff(repository, ref, from_ref=None, **kwargs):
    """git diff command, pygit2 wrapper
    :param ref:
    :param from_ref:
    :param flags:
    :param context_lines:
    :param paths:
    """

    _diff = {}
    ref = ref.strip()
    sha = resolve_version(repository, ref)
    if not sha:
        raise JagareError("%s...%s" % (from_ref, ref))
    commit = get_commit_by_sha(repository, sha)
    from_commit = None
    if from_ref:
        from_ref = from_ref.strip()
        from_sha = resolve_version(repository, from_ref)
        if not from_sha:
            raise JagareError("%s...%s" % (from_ref, ref))
        from_commit = get_commit_by_sha(repository, from_sha)

    # get pygit2 diff
    if from_commit:
        diff, _diff['old_sha'] = diff_commits(repository, commit, from_commit,
                                              **kwargs)
    else:
        diff, _diff['old_sha'] = diff_commit(repository, commit, **kwargs)

    _diff['new_sha'] = commit.hex
    _diff['diff'] = diff

    return _diff
示例#2
0
def get_commit_by_sha(repository, sha):
    try:
        commit = repository[sha]
    except (ValueError, KeyError, TypeError):
        raise JagareError("Commit '%s' is invalid." % sha)

    if commit and commit.type == GIT_OBJ_COMMIT:
        return commit
示例#3
0
文件: ref.py 项目: tclh123/ellen
def update_ref(repository, ref, newvalue):
    """git update-ref/symbolic-ref command, pygit2 wrapper.

    :param ref: the full name of the reference/symbolic ref.
    :param newvalue: the sha-1 value of the commit
                      or the full name of the target reference."""
    # TODO: support for no-deref option
    # git update-ref
    if repository.is_empty:
        raise JagareError("repository is empty")

    try:
        commit = repository.revparse_single(newvalue)
    except KeyError:
        raise JagareError("newvalue is invalid.")
    except Exception:
        raise JagareError("refs not found.")

    try:
        repo_ref = repository.lookup_reference(ref)
    except KeyError:
        repository.create_reference(ref, commit.hex)
        return

    if repo_ref.type == GIT_REF_OID:
        try:
            repo_ref.target = commit.hex
        except OSError:
            raise JagareError("OSError occurred because of concurrency,"
                              " try again later")

    # TODO: change acting when the reference is symbolic
    elif repo_ref.type == GIT_REF_SYMBOLIC:
        # WARNING: this else is acting like `git symbolic-ref`
        try:
            repo_new = repository.lookup_reference(newvalue)
        except Exception:
            raise JagareError("refs not found.", 400)
        repo_ref.target = repo_new.name
示例#4
0
def create_commit(repository, branch, parent, author_name, author_email,
                  message, reflog, data):
    """git commit command, pygit2 wrapper.
    :param parent: parent ref
    :param data: list of tuple(filepath, content, action),
        action is insert/remove"""
    if repository.is_empty:
        if branch != "master" or parent != "master":
            raise JagareError("only commit to master when repo is empty")

    parents_sha = []
    parent_commit = None
    if not repository.is_empty:
        parent_commit = repository.revparse_single(parent)
        parents_sha.append(str(parent_commit.id))

    ret = []
    flag = False
    root = init_root()
    for filepath, content, action in data:
        content = unicode_to_utf8(content)
        content = content.replace("\r\n", "\n")
        if action == "insert":
            root.add_file(filepath, content)
        elif action == "remove":
            root.del_file(filepath)
        else:
            root.add_file(filepath, content)
        #filepath = unicode_to_utf8(filepath)
        #mode = _get_pygit2_mode(mode)
        flag = True

    # FIXME: remove this after refactor gist
    #if not flag:
    #    root.add_file('empty', '')
    #    flag = True

    if flag:
        for entry in root.walk():
            entry.write(repository, parent_commit if parent_commit else None)
        tree_oid = root.id
        signature = Signature(author_name, author_email)
        commit_oid = repository.create_commit("refs/heads/%s" % branch,
                                              signature, signature, message,
                                              tree_oid, parents_sha)
        master = repository.lookup_reference("refs/heads/%s" % branch)
        master.target = str(commit_oid)
        master.log_append(str(commit_oid), signature, reflog)
        return ret
    return []
示例#5
0
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
示例#6
0
def repository(path):
    try:
        repo = Repository(path)
    except KeyError:
        raise JagareError('repo %s not exists' % path)
    return repo