Example #1
0
def commit(repo, commit_msg):
    if not commit_msg:
        commit_msg = 'dulwich_' + U.stime()
    if not py.isbytes(commit_msg):
        commit_msg = commit_msg.encode('utf-8')

    index = repo.open_index()
    new_tree = index.commit(repo.object_store)
    if new_tree != repo[repo.head()].tree:
        bhash = repo.do_commit(commit_msg, tree=new_tree)
        return bhash, commit_msg
    else:
        return b'', py.No("Empty commit!")
Example #2
0
def get_git_patch(repo, unstaged=True):
    final_changes = {}
    store = OverrideObjectStore(repo.object_store)

    try:
        head = repo.head()
    except KeyError:
        return None

    tree_id = repo[head].tree
    tree = repo[tree_id]

    index = repo.open_index()

    normalizer = repo.get_blob_normalizer()
    filter_callback = normalizer.checkin_normalize
    object_store = repo.object_store
    blob_from_path_and_stat = dulwich.index.blob_from_path_and_stat
    cleanup_mode = dulwich.index.cleanup_mode
    lookup_path = tree.lookup_path
    repo_path = repo.path.encode(sys.getfilesystemencoding())

    def lookup_entry(path):
        absolute_path = os.path.join(repo_path, path)
        if os.path.isfile(absolute_path):
            st = os.lstat(absolute_path)
            # TODO: Building the blob means that we need to load the whole
            # file content in memory. We should be able to compute the sha
            # without needed to load the whole blob in memory.
            blob = blob_from_path_and_stat(absolute_path, st)
            blob = filter_callback(blob, path)
            blob_id = blob.id

            mode = cleanup_mode(st.st_mode)

            # Check if on-disk blob differs from the one in tree
            try:
                tree_blob = lookup_path(object_store.__getitem__, path)
            except KeyError:
                # Lookup path will fails for added files
                store[blob_id] = blob
            else:
                # If the blob for path in index differs from the one on disk,
                # store the on-disk one
                if tree_blob[1] != blob_id:
                    store[blob_id] = blob

            return blob_id, mode
        elif os.path.isdir(absolute_path):
            try:
                tree_blob = lookup_path(object_store.__getitem__, path)
            except KeyError:
                # If the submodule is not in the store, it must be in index
                # and should be added
                index_entry = index[path]
                return index_entry.sha, index_entry.mode

            tree_mode = tree_blob[0]

            if dulwich.objects.S_ISGITLINK(tree_mode):
                return tree_blob[1], tree_mode
            else:
                # We shouldn't be here?
                raise KeyError(path)
        else:
            # Indicate that the files has been removed
            raise KeyError(path)

    # Merges names from the index and from the store as some files can be only
    # on index or only on the store
    names = set()
    for (name, _, _) in object_store.iter_tree_contents(tree_id):
        names.add(name)

    names.update(index._byname.keys())

    final_changes = dulwich.index.changes_from_tree(names,
                                                    lookup_entry,
                                                    repo.object_store,
                                                    tree_id,
                                                    want_unchanged=False)

    # Generate the diff

    diff = BytesIO()

    def key(x):
        # Generate a comparable sorting key
        paths = tuple(p for p in x[0] if p)
        return paths

    for (oldpath, newpath), (oldmode,
                             newmode), (oldsha,
                                        newsha) in sorted(final_changes,
                                                          key=key):
        dulwich.patch.write_object_diff(diff, store,
                                        (oldpath, oldmode, oldsha),
                                        (newpath, newmode, newsha))

    diff.seek(0)
    diff_result = diff.getvalue()

    # Detect empty diff
    if not diff_result:
        return None

    return diff_result
Example #3
0
#! /bin/python

#import git
#repo = git.Repo( '.' )
#print repo.git.status()

#import sh
#git = sh.git.bake(_cwd='.')
#print git.status()

#import pygit2
#repo = pygit2.Repository('.')
#print repo.path
#print repo.status()

import dulwich.repo
repo = dulwich.repo.Repo('.')
print repo
index = repo.open_index()
print index
print list(index)
Example #4
0
def emit_repo_as_xdot(repo, options):
    '''Emits xdot for the given repo on stdout.'''

    global graph  # TODO: globals are bad mmmmkay
    global vertices

    vertices = {}

    graph = pydot.Graph(verbose=True)
    graph.set_bgcolor('#00000000')  # transparent background

    objstore = repo.object_store
    seen = set()

    # walk everything in the object store. (this means orphaned nodes will show.)
    for sha in objstore:
        if not options.blobs and objstore[sha].type_name in ('blob', 'tree'):
            continue
        walk_node(objstore, seen, sha, options)

    for ref in repo.refs.keys():
        if ref == 'HEAD':
            continue  # TODO: let this loop handle symbolic refs too
        branch_node = add_branch_node(ref)
        graph.add_edge(
            pydot.Edge(branch_node, repo.refs[ref],
                       **edge_opts(style='dotted')))

    # do HEAD as a special case
    ref = 'HEAD'
    nopts = node_opts(label=ref,
                      shape='diamond',
                      style='filled',
                      fillcolor='#ff3333',
                      fontcolor='white',
                      tooltip='Symbolic Ref: HEAD')
    head_node = pydot.Node(ref, **nopts)
    graph.add_node(head_node)

    symref = repo.refs.read_ref(ref)
    if symref.startswith('ref: '):
        symref = symref[5:]
    points_to = add_branch_node(symref)
    graph.add_node(points_to)
    graph.add_edge(
        pydot.Edge(head_node, add_branch_node(symref),
                   **edge_opts(style='dotted')))

    # index
    if options.index:
        try:
            head_tree = repo['HEAD'].tree
        except KeyError:
            head_tree = None

        index = repo.open_index()

    try:
        changes = list(index.changes_from_tree(objstore, head_tree))
    except TypeError:
        # the official dulwich repo throws a TypeError changes_from_tree is
        # called against an empty tree (None)
        if head_tree is not None: raise
        changes = []

    if changes:
        index_node = pydot.Node('index',
                                shape='invtriangle',
                                style='filled',
                                fillcolor='#33ff33',
                                fontname=DEFAULT_FONTNAME,
                                fontsize=DEFAULT_FONTSIZE)
        graph.add_node(index_node)
        for (oldpath, newpath), (oldmode, newmode), (oldsha,
                                                     newsha) in changes:
            graph.add_edge(
                pydot.Edge(index_node,
                           vert_for_sha(objstore, newsha),
                           label=q('  ' + newpath),
                           fontname=DEFAULT_FONTNAME,
                           fontsize=DEFAULT_FONTSIZE))

    # invoke dot -Txdot to turn out DOT file into an xdot file, which canviz is expecting
    subprocess.Popen(['dot', '-Txdot'],
                     stdin=subprocess.PIPE).communicate(graph.to_string())
Example #5
0
def emit_repo_as_xdot(repo, options):
    """Emits xdot for the given repo on stdout."""

    global graph  # TODO: globals are bad mmmmkay
    global vertices

    vertices = {}

    graph = pydot.Graph(verbose=True)
    graph.set_bgcolor("#00000000")  # transparent background

    objstore = repo.object_store
    seen = set()

    # walk everything in the object store. (this means orphaned nodes will show.)
    for sha in objstore:
        if not options.blobs and objstore[sha].type_name in ("blob", "tree"):
            continue
        walk_node(objstore, seen, sha, options)

    for ref in repo.refs.keys():
        if ref == "HEAD":
            continue  # TODO: let this loop handle symbolic refs too
        branch_node = add_branch_node(ref)
        graph.add_edge(pydot.Edge(branch_node, repo.refs[ref], **edge_opts(style="dotted")))

    # do HEAD as a special case
    ref = "HEAD"
    nopts = node_opts(
        label=ref, shape="diamond", style="filled", fillcolor="#ff3333", fontcolor="white", tooltip="Symbolic Ref: HEAD"
    )
    head_node = pydot.Node(ref, **nopts)
    graph.add_node(head_node)

    symref = repo.refs.read_ref(ref)
    if symref.startswith("ref: "):
        symref = symref[5:]
    points_to = add_branch_node(symref)
    graph.add_node(points_to)
    graph.add_edge(pydot.Edge(head_node, add_branch_node(symref), **edge_opts(style="dotted")))

    # index
    if options.index:
        try:
            head_tree = repo["HEAD"].tree
        except KeyError:
            head_tree = None

        index = repo.open_index()

    try:
        changes = list(index.changes_from_tree(objstore, head_tree))
    except TypeError:
        # the official dulwich repo throws a TypeError changes_from_tree is
        # called against an empty tree (None)
        if head_tree is not None:
            raise
        changes = []

    if changes:
        index_node = pydot.Node(
            "index",
            shape="invtriangle",
            style="filled",
            fillcolor="#33ff33",
            fontname=DEFAULT_FONTNAME,
            fontsize=DEFAULT_FONTSIZE,
        )
        graph.add_node(index_node)
        for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
            graph.add_edge(
                pydot.Edge(
                    index_node,
                    vert_for_sha(objstore, newsha),
                    label=q("  " + newpath),
                    fontname=DEFAULT_FONTNAME,
                    fontsize=DEFAULT_FONTSIZE,
                )
            )

    # invoke dot -Txdot to turn out DOT file into an xdot file, which canviz is expecting
    subprocess.Popen(["dot", "-Txdot"], stdin=subprocess.PIPE).communicate(graph.to_string())