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

[PATCH] diff preview without text deltas

From: Martin Hauner <martin.hauner_at_gmx.net>
Date: 2005-07-12 22:05:02 CEST

Hi,

attached is a patch whichh adds new diff preview api calls (which the
gui clients like to have) that doesn't produce text deltas.

It runs but there are still a few issues i would like to discuss:

only new api calls
------------------

The patch just adds two new api calls and does not add any code to run
the preview from the command line tool.

Would you like to see some code to run the preview from "svn" too or
will you accept an api only patch?

minor version compatibility:
----------------------------

1) running with my modified trunk an "svn diff" against the 1.2 svnserve
    does work.

2) running a 1.2 client "svn diff" against the modified trunk svnserve
    does not work.

The HACKING file says:

> (a) Fields can be added to any tuple; old clients will simply
> ignore them. (Right now, the marshalling implementation does
> not let you put number or boolean values in the optional part
> of a tuple, but changing that will not affect the protocol.)

Since i added an optional bool (text_deltas) to do_diff it looks like
this is the problem. After patching vparse_tuple to simply return TRUE
for an unspecified bool 2) does work too.

(By the way, vparse_tuple seems to handle unspecified numbers 'n'. Is
this the number HACKING talks about?)

May i change vparse_tuple to ignore an (unspecified) optional boolean?
One would have to initialize the optional boolean value before running
vparse_tuple to make sure it has a valid value if it is ignored by
vparse_tuple.

subversion/libsvn_ra_svn/protocol
---------------------------------

should the protocol file be updated?

at least for diff it looks incomplete, it doesn't list the
ignore_ancestry bool parameter.

code duplication
----------------

I have added some helper stuff to avoid a lot of code duplication
between diff_preview and diff. The helper stuff is currently only
called by the new diff_preview methods. I haven't changed the diff
methods so far.

Would you like to see that in another patch or should I add it to
this patch? I would prefer another patch to have the two issues
(new feature, remove code duplication) seperated.

handles only repository/repository case
---------------------------------------

the diff preview does currently only handle diff previews between
two repository urls. I would like to add the other cases in another
patch. The current patch is already getting large.

Is this ok?

Bug?

----
Strange is that the diff preview sometimes lists files as changed
that have not changed, ie. the preview delta editors open_file
method gets called. If i run a normal svn diff on the same urls
the files are not part of the patch.
Is there something obvious i have to do to keep such files
out of the preview?
-- 
Martin
Subcommander, http://subcommander.tigris.org
a cross platform Win32/Unix/MacOSX subversion gui client & diff/merge tool.

Added new svn_client api calls svn_diff_preview & svn_diff_preview_peg.
A diff preview lists the changed items without creating text deltas.

To achieve this the svn_ra__vtable_t do_diff function got a new boolean
parameter text_deltas that is finally passed to svn_repos_begin_report
to run the diff without creating text deltas.

* subversion/include/svn_ra.h
  (svn_ra_do_diff2): new method, similar to svn_ra_do_diff but with a
  new text_deltas boolean parameter.
  (svn_ra_do_diff): updated method description, added deprecated note.
  (svn_ra_plugin_t): do_diff, added new text_deltas boolean parameter.

* subversion/libsvn_ra/ra_loader.h
  (svn_ra__vtable_t): added text_deltas parameter to do_diff function.

* subversion/libsvn_ra/ra_loader.c
  (svn_ra_do_diff2): new method.
  (svn_ra_do_diff): hardcoded TRUE as value for the new text_deltas
  parameter of do_diff.
  
* subversion/libsvn_ra/wrapper_template.h
  (compat_do_diff): added text_deltas parameter, pass new parameter to
  do_diff.

* subversion/include/svn_diff_preview.h
  new file, callback declaration for svn_client_diff_preview and
  for svn_client_diff_preview_peg.

* subversion/include/svn_client.h
  (svn_client_diff_preview,svn_client_diff_preview_peg): new methods.

* subversion/libsvn_client/client.h
  (svn_client__get_diff_preview_editor): new method, implemented in
  subversion/libsvn_client/repos_diff_preview.c.
  
* subversion/libsvn_client/repos_diff_preview.c
  new file, the implementation of the diff preview svn_delta_editor_t.

* subversion/libsvn_client/diff.c
  (diff_parameters,diff_paths,diff_repos_repos): new helper structures
  used by the new helper functions.
  (svn_client_check_paths,svn_client_check_paths_peg,
  diff_prepare_repos_repos): new helper methods used to remove most of
  the code duplication between diff and diff preview.
  (diff_preview_repos_repos): do diff preview between two repository
  paths.
  (do_diff_preview): new method, diff preview without peg revision.
  (do_diff_preview_peg): new method, diff preview with peg revision.
  (svn_client_diff_preview): new method, implemementation of public api
  diff preview function (without peg revision).
  (svn_client_diff_preview_peg): new method, implemementation of public
  api diff preview peg function.
  
* subversion/libsvn_ra_dav/ra_dav.h
  (svn_ra_dav__do_diff): added text_deltas boolean parameter.

* subversion/libsvn_ra_dav/fetch.c
  (svn_ra_dav__do_diff): added text_deltas boolean parameter. Passing
  new parameter to make_reporter.

* subversion/libsvn_ra_local/ra_plugin.c
  (svn_ra_local__do_diff): added text_deltas boolean parameter. Passing
  new parameter to make_reporter.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_diff): added text_deltas boolean parameter. Added text_deltas
  to "diff" cmd.

* subversion/svnserve/serve.c
  (diff): added parsing of the new text_deltas parameter. Passing new
  parameter to accept_report.

Index: subversion/libsvn_ra/wrapper_template.h
===================================================================
--- subversion/libsvn_ra/wrapper_template.h (revision 15310)
+++ subversion/libsvn_ra/wrapper_template.h (working copy)
@@ -287,8 +287,8 @@
   void *baton2;
   
   SVN_ERR (VTBL.do_diff (session_baton, &reporter2, &baton2, revision,
- diff_target, recurse, ignore_ancestry, versus_url,
- diff_editor, diff_baton, pool));
+ diff_target, recurse, ignore_ancestry, TRUE,
+ versus_url, diff_editor, diff_baton, pool));
 
   compat_wrap_reporter (reporter, report_baton, reporter2, baton2, pool);
 
Index: subversion/libsvn_ra/ra_loader.c
===================================================================
--- subversion/libsvn_ra/ra_loader.c (revision 15310)
+++ subversion/libsvn_ra/ra_loader.c (working copy)
@@ -409,6 +409,25 @@
                                      status_editor, status_baton, pool);
 }
 
+svn_error_t *svn_ra_do_diff2 (svn_ra_session_t *session,
+ const svn_ra_reporter2_t **reporter,
+ void **report_baton,
+ svn_revnum_t revision,
+ const char *diff_target,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
+ const char *versus_url,
+ const svn_delta_editor_t *diff_editor,
+ void *diff_baton,
+ apr_pool_t *pool)
+{
+ return session->vtable->do_diff (session, reporter, report_baton, revision,
+ diff_target, recurse, ignore_ancestry,
+ text_deltas, versus_url, diff_editor,
+ diff_baton, pool);
+}
+
 svn_error_t *svn_ra_do_diff (svn_ra_session_t *session,
                              const svn_ra_reporter2_t **reporter,
                              void **report_baton,
@@ -423,7 +442,8 @@
 {
   return session->vtable->do_diff (session, reporter, report_baton, revision,
                                    diff_target, recurse, ignore_ancestry,
- versus_url, diff_editor, diff_baton, pool);
+ TRUE, versus_url, diff_editor, diff_baton,
+ pool);
 }
 
 svn_error_t *svn_ra_get_log (svn_ra_session_t *session,
Index: subversion/libsvn_ra/ra_loader.h
===================================================================
--- subversion/libsvn_ra/ra_loader.h (revision 15310)
+++ subversion/libsvn_ra/ra_loader.h (working copy)
@@ -134,6 +134,7 @@
                            const char *diff_target,
                            svn_boolean_t recurse,
                            svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
                            const char *versus_url,
                            const svn_delta_editor_t *diff_editor,
                            void *diff_baton,
Index: subversion/include/svn_diff_preview.h
===================================================================
--- subversion/include/svn_diff_preview.h (revision 0)
+++ subversion/include/svn_diff_preview.h (revision 0)
@@ -0,0 +1,96 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file svn_diff_preview.h
+ * @brief callback declaration for svn_client_diff_preview
+ */
+
+#ifndef SVN_DIFF_PREVIEW_H
+#define SVN_DIFF_PREVIEW_H
+
+#include "svn_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/** the difference type in an svn_diff_preview_t structure.
+ *
+ * @since New in 1.3.
+ */
+typedef enum svn_diff_preview_kind
+{
+ /** an unchagned item */
+ svn_diff_preview_kind_unchanged,
+
+ /** an added item */
+ svn_diff_preview_kind_added,
+
+ /** a modified item */
+ svn_diff_preview_kind_modified,
+
+ /** a deleted item */
+ svn_diff_preview_kind_deleted
+
+} svn_diff_preview_kind_t;
+
+
+/** a diff summarize that describes the diff of an item. Passed to
+ * svn_diff_summarize_func_t.
+ *
+ * @since New in 1.3.
+ */
+typedef struct svn_diff_preview_t
+{
+ /** file or dir */
+ svn_node_kind_t node_kind;
+
+ /** item paths, relative to the old diff target and new diff target */
+ const char* path_old;
+ const char* path_new;
+
+ /** the mime types of old and new */
+ const char *mimetype_old;
+ const char *mimetype_new;
+
+ /** change kind: unchanged, added, modified or deleted */
+ svn_diff_preview_kind_t preview_kind;
+
+ /** properties changed? */
+ svn_boolean_t props_changed;
+
+} svn_diff_preview_t;
+
+
+/** A callback used in svn_client_diff_preview for reporting a @a diff
+ * preview.
+ *
+ * @a baton is a closure object; it should be provided by the
+ * implementation, and passed by the caller.
+ *
+ * @since New in 1.3.
+ */
+typedef void (*svn_diff_preview_func_t) (void *preview_baton,
+ svn_diff_preview_t *diff);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif // SVN_DIFF_PREVIEW_H

Property changes on: subversion\include\svn_diff_preview.h
___________________________________________________________________
Name: svn:eol-style
   + native

Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 15310)
+++ subversion/include/svn_client.h (working copy)
@@ -40,8 +40,8 @@
 #include "svn_error.h"
 #include "svn_opt.h"
 #include "svn_version.h"
+#include "svn_diff_preview.h"
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -1203,6 +1203,57 @@
                                   svn_client_ctx_t *ctx,
                                   apr_pool_t *pool);
 
+/**
+ * Produce a diff preview which lists the changed items between
+ * @a path1/@a revision1 and @a path2/@a revision2 without creating the
+ * delta. @a path1 and @a path2 can be either working-copy paths or URLs.
+ *
+ * Calls @a preview_func with @a preview_baton for each difference with
+ * a @c svn_diff_preview_t * structure describing the difference.
+ *
+ * See svn_client_diff3 for a description of the other parameters.
+ *
+ * @since New in 1.3.
+ */
+svn_error_t *
+svn_client_diff_preview (const char *path1,
+ const svn_opt_revision_t *revision1,
+ const char *path2,
+ const svn_opt_revision_t *revision2,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t no_diff_deleted,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Produce diff preview which lists the changed items between the
+ * filesystem object @a path in peg revision @a peg_revision, as it
+ * changed between @a start_revision and @a end_revision. @a path can
+ * be either a working-copy path or URL.
+ *
+ * Calls @a preview_func with @a preview_baton for each difference with
+ * a @c svn_diff_preview_t * structure describing the difference.
+ *
+ * See svn_client_diff_peg3 for a description of the other parameters.
+ *
+ * @since New in 1.3.
+ */
+svn_error_t *
+svn_client_diff_preview_peg (const char *path,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *start_revision,
+ const svn_opt_revision_t *end_revision,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t no_diff_deleted,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
 /** Merge changes from @a source1/@a revision1 to @a source2/@a revision2 into
  * the working-copy path @a target_wcpath.
  *
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h (revision 15310)
+++ subversion/include/svn_ra.h (working copy)
@@ -758,10 +758,31 @@
  * finishing the report, and may not perform any RA operations using
  * @a session from within the editing operations of @a diff_editor.
  *
+ * @a text_deltas instructs the driver of the @a diff_editor to enable
+ * the generation of text deltas.
+ *
  * Use @a pool for memory allocation.
  *
- * @since New in 1.2.
+ * @since New in 1.3.
  */
+svn_error_t *svn_ra_do_diff2 (svn_ra_session_t *session,
+ const svn_ra_reporter2_t **reporter,
+ void **report_baton,
+ svn_revnum_t revision,
+ const char *diff_target,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
+ const char *versus_url,
+ const svn_delta_editor_t *diff_editor,
+ void *diff_baton,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_ra_do_diff2(), but with @a text_deltas set to @c TRUE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.2 API.
+ */
 svn_error_t *svn_ra_do_diff (svn_ra_session_t *session,
                              const svn_ra_reporter2_t **reporter,
                              void **report_baton,
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c (revision 15310)
+++ subversion/libsvn_ra_local/ra_plugin.c (working copy)
@@ -697,6 +697,7 @@
                        const char *update_target,
                        svn_boolean_t recurse,
                        svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
                        const char *switch_url,
                        const svn_delta_editor_t *update_editor,
                        void *update_baton,
@@ -708,7 +709,7 @@
                         update_revision,
                         update_target,
                         switch_url,
- TRUE,
+ text_deltas,
                         recurse,
                         ignore_ancestry,
                         update_editor,
Index: subversion/libsvn_client/client.h
===================================================================
--- subversion/libsvn_client/client.h (revision 15310)
+++ subversion/libsvn_client/client.h (working copy)
@@ -400,6 +400,37 @@
 
 /* ---------------------------------------------------------------- */
 
+/*** Editor for diff preview ***/
+
+/* Create an editor for a repository diff preview, i.e. comparing one
+ * repository version against the other and only providing information
+ * about the changed items without the text delta.
+ *
+ * @preview_func is called with @a preview_baton as parameter by the
+ * created svn_delta_editor_t for each changed item.
+ *
+ * See svn_client__get_diff_editor for a description of the other
+ * parameters.
+ */
+svn_error_t *
+svn_client__get_diff_preview_editor (const char *target,
+ svn_wc_adm_access_t *adm_access,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_boolean_t recurse,
+ svn_boolean_t dry_run,
+ svn_ra_session_t *ra_session,
+ svn_revnum_t revision,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ const svn_delta_editor_t **editor,
+ void **edit_baton,
+ apr_pool_t *pool);
+
+/* ---------------------------------------------------------------- */
+
 /*** Commit Stuff ***/
 
 /* WARNING: This is all new, untested, un-peer-reviewed conceptual
Index: subversion/libsvn_client/diff.c
===================================================================
--- subversion/libsvn_client/diff.c (revision 15310)
+++ subversion/libsvn_client/diff.c (working copy)
@@ -1397,8 +1397,257 @@
   return SVN_NO_ERROR;
 }
 
+/** Helper structure: for passing around the diff parameters */
+struct diff_parameters
+{
+ /* first input path */
+ const char *path1;
 
+ /* revision of first input path */
+ const svn_opt_revision_t *revision1;
 
+ /* second input path */
+ const char *path2;
+
+ /* revision of second input path */
+ const svn_opt_revision_t *revision2;
+
+ /* peg revision */
+ const svn_opt_revision_t *peg_revision;
+
+ /* recurse */
+ svn_boolean_t recurse;
+
+ /* ignore acestry */
+ svn_boolean_t ignore_ancestry;
+
+ /* ignore deleted */
+ svn_boolean_t no_diff_deleted;
+};
+
+/** Helper structure: filled by svn_client_check_paths(_peg) */
+struct diff_paths
+{
+ /* revision1 is a local revision */
+ svn_boolean_t is_local_rev1;
+
+ /* revision2 is a local revision */
+ svn_boolean_t is_local_rev2;
+
+ /* path1 is a repos url */
+ svn_boolean_t is_repos_path1;
+
+ /* path2 is a repos url, not used by svn_client_check_paths_peg */
+ svn_boolean_t is_repos_path2;
+};
+
+
+/** check if paths are urls and if the revisions are local for a diff
+ * with two source paths or urls. Fills the @a paths structure. */
+static svn_error_t *
+svn_client_check_paths (const struct diff_parameters* params,
+ struct diff_paths* paths)
+{
+ /* Either path could be a URL or a working copy path. Let's figure
+ out what's what. */
+ paths->is_repos_path1 = svn_path_is_url (params->path1);
+ paths->is_repos_path2 = svn_path_is_url (params->path2);
+
+ /* Verify our revision arguments in light of the paths. */
+ if ((params->revision1->kind == svn_opt_revision_unspecified)
+ || (params->revision2->kind == svn_opt_revision_unspecified))
+ return svn_error_create (SVN_ERR_CLIENT_BAD_REVISION, NULL,
+ _("Not all required revisions are specified"));
+
+ /* Revisions can be said to be local or remote. BASE and WORKING,
+ for example, are local. */
+ paths->is_local_rev1 =
+ ((params->revision1->kind == svn_opt_revision_base)
+ || (params->revision1->kind == svn_opt_revision_working));
+ paths->is_local_rev2 =
+ ((params->revision2->kind == svn_opt_revision_base)
+ || (params->revision2->kind == svn_opt_revision_working));
+
+ /* Working copy paths with non-local revisions get turned into
+ URLs. We don't do that here, though. We simply record that it
+ needs to be done, which is information that helps us choose our
+ diff helper function. */
+ if ((! paths->is_repos_path1) && (! paths->is_local_rev1))
+ paths->is_repos_path1 = TRUE;
+ if ((! paths->is_repos_path2) && (! paths->is_local_rev2))
+ paths->is_repos_path2 = TRUE;
+
+ return SVN_NO_ERROR;
+}
+
+/** check if path is a url and if the revisions are local for a peg
+ * diff with a single source path or url. */
+static svn_error_t *
+svn_client_check_paths_peg (const struct diff_parameters* params,
+ struct diff_paths* paths)
+{
+ /* Either path could be a URL or a working copy path. Let's figure
+ out what's what. */
+ paths->is_repos_path1 = svn_path_is_url (params->path1);
+ paths->is_repos_path2 = FALSE;
+
+ /* Verify our revision arguments in light of the paths. */
+ if ((params->revision1->kind == svn_opt_revision_unspecified)
+ || (params->revision2->kind == svn_opt_revision_unspecified))
+ return svn_error_create (SVN_ERR_CLIENT_BAD_REVISION, NULL,
+ _("Not all required revisions are specified"));
+
+ /* Revisions can be said to be local or remote. BASE and WORKING,
+ for example, are local. */
+ paths->is_local_rev1 =
+ ((params->revision1->kind == svn_opt_revision_base)
+ || (params->revision1->kind == svn_opt_revision_working));
+ paths->is_local_rev2 =
+ ((params->revision2->kind == svn_opt_revision_base)
+ || (params->revision2->kind == svn_opt_revision_working));
+
+ if (paths->is_local_rev1 && paths->is_local_rev2)
+ return svn_error_create (SVN_ERR_CLIENT_BAD_REVISION, NULL,
+ _("At least one revision must be non-local for "
+ "a pegged diff"));
+ return SVN_NO_ERROR;
+}
+
+/** Helper structure filled by diff_prepare_repos_repos */
+struct diff_repos_repos
+{
+ /* url created from path1 */
+ const char *url1;
+
+ /* url created from path2 */
+ const char *url2;
+
+ /* the BASE_PATH for the diff */
+ const char *base_path;
+
+ /* url1 and url2 are the same */
+ svn_boolean_t same_urls;
+
+ /* revision of url1 */
+ svn_revnum_t rev1;
+
+ /* revision of url2 */
+ svn_revnum_t rev2;
+
+ /* anchor & target based on url1 */
+ const char *anchor1;
+ const char *target1;
+
+ /* anchor & target based on url2 */
+ const char *anchor2;
+ const char *target2;
+};
+
+/** Helper function: prepare a repos repos diff. Fills @a drr
+ * structure. */
+static svn_error_t *
+diff_prepare_repos_repos (const struct diff_parameters *params,
+ struct diff_repos_repos *drr,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ svn_ra_session_t *ra_session1, *ra_session2;
+ svn_node_kind_t kind1, kind2;
+
+ apr_pool_t *temppool = svn_pool_create (pool);
+
+ /* Figure out URL1 and URL2. */
+ SVN_ERR (convert_to_url (&drr->url1, params->path1, pool));
+ SVN_ERR (convert_to_url (&drr->url2, params->path2, pool));
+ drr->same_urls = (strcmp (drr->url1, drr->url2) == 0);
+
+ /* We need exactly one BASE_PATH, so we'll let the BASE_PATH
+ calculated for PATH2 override the one for PATH1 (since the diff
+ will be "applied" to URL2 anyway). */
+ drr->base_path = NULL;
+ if (drr->url1 != params->path1)
+ drr->base_path = params->path1;
+ if (drr->url2 != params->path2)
+ drr->base_path = params->path2;
+
+ /* If we are performing a pegged diff, we need to find out what our
+ actual URLs will be. */
+ if (params->peg_revision->kind != svn_opt_revision_unspecified)
+ {
+ svn_opt_revision_t *start_ignore, *end_ignore;
+
+ SVN_ERR (svn_client__repos_locations (&drr->url1, &start_ignore,
+ &drr->url2, &end_ignore,
+ params->path2,
+ params->peg_revision,
+ params->revision1,
+ params->revision2,
+ ctx, pool));
+
+ /* @todo copy info when called from diff_repos_repos */
+ /* callback_baton->orig_path_1 = url1; */
+ /* callback_baton->orig_path_2 = url2; */
+ }
+
+
+ /* Open temporary RA sessions to each URL. */
+ SVN_ERR (svn_client__open_ra_session_internal (&ra_session1,
+ drr->url1, NULL,
+ NULL, NULL, FALSE,
+ TRUE, ctx, temppool));
+ SVN_ERR (svn_client__open_ra_session_internal (&ra_session2,
+ drr->url2, NULL,
+ NULL, NULL, FALSE,
+ TRUE, ctx, temppool));
+
+ /* Resolve named revisions to real numbers. */
+ SVN_ERR (svn_client__get_revision_number
+ (&drr->rev1, ra_session1, params->revision1,
+ (params->path1 == drr->url1) ? NULL : params->path1, pool));
+ /* @todo copy info when called from diff_repos_repos */
+ /* callback_baton->revnum1 = rev1; */
+ SVN_ERR (svn_client__get_revision_number
+ (&drr->rev2, ra_session2, params->revision2,
+ (params->path2 == drr->url2) ? NULL : params->path2, pool));
+ /* @todo copy info when called from diff_repos_repos */
+ /* callback_baton->revnum2 = rev2; */
+
+ /* Choose useful anchors and targets for our two URLs, and verify
+ that both sides of the diff exist. */
+ drr->anchor1 = drr->url1;
+ drr->anchor2 = drr->url2;
+ drr->target1 = "";
+ drr->target2 = "";
+ SVN_ERR (svn_ra_check_path (ra_session1, "", drr->rev1, &kind1,
+ temppool));
+ SVN_ERR (svn_ra_check_path (ra_session2, "", drr->rev2, &kind2,
+ temppool));
+ if (kind1 == svn_node_none)
+ return svn_error_createf
+ (SVN_ERR_FS_NOT_FOUND, NULL,
+ _("'%s' was not found in the repository at revision %ld"),
+ drr->url1, drr->rev1);
+ if (kind2 == svn_node_none)
+ return svn_error_createf
+ (SVN_ERR_FS_NOT_FOUND, NULL,
+ _("'%s' was not found in the repository at revision %ld"),
+ drr->url2, drr->rev2);
+ if ((kind1 == svn_node_file) || (kind2 == svn_node_file))
+ {
+ svn_path_split (drr->url1, &drr->anchor1, &drr->target1, pool);
+ drr->target1 = svn_path_uri_decode (drr->target1, pool);
+ svn_path_split (drr->url2, &drr->anchor2, &drr->target2, pool);
+ drr->target2 = svn_path_uri_decode (drr->target2, pool);
+ if (drr->base_path)
+ drr->base_path = svn_path_dirname (drr->base_path, pool);
+ }
+
+ /* Destroy the temporary pool, which closes our RA session. */
+ svn_pool_destroy (temppool);
+
+ return SVN_NO_ERROR;
+}
+
 /* URL1/PATH1, URL2/PATH2, and TARGET_WCPATH all better be
    directories. For the single file case, the caller does the merging
    manually. PATH1 and PATH2 can be NULL.
@@ -2215,7 +2464,170 @@
   return SVN_NO_ERROR;
 }
 
+/* Perform a diff preview between two repository paths. */
+static svn_error_t *
+diff_preview_repos_repos (const struct diff_parameters* diff_param,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ svn_ra_session_t *ra_session1, *ra_session2;
 
+ const svn_ra_reporter2_t *reporter;
+ void *report_baton;
+
+ const svn_delta_editor_t *diff_editor;
+ void *diff_edit_baton;
+
+ struct diff_repos_repos drr;
+
+ /* prepare info for the repos repos diff */
+ SVN_ERR (diff_prepare_repos_repos (diff_param, &drr, ctx, pool ));
+
+ /* Now, we reopen two RA session to the correct anchor/target
+ locations for our URLs. */
+ SVN_ERR (svn_client__open_ra_session_internal (&ra_session1,
+ drr.anchor1,
+ NULL, NULL, NULL,
+ FALSE, TRUE,
+ ctx, pool));
+ SVN_ERR (svn_client__open_ra_session_internal (&ra_session2,
+ drr.anchor1,
+ NULL, NULL, NULL,
+ FALSE, TRUE,
+ ctx, pool));
+
+ /* Set up the repos_diff editor on BASE_PATH, if available.
+ Otherwise, we just use "". */
+ SVN_ERR (svn_client__get_diff_preview_editor (drr.base_path ?
+ drr.base_path : "",
+ NULL,
+ preview_func,
+ preview_baton,
+ diff_param->recurse,
+ /* doesn't matter for diff */ FALSE,
+ ra_session2,
+ drr.rev1,
+ /* no notify_func */ NULL,
+ /* no notify_baton */ NULL,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ &diff_editor,
+ &diff_edit_baton,
+ pool));
+
+ /* We want to switch our txn into URL2 */
+ SVN_ERR (svn_ra_do_diff2 (ra_session1,
+ &reporter, &report_baton,
+ drr.rev2, drr.target1,
+ diff_param->recurse,
+ diff_param->ignore_ancestry,
+ FALSE, /* do not create text delta */
+ drr.url2,
+ diff_editor, diff_edit_baton,
+ pool));
+
+ /* Drive the reporter; do the diff. */
+ SVN_ERR (reporter->set_path (report_baton, "", drr.rev1, FALSE, NULL,
+ pool));
+ SVN_ERR (reporter->finish_report (report_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* This is basically just the guts of svn_client_diff_preview(). */
+static svn_error_t *
+do_diff_preview (const struct diff_parameters* diff_param,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ struct diff_paths diff_paths;
+
+ /* Check if paths/revisions are urls/local. */
+ svn_client_check_paths(diff_param, &diff_paths);
+
+ if (diff_paths.is_repos_path1) /* path1 is (effectively) a URL */
+ {
+ if (diff_paths.is_repos_path2) /* path2 is (effectively) a URL */
+ {
+ SVN_ERR (diff_preview_repos_repos (diff_param, preview_func,
+ preview_baton, ctx, pool));
+ }
+ else /* path2 is a working copy path */
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ }
+ else /* path1 is a working copy path */
+ {
+ if (diff_paths.is_repos_path2) /* path2 is (effectively) a URL */
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ else /* path2 is a working copy path */
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* This is basically just the guts of svn_client_diff_preview_peg(). */
+static svn_error_t *
+do_diff_preview_peg (const struct diff_parameters* diff_param,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ struct diff_paths diff_paths;
+
+ /* Check if paths/revisions are urls/local. */
+ svn_client_check_paths_peg(diff_param, &diff_paths);
+
+ if (! diff_paths.is_local_rev1) /* path1 is (effectively) a URL */
+ {
+ if (! diff_paths.is_local_rev2) /* path2 is (effectively) a URL */
+ {
+ SVN_ERR (diff_preview_repos_repos (diff_param, preview_func,
+ preview_baton, ctx, pool));
+ }
+ else /* path2 is a working copy path */
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ }
+ else /* path1 is a working copy path */
+ {
+ if (! diff_paths.is_local_rev2) /* path2 is (effectively) a URL */
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ else
+ {
+ /* @todo */
+ return svn_error_create (SVN_ERR_UNSUPPORTED_FEATURE,
+ NULL, NULL);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
 /*----------------------------------------------------------------------- */
 
 /*** Public Interfaces. ***/
@@ -2448,6 +2860,69 @@
 }
 
 svn_error_t *
+svn_client_diff_preview (const char *path1,
+ const svn_opt_revision_t *revision1,
+ const char *path2,
+ const svn_opt_revision_t *revision2,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t no_diff_deleted,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ struct diff_parameters diff_params;
+
+ /* We will never do a pegged diff from here. */
+ svn_opt_revision_t* peg_revision = apr_palloc (pool,
+ sizeof(*peg_revision));
+ peg_revision->kind = svn_opt_revision_unspecified;
+
+ /* fill diff_param */
+ diff_params.path1 = path1;
+ diff_params.revision1 = revision1;
+ diff_params.path2 = path2;
+ diff_params.revision2 = revision2;
+ diff_params.peg_revision = peg_revision;
+ diff_params.recurse = recurse;
+ diff_params.ignore_ancestry = ignore_ancestry;
+ diff_params.no_diff_deleted = no_diff_deleted;
+
+ return do_diff_preview (&diff_params, preview_func, preview_baton,
+ ctx, pool);
+}
+
+svn_error_t *
+svn_client_diff_preview_peg (const char *path,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *start_revision,
+ const svn_opt_revision_t *end_revision,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ svn_boolean_t no_diff_deleted,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ struct diff_parameters diff_params;
+
+ /* fill diff_param */
+ diff_params.path1 = path;
+ diff_params.revision1 = start_revision;
+ diff_params.path2 = path;
+ diff_params.revision2 = end_revision;
+ diff_params.peg_revision = peg_revision;
+ diff_params.recurse = recurse;
+ diff_params.ignore_ancestry = ignore_ancestry;
+ diff_params.no_diff_deleted = no_diff_deleted;
+
+ return do_diff_preview_peg (&diff_params, preview_func, preview_baton,
+ ctx, pool);
+}
+
+svn_error_t *
 svn_client_merge (const char *source1,
                   const svn_opt_revision_t *revision1,
                   const char *source2,
Index: subversion/libsvn_client/repos_diff_preview.c
===================================================================
--- subversion/libsvn_client/repos_diff_preview.c (revision 0)
+++ subversion/libsvn_client/repos_diff_preview.c (revision 0)
@@ -0,0 +1,418 @@
+/*
+ * repos_diff_preview.c -- The diff preview editor for previewing the
+ * differences of two repository versions
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+
+#include "svn_wc.h"
+#include "svn_props.h"
+#include "svn_pools.h"
+
+#include "client.h"
+
+
+/* Overall crawler editor baton. */
+struct preview_edit_baton {
+
+ /* The preview callback passed down from the api */
+ svn_diff_preview_func_t preview_func;
+
+ /* The preview callback baton */
+ void *preview_baton;
+};
+
+
+/* Directory level baton.
+ */
+struct preview_dir_baton {
+
+ /* the overall crawler editor baton */
+ struct preview_edit_baton *edit_baton;
+
+ /* the preview filled by the editor calls */
+ svn_diff_preview_t *preview;
+
+ /* The path of the directory within the repository */
+ const char *path;
+};
+
+
+/* File level baton.
+ */
+struct preview_file_baton {
+
+ /* the overall crawler editor baton */
+ struct preview_edit_baton *edit_baton;
+
+ /* the preview filled by the editor calls */
+ svn_diff_preview_t *preview;
+
+ /* The path of the file within the repository */
+ const char *path;
+};
+
+
+/* An editor function. The root of the comparison hierarchy */
+static svn_error_t *
+set_target_revision (void *edit_baton,
+ svn_revnum_t target_revision,
+ apr_pool_t *pool)
+{
+ struct preview_edit_baton *eb = edit_baton;
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. The root of the comparison hierarchy */
+static svn_error_t *
+open_root (void *edit_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *pool,
+ void **root_baton)
+{
+ struct preview_edit_baton *eb = edit_baton;
+ struct preview_dir_baton *db = apr_pcalloc (pool, sizeof (*db));
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ diff->node_kind = svn_node_dir;
+ diff->preview_kind = svn_diff_preview_kind_unchanged;
+ diff->path_old = 0;
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ db->edit_baton = eb;
+ db->preview = diff;
+ db->path = 0;
+
+ *root_baton = db;
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+delete_entry (const char *path,
+ svn_revnum_t base_revision,
+ void *parent_baton,
+ apr_pool_t *pool)
+{
+ struct preview_dir_baton *pb = parent_baton;
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ diff->node_kind = svn_node_file;
+ diff->preview_kind = svn_diff_preview_kind_deleted;
+ diff->path_old = apr_pstrdup (pool, path);
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ pb->edit_baton->preview_func (pb->edit_baton->preview_baton,diff);
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+add_directory (const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *pool,
+ void **child_baton)
+{
+ struct preview_dir_baton *pb = parent_baton;
+ struct preview_dir_baton *db = apr_pcalloc (pool, sizeof (*db));
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ db->edit_baton = pb->edit_baton;
+ db->preview = diff;
+ db->path = apr_pstrdup (pool, path);
+
+ diff->node_kind = svn_node_dir;
+ diff->preview_kind = svn_diff_preview_kind_added;
+ diff->path_old = apr_pstrdup (pool, path);
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ *child_baton = db;
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+open_directory (const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *pool,
+ void **child_baton)
+{
+ struct preview_dir_baton *pb = parent_baton;
+ struct preview_dir_baton *db = apr_pcalloc (pool, sizeof (*db));
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ db->edit_baton = pb->edit_baton;
+ db->preview = diff;
+ db->path = apr_pstrdup (pool, path);
+
+ diff->node_kind = svn_node_dir;
+ diff->preview_kind = svn_diff_preview_kind_unchanged;
+ diff->path_old = apr_pstrdup (pool, path);
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ *child_baton = db;
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+change_dir_prop (void *dir_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *pool)
+{
+ struct preview_dir_baton *pb = dir_baton;
+
+ if ( svn_property_kind (NULL,name) == svn_prop_regular_kind )
+ {
+ pb->preview->props_changed = TRUE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+close_directory (void *dir_baton,
+ apr_pool_t *pool)
+{
+ struct preview_dir_baton *db = dir_baton;
+
+ if (db->preview->path_old // ignore empty root
+ && (db->preview->preview_kind != svn_diff_preview_kind_unchanged
+ || db->preview->props_changed == TRUE))
+ {
+ db->edit_baton->preview_func (db->edit_baton->preview_baton,db->preview);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+absent_directory (const char *path,
+ void *parent_baton,
+ apr_pool_t *pool)
+{
+ struct preview_dir_baton *pb = parent_baton;
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+add_file (const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *pool,
+ void **file_baton)
+{
+ struct preview_dir_baton *pb = parent_baton;
+ struct preview_file_baton *fb = apr_pcalloc (pool, sizeof (*fb));
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ fb->edit_baton = pb->edit_baton;
+ fb->preview = diff;
+ fb->path = apr_pstrdup (pool, path);
+
+ diff->node_kind = svn_node_file;
+ diff->preview_kind = svn_diff_preview_kind_added;
+ diff->path_old = apr_pstrdup (pool, path);
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ *file_baton = fb;
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+open_file (const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *pool,
+ void **file_baton)
+{
+ struct preview_dir_baton *pb = parent_baton;
+ struct preview_file_baton *fb = apr_pcalloc (pool, sizeof (*fb));
+ svn_diff_preview_t *diff = apr_pcalloc (pool, sizeof (*diff));
+
+ fb->edit_baton = pb->edit_baton;
+ fb->preview = diff;
+ fb->path = apr_pstrdup (pool, path);
+
+ diff->node_kind = svn_node_file;
+ diff->preview_kind = svn_diff_preview_kind_modified;
+ diff->path_old = apr_pstrdup (pool, path);
+ diff->path_new = 0;
+ diff->props_changed = FALSE;
+ diff->mimetype_new = 0;
+ diff->mimetype_old = 0;
+
+ *file_baton = fb;
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. Do the work of applying the text delta. */
+static svn_error_t *
+window_handler (svn_txdelta_window_t *window,
+ void *window_baton)
+{
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+apply_textdelta (void *file_baton,
+ const char *base_checksum,
+ apr_pool_t *pool,
+ svn_txdelta_window_handler_t *handler,
+ void **handler_baton)
+{
+ *handler = svn_delta_noop_window_handler;
+ *handler_baton = NULL;
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+change_file_prop (void *file_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *pool)
+{
+ struct preview_file_baton *fb = file_baton;
+
+ if ( svn_property_kind (NULL,name) == svn_prop_regular_kind )
+ {
+ fb->preview->props_changed = TRUE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+close_file (void *file_baton,
+ const char *text_checksum,
+ apr_pool_t *pool)
+{
+ struct preview_file_baton *fb = file_baton;
+
+ fb->edit_baton->preview_func (fb->edit_baton->preview_baton,fb->preview);
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+absent_file (const char *path,
+ void *parent_baton,
+ apr_pool_t *pool)
+{
+ struct preview_dir_baton *pb = parent_baton;
+
+ return SVN_NO_ERROR;
+}
+
+/* An editor function. */
+static svn_error_t *
+close_edit (void *edit_baton,
+ apr_pool_t *pool)
+{
+ return SVN_NO_ERROR;
+}
+
+
+
+/* Create a repository diff preview editor and baton. */
+svn_error_t *
+svn_client__get_diff_preview_editor (const char *target,
+ svn_wc_adm_access_t *adm_access,
+ svn_diff_preview_func_t preview_func,
+ void *preview_baton,
+ svn_boolean_t recurse,
+ svn_boolean_t dry_run,
+ svn_ra_session_t *ra_session,
+ svn_revnum_t revision,
+ svn_wc_notify_func2_t notify_func,
+ void *notify_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ const svn_delta_editor_t **editor,
+ void **edit_baton,
+ apr_pool_t *pool)
+{
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ svn_delta_editor_t *tree_editor = svn_delta_default_editor (subpool);
+ struct preview_edit_baton *eb = apr_palloc (subpool, sizeof (*eb));
+
+ eb->preview_func = preview_func;
+ eb->preview_baton = preview_baton;
+ //eb->revision = revision;
+ //eb->target_revision = SVN_INVALID_REVNUM;
+
+ tree_editor->set_target_revision = set_target_revision;
+ tree_editor->open_root = open_root;
+
+ tree_editor->delete_entry = delete_entry;
+ tree_editor->add_directory = add_directory;
+ tree_editor->open_directory = open_directory;
+ tree_editor->change_dir_prop = change_dir_prop;
+ tree_editor->close_directory = close_directory;
+ tree_editor->absent_directory = absent_directory;
+
+ tree_editor->add_file = add_file;
+ tree_editor->open_file = open_file;
+ tree_editor->apply_textdelta = apply_textdelta;
+ tree_editor->change_file_prop = change_file_prop;
+ tree_editor->close_file = close_file;
+ tree_editor->absent_file = absent_file;
+
+ tree_editor->close_edit = close_edit;
+
+ SVN_ERR (svn_delta_get_cancellation_editor (cancel_func,
+ cancel_baton,
+ tree_editor,
+ eb,
+ editor,
+ edit_baton,
+ pool));
+
+ return SVN_NO_ERROR;
+}
Index: subversion/libsvn_ra_svn/client.c
===================================================================
--- subversion/libsvn_ra_svn/client.c (revision 15310)
+++ subversion/libsvn_ra_svn/client.c (working copy)
@@ -1050,6 +1050,7 @@
                                 svn_revnum_t rev, const char *target,
                                 svn_boolean_t recurse,
                                 svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
                                 const char *versus_url,
                                 const svn_delta_editor_t *diff_editor,
                                 void *diff_baton, apr_pool_t *pool)
@@ -1058,8 +1059,9 @@
   svn_ra_svn_conn_t *conn = sess_baton->conn;
 
   /* Tell the server we want to start a diff. */
- SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "diff", "(?r)cbbc", rev, target,
- recurse, ignore_ancestry, versus_url));
+ SVN_ERR(svn_ra_svn_write_cmd(conn, pool, "diff", "(?r)cbbcb", rev,
+ target, recurse, ignore_ancestry,
+ versus_url, text_deltas));
   SVN_ERR(handle_auth_request(sess_baton, pool));
 
   /* Fetch a reporter for the caller to drive. The reporter will drive
Index: subversion/libsvn_ra_svn/marshal.c
===================================================================
--- subversion/libsvn_ra_svn/marshal.c (revision 15310)
+++ subversion/libsvn_ra_svn/marshal.c (working copy)
@@ -691,6 +691,11 @@
             case 'n':
               *va_arg(*ap, apr_uint64_t *) = SVN_RA_SVN_UNSPECIFIED_NUMBER;
               break;
+#if 0
+ case 'b':
+ *va_arg(*ap, svn_boolean_t *) = TRUE;
+ break;
+#endif
             case '(':
               list_level++;
               break;
Index: subversion/libsvn_ra_dav/ra_dav.h
===================================================================
--- subversion/libsvn_ra_dav/ra_dav.h (revision 15310)
+++ subversion/libsvn_ra_dav/ra_dav.h (working copy)
@@ -290,6 +290,7 @@
   const char *diff_target,
   svn_boolean_t recurse,
   svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
   const char *versus_url,
   const svn_delta_editor_t *wc_diff,
   void *wc_diff_baton,
Index: subversion/libsvn_ra_dav/fetch.c
===================================================================
--- subversion/libsvn_ra_dav/fetch.c (revision 15310)
+++ subversion/libsvn_ra_dav/fetch.c (working copy)
@@ -3187,6 +3187,7 @@
                                   const char *diff_target,
                                   svn_boolean_t recurse,
                                   svn_boolean_t ignore_ancestry,
+ svn_boolean_t text_deltas,
                                   const char *versus_url,
                                   const svn_delta_editor_t *wc_diff,
                                   void *wc_diff_baton,
@@ -3203,7 +3204,7 @@
                         FALSE,
                         wc_diff,
                         wc_diff_baton,
- TRUE, /* fetch_content */
+ text_deltas, /* fetch_content */
                         FALSE, /* send_all */
                         TRUE, /* spool_response */
                         pool);
Index: subversion/svnserve/serve.c
===================================================================
--- subversion/svnserve/serve.c (revision 15310)
+++ subversion/svnserve/serve.c (working copy)
@@ -1034,11 +1034,12 @@
   server_baton_t *b = baton;
   svn_revnum_t rev;
   const char *target, *versus_url, *versus_path;
- svn_boolean_t recurse, ignore_ancestry;
+ svn_boolean_t recurse, ignore_ancestry, text_deltas;
 
   /* Parse the arguments. */
- SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "(?r)cbbc", &rev, &target,
- &recurse, &ignore_ancestry, &versus_url));
+ SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "(?r)cbbc?b", &rev, &target,
+ &recurse, &ignore_ancestry, &versus_url,
+ &text_deltas));
   target = svn_path_canonicalize(target, pool);
   versus_url = svn_path_canonicalize(versus_url, pool);
   SVN_ERR(trivial_auth_request(conn, pool, b));
@@ -1048,8 +1049,8 @@
                           svn_path_uri_decode(versus_url, pool),
                           &versus_path, pool));
 
- return accept_report(conn, pool, b, rev, target, versus_path, TRUE, recurse,
- ignore_ancestry);
+ return accept_report(conn, pool, b, rev, target, versus_path,
+ text_deltas, recurse, ignore_ancestry);
 }
 
 /* Send a log entry to the client. */

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Jul 12 22:13:52 2005

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

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