Over a million developers have joined DZone.

Get Diffs Of A Changeset Using Pysvn


from svn import fs, repos, core, delta
import difflib

def cat(path, rev, fs_ptr, taskpool):
    """dump the contents of a file"""
    contents = ''
    root = fs.revision_root(fs_ptr, rev, taskpool)
    if not len(path):
      print "You must supply a file path."
      return contents
    kind = fs.check_path(root, path, taskpool)
    if kind == core.svn_node_none:
      print "Path '%s' does not exist." % path
      return contents
    if kind == core.svn_node_dir:
      print "Path '%s' is not a file." % path
      return contents
    filelen = fs.file_length(root, path, taskpool)
    stream = fs.file_contents(root, path, taskpool)
    read = 0
    while read < filelen:
      contents += core.svn_stream_read(stream, int(core.SVN_STREAM_CHUNK_SIZE))
      read += len(contents)
    contents += core.svn_stream_read(stream, int(filelen))
    return contents

def diff(text1, text2):
    result = difflib.unified_diff(text1.splitlines(1), text2.splitlines(1))
    return ''.join(result)

def get_diff(rev, fs_ptr, pool):
    root = fs.revision_root(fs_ptr, rev, pool)
    editor = repos.RevisionChangeCollector(fs_ptr, rev, pool)
    e_ptr, e_baton = delta.make_editor(editor, pool)
    repos.svn_repos_replay(root, e_ptr, e_baton, pool)

    changes = []
    for path, change in editor.changes.items():
        changes.append([path, change.base_rev])

    final_diff = ''
    for path, base_rev in changes:
        text1 = cat(path, base_rev, fs_ptr, pool)
        text2 = ccat(path, rev, fs_ptr, pool)
        final_diff += diff(text1, text2)

    return final_diff

def main(pool):

    # customize this
    repos_path = '/path/to/repository/'
    revision = 3
    repos_ptr = repos.svn_repos_open(repos_path, pool)
    fs_ptr = repos.svn_repos_fs(repos_ptr)

    print get_diff(revision, fs_ptr, pool)

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}