DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Get Diffs Of A Changeset Using Pysvn

09.16.2005
| 2905 views |
  • submit to reddit
        
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])
    changes.sort()

    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)
    
core.run_app(main)