[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: usage of svn_wc_diff

From: Daniel Näslund <daniel_at_longitudo.com>
Date: Wed, 8 Dec 2010 22:35:10 +0100

On Tue, Dec 07, 2010 at 10:39:28AM -0800, JamieEchlin wrote:
>
> Hi,
>
> Firstly I hope this is the right forum, it doesn't seem appropriate for the
> dev forum.
>
> Has anyone got an example of using svn_wc_diff (or 2/3/4 etc), preferably
> from python? I can find zero examples on the interwebs. I can't work out
> what I need to pass from the minimal doxygen docs...
>
> Basically I'm trying to do a working copy diff... I know I can call svn but
> I need this to work in an env where svn(.exe) might not be present, and also
> it doesn't give me enough control for what I'm trying to do, which is
> basically property diffs.

This mail contains only fragments of code that I haven't tested much at
all. For examples of using the swig-python bindings, read
subversion/bindings/swig/python/tests/*.py. For an example in C of how
the diff callbacks are implemented read subversion/libsvn_client/diff.c.

Here's a really rough sketch [2] of how you might call svn_wc_diff4() with
the 1.6 swig bindings. It doesn't produce any diff output, for that
you'd have to call the diff library functions [1] with the data you've
collected through the diff callbacks. Note that the output for the
property diffs are not created through the diff library (they will be in
1.7 though, e.g. using regular unidiff format for both props and file
contents).

[1] Code for calling the diff library functions:
[[[
#!/usr/bin/env python

import getopt
import sys
import os
import svn.diff, svn.core, svn.client

def diff_with_pools(modified, original):
    pool = svn.core.Pool()
    diff = svn.diff.svn_diff_file_diff_2(original, modified, "", pool)
    has_changes = svn.diff.contains_diffs(diff)
    print has_changes
    svn.diff.file_output_unified3(sys.stdout, diff, original, modified,
                                  None, None, "", None, True)

if __name__ == '__main__':
    # Canonicalize the repository path
    modified = svn.core.svn_path_canonicalize(args[0])
    original = svn.core.svn_path_canonicalize(args[1])

    pool = svn.core.Pool()
    diff = svn.diff.svn_diff_file_diff_2(original, modified, "", pool)
    has_changes = svn.diff.contains_diffs(diff)
    print has_changes
    svn.diff.file_output_unified3(sys.stdout, diff, original, modified,
                                  None, None, "", None, True)
]]]

[2] Code for calling svn_wc_diff4()
[[[

#!/usr/bin/env python

import svn.wc
import svn.core
import svn.client
import svn.ra

def props_changed(path, propchanges):
    """ Here you'll have to find out what properties are regular props
        and write them out in a manner similar to what
        libsvn_client/diff.c::display_prop_diff() does. """

    for (name, value) in propchanges.items():
        (kind, unused_prefix_len) = svn.core.svn_property_kind(name)
        if kind != svn.core.svn_prop_regular_kind:
            continue
        ### Append to some prop dict

class Callback(svn.wc.DiffCallbacks2):
    def file_changed(self, adm_access, path,
                     tmpfile1, tmpfile2, rev1, rev2,
                     mimetype1, mimetype2, propchanges,
                     originalprops):
        print "In file_changed"
        props_changed(path, propchanges)
        return (svn.wc.notify_state_unknown, svn.wc.notify_state_unknown)

    def file_added(self, adm_access, path, tmpfile1, tmpfile2,
                   rev1, rev2, mimetype1, mimetype2, propchanges,
                   originalprops):
        print "In file_added"
        return (svn.wc.notify_state_unknown, svn.wc.notify_state_unknown)

    def file_deleted(self, adm_access, path, tmpfile1,
                     tmpfile2, mimetype1, mimetype2, originalprops):
            print "In file_deleted"
            return svn.wc.notify_state_unknown

    def dir_added(self, adm_access, path, rev):
        print "In dir_added"
        return svn.wc.notify_state_unknown

    def dir_deleted(self, adm_access, path):
        print "In dir_deleted"
        return svn.wc.notify_state_unknown

    def dir_props_changed(self, adm_access, path,
                          propchanges, original_props):
        print "In dir_props_changed"
        props_changed(path, propchanges)
        return svn.wc.notify_state_unknown

target = 'iota'
diff_callbacks = Callback()
depth = svn.core.svn_depth_infinity
pool = svn.core.Pool()

path_to_wc = "wc"
wc = svn.wc.adm_open3(None, path_to_wc, True, -1, None)

svn.wc.svn_wc_diff4(wc, target, diff_callbacks, depth, False,
                    None, pool)
]]]

Daniel
Received on 2010-12-08 22:36:00 CET

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.