You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2014/02/19 22:55:34 UTC
svn commit: r1569937 - /subversion/trunk/subversion/libsvn_client/diff.c
Author: rhuijben
Date: Wed Feb 19 21:55:34 2014
New Revision: 1569937
URL: http://svn.apache.org/r1569937
Log:
In the libsvn_client diff code: separate the diff driver generated state
from the diff writer/output state.
* subversion/libsvn_client/diff.c
(make_repos_relpath): Replace ra_session argument with just the required
value as a diff writer shouldn't need access to the network layer.
(display_prop_diffs): Update forwarded arguments for make_repos_relpath.
(diff_driver_info_t): New baton, extracted from diff_cmd_baton.
(diff_cmd_baton): Rename to...
(diff_writer_info_t): ... this. Extract some fields to an inner struct
of type diff_driver_info_t.
(diff_props_changed,
diff_dir_props_changed,
diff_content_changed,
diff_file_changed,
diff_file_added,
diff_file_deleted): Update caller.
(diff_wc_wc,
diff_repos_repos,
diff_repos_wc): Optionally fill an diff_driver_info_t instance
instead of passing the whole baton.
(do_diff,
do_diff_summarize): Update caller.
(set_up_diff_cmd_and_options): Rename to...
(create_diff_writer_info): ... this.
(svn_client_diff6,
svn_client_diff_peg6): Update caller.
Modified:
subversion/trunk/subversion/libsvn_client/diff.c
Modified: subversion/trunk/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/diff.c?rev=1569937&r1=1569936&r2=1569937&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/diff.c (original)
+++ subversion/trunk/subversion/libsvn_client/diff.c Wed Feb 19 21:55:34 2014
@@ -64,8 +64,8 @@
_("Path '%s' must be an immediate child of " \
"the directory '%s'"), path, relative_to_dir)
-/* Calculate the repository relative path of DIFF_RELPATH, using RA_SESSION
- * and WC_CTX, and return the result in *REPOS_RELPATH.
+/* Calculate the repository relative path of DIFF_RELPATH, using
+ * SESSION_RELPATH and WC_CTX, and return the result in *REPOS_RELPATH.
* ORIG_TARGET is the related original target passed to the diff command,
* and may be used to derive leading path components missing from PATH.
* ANCHOR is the local path where the diff editor is anchored.
@@ -74,16 +74,15 @@ static svn_error_t *
make_repos_relpath(const char **repos_relpath,
const char *diff_relpath,
const char *orig_target,
- svn_ra_session_t *ra_session,
+ const char *session_relpath,
svn_wc_context_t *wc_ctx,
const char *anchor,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
const char *local_abspath;
- const char *orig_repos_relpath = NULL;
- if (! ra_session
+ if (! session_relpath
|| (anchor && !svn_path_is_url(orig_target)))
{
svn_error_t *err;
@@ -98,7 +97,7 @@ make_repos_relpath(const char **repos_re
wc_ctx, local_abspath,
result_pool, scratch_pool);
- if (!ra_session
+ if (!session_relpath
|| ! err
|| (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND))
{
@@ -113,23 +112,8 @@ make_repos_relpath(const char **repos_re
svn_error_clear(err);
}
- {
- const char *url;
- const char *repos_root_url;
-
- /* Would be nice if the RA layer could just provide the parent
- repos_relpath of the ra session */
- SVN_ERR(svn_ra_get_session_url(ra_session, &url, scratch_pool));
-
- SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
- scratch_pool));
-
- orig_repos_relpath = svn_uri_skip_ancestor(repos_root_url, url,
- scratch_pool);
-
- *repos_relpath = svn_relpath_join(orig_repos_relpath, diff_relpath,
- result_pool);
- }
+ *repos_relpath = svn_relpath_join(session_relpath, diff_relpath,
+ result_pool);
return SVN_NO_ERROR;
}
@@ -452,7 +436,7 @@ display_prop_diffs(const apr_array_heade
const char *relative_to_dir,
svn_boolean_t show_diff_header,
svn_boolean_t use_git_diff_format,
- svn_ra_session_t *ra_session,
+ const char *ra_session_relpath,
svn_wc_context_t *wc_ctx,
apr_pool_t *scratch_pool)
{
@@ -465,10 +449,10 @@ display_prop_diffs(const apr_array_heade
if (use_git_diff_format)
{
SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath, orig_path1,
- ra_session, wc_ctx, anchor,
+ ra_session_relpath, wc_ctx, anchor,
scratch_pool, scratch_pool));
SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath, orig_path2,
- ra_session, wc_ctx, anchor,
+ ra_session_relpath, wc_ctx, anchor,
scratch_pool, scratch_pool));
}
@@ -530,9 +514,42 @@ display_prop_diffs(const apr_array_heade
/*** Callbacks for 'svn diff', invoked by the repos-diff editor. ***/
+/* State provided by the diff drivers; used by the diff writer */
+typedef struct diff_driver_info_t
+{
+ /* The anchor to prefix before wc paths */
+ const char *anchor;
+ const char *anchor_url;
+
+ /* Relative path of ra session from repos_root_url */
+ const char *session_relpath;
-struct diff_cmd_baton {
+ /* The original targets passed to the diff command. We may need
+ these to construct distinctive diff labels when comparing the
+ same relative path in the same revision, under different anchors
+ (for example, when comparing a trunk against a branch). */
+ const char *orig_path_1;
+ const char *orig_path_2;
+
+ /* Whether the local diff target of a repos->wc diff is a copy. */
+ svn_boolean_t repos_wc_diff_target_is_copy;
+ /* These are the numeric representations of the revisions passed to
+ svn_client_diff6(), either may be SVN_INVALID_REVNUM. We need these
+ because some of the svn_wc_diff_callbacks4_t don't get revision
+ arguments.
+
+ ### Perhaps we should change the callback signatures and eliminate
+ ### these? (### Done in the diff processor)
+ */
+ svn_revnum_t revnum1;
+ svn_revnum_t revnum2;
+} diff_driver_info_t;
+
+
+/* Diff writer state */
+typedef struct diff_writer_info_t
+{
/* If non-null, the external diff command to invoke. */
const char *diff_cmd;
@@ -556,24 +573,6 @@ struct diff_cmd_baton {
const char *header_encoding;
- /* The original targets passed to the diff command. We may need
- these to construct distinctive diff labels when comparing the
- same relative path in the same revision, under different anchors
- (for example, when comparing a trunk against a branch). */
- const char *orig_path_1;
- const char *orig_path_2;
-
- /* These are the numeric representations of the revisions passed to
- svn_client_diff6(), either may be SVN_INVALID_REVNUM. We need these
- because some of the svn_wc_diff_callbacks4_t don't get revision
- arguments.
-
- ### Perhaps we should change the callback signatures and eliminate
- ### these?
- */
- svn_revnum_t revnum1;
- svn_revnum_t revnum2;
-
/* Set this if you want diff output even for binary files. */
svn_boolean_t force_binary;
@@ -604,15 +603,8 @@ struct diff_cmd_baton {
svn_wc_context_t *wc_ctx;
- /* The RA session used during diffs involving the repository. */
- svn_ra_session_t *ra_session;
-
- /* The anchor to prefix before wc paths */
- const char *anchor;
-
- /* Whether the local diff target of a repos->wc diff is a copy. */
- svn_boolean_t repos_wc_diff_target_is_copy;
-};
+ struct diff_driver_info_t ddi;
+} diff_writer_info_t;
/* An helper for diff_dir_props_changed, diff_file_changed and diff_file_added
*/
@@ -624,7 +616,7 @@ diff_props_changed(const char *diff_relp
const apr_array_header_t *propchanges,
apr_hash_t *original_props,
svn_boolean_t show_diff_header,
- struct diff_cmd_baton *diff_cmd_baton,
+ diff_writer_info_t *diff_cmd_baton,
apr_pool_t *scratch_pool)
{
apr_array_header_t *props;
@@ -643,9 +635,9 @@ diff_props_changed(const char *diff_relp
* dir_props_changed(). */
SVN_ERR(display_prop_diffs(props, original_props,
diff_relpath,
- diff_cmd_baton->anchor,
- diff_cmd_baton->orig_path_1,
- diff_cmd_baton->orig_path_2,
+ diff_cmd_baton->ddi.anchor,
+ diff_cmd_baton->ddi.orig_path_1,
+ diff_cmd_baton->ddi.orig_path_2,
rev1,
rev2,
diff_cmd_baton->header_encoding,
@@ -653,7 +645,7 @@ diff_props_changed(const char *diff_relp
diff_cmd_baton->relative_to_dir,
show_diff_header,
diff_cmd_baton->use_git_diff_format,
- diff_cmd_baton->ra_session,
+ diff_cmd_baton->ddi.session_relpath,
diff_cmd_baton->wc_ctx,
scratch_pool));
}
@@ -672,15 +664,15 @@ diff_dir_props_changed(svn_wc_notify_sta
void *diff_baton,
apr_pool_t *scratch_pool)
{
- struct diff_cmd_baton *diff_cmd_baton = diff_baton;
+ diff_writer_info_t *diff_cmd_baton = diff_baton;
return svn_error_trace(diff_props_changed(diff_relpath,
/* ### These revs be filled
* ### with per node info */
dir_was_added
? 0 /* Magic legacy value */
- : diff_cmd_baton->revnum1,
- diff_cmd_baton->revnum2,
+ : diff_cmd_baton->ddi.revnum1,
+ diff_cmd_baton->ddi.revnum2,
dir_was_added,
propchanges,
original_props,
@@ -711,7 +703,7 @@ diff_content_changed(svn_boolean_t *wrot
svn_boolean_t force_diff,
const char *copyfrom_path,
svn_revnum_t copyfrom_rev,
- struct diff_cmd_baton *diff_cmd_baton,
+ diff_writer_info_t *diff_cmd_baton,
apr_pool_t *scratch_pool)
{
int exitcode;
@@ -721,8 +713,8 @@ diff_content_changed(svn_boolean_t *wrot
const char *label1, *label2;
svn_boolean_t mt1_binary = FALSE, mt2_binary = FALSE;
const char *index_path = diff_relpath;
- const char *path1 = diff_cmd_baton->orig_path_1;
- const char *path2 = diff_cmd_baton->orig_path_2;
+ const char *path1 = diff_cmd_baton->ddi.orig_path_1;
+ const char *path2 = diff_cmd_baton->ddi.orig_path_2;
/* If only property differences are shown, there's nothing to do. */
if (diff_cmd_baton->properties_only)
@@ -730,7 +722,7 @@ diff_content_changed(svn_boolean_t *wrot
/* Generate the diff headers. */
SVN_ERR(adjust_paths_for_diff_labels(&index_path, &path1, &path2,
- rel_to_dir, diff_cmd_baton->anchor,
+ rel_to_dir, diff_cmd_baton->ddi.anchor,
scratch_pool, scratch_pool));
label1 = diff_label(path1, rev1, scratch_pool);
@@ -881,16 +873,16 @@ diff_content_changed(svn_boolean_t *wrot
const char *repos_relpath1;
const char *repos_relpath2;
SVN_ERR(make_repos_relpath(&repos_relpath1, diff_relpath,
- diff_cmd_baton->orig_path_1,
- diff_cmd_baton->ra_session,
+ diff_cmd_baton->ddi.orig_path_1,
+ diff_cmd_baton->ddi.session_relpath,
diff_cmd_baton->wc_ctx,
- diff_cmd_baton->anchor,
+ diff_cmd_baton->ddi.anchor,
scratch_pool, scratch_pool));
SVN_ERR(make_repos_relpath(&repos_relpath2, diff_relpath,
- diff_cmd_baton->orig_path_2,
- diff_cmd_baton->ra_session,
+ diff_cmd_baton->ddi.orig_path_2,
+ diff_cmd_baton->ddi.session_relpath,
diff_cmd_baton->wc_ctx,
- diff_cmd_baton->anchor,
+ diff_cmd_baton->ddi.anchor,
scratch_pool, scratch_pool));
SVN_ERR(print_git_diff_header(outstream, &label1, &label2,
operation,
@@ -950,20 +942,20 @@ diff_file_changed(svn_wc_notify_state_t
void *diff_baton,
apr_pool_t *scratch_pool)
{
- struct diff_cmd_baton *diff_cmd_baton = diff_baton;
+ diff_writer_info_t *diff_cmd_baton = diff_baton;
svn_boolean_t wrote_header = FALSE;
/* During repos->wc diff of a copy revision numbers obtained
* from the working copy are always SVN_INVALID_REVNUM. */
- if (diff_cmd_baton->repos_wc_diff_target_is_copy)
+ if (diff_cmd_baton->ddi.repos_wc_diff_target_is_copy)
{
if (rev1 == SVN_INVALID_REVNUM &&
- diff_cmd_baton->revnum1 != SVN_INVALID_REVNUM)
- rev1 = diff_cmd_baton->revnum1;
+ diff_cmd_baton->ddi.revnum1 != SVN_INVALID_REVNUM)
+ rev1 = diff_cmd_baton->ddi.revnum1;
if (rev2 == SVN_INVALID_REVNUM &&
- diff_cmd_baton->revnum2 != SVN_INVALID_REVNUM)
- rev2 = diff_cmd_baton->revnum2;
+ diff_cmd_baton->ddi.revnum2 != SVN_INVALID_REVNUM)
+ rev2 = diff_cmd_baton->ddi.revnum2;
}
if (tmpfile1)
@@ -1004,20 +996,20 @@ diff_file_added(svn_wc_notify_state_t *c
void *diff_baton,
apr_pool_t *scratch_pool)
{
- struct diff_cmd_baton *diff_cmd_baton = diff_baton;
+ diff_writer_info_t *diff_cmd_baton = diff_baton;
svn_boolean_t wrote_header = FALSE;
/* During repos->wc diff of a copy revision numbers obtained
* from the working copy are always SVN_INVALID_REVNUM. */
- if (diff_cmd_baton->repos_wc_diff_target_is_copy)
+ if (diff_cmd_baton->ddi.repos_wc_diff_target_is_copy)
{
if (rev1 == SVN_INVALID_REVNUM &&
- diff_cmd_baton->revnum1 != SVN_INVALID_REVNUM)
- rev1 = diff_cmd_baton->revnum1;
+ diff_cmd_baton->ddi.revnum1 != SVN_INVALID_REVNUM)
+ rev1 = diff_cmd_baton->ddi.revnum1;
if (rev2 == SVN_INVALID_REVNUM &&
- diff_cmd_baton->revnum2 != SVN_INVALID_REVNUM)
- rev2 = diff_cmd_baton->revnum2;
+ diff_cmd_baton->ddi.revnum2 != SVN_INVALID_REVNUM)
+ rev2 = diff_cmd_baton->ddi.revnum2;
}
if (diff_cmd_baton->no_copyfrom_on_add
@@ -1048,8 +1040,8 @@ diff_file_added(svn_wc_notify_state_t *c
{
const char *index_path = diff_relpath;
- if (diff_cmd_baton->anchor)
- index_path = svn_dirent_join(diff_cmd_baton->anchor, diff_relpath,
+ if (diff_cmd_baton->ddi.anchor)
+ index_path = svn_dirent_join(diff_cmd_baton->ddi.anchor, diff_relpath,
scratch_pool);
SVN_ERR(svn_stream_printf_from_utf8(diff_cmd_baton->outstream,
@@ -1099,14 +1091,14 @@ diff_file_deleted(svn_wc_notify_state_t
void *diff_baton,
apr_pool_t *scratch_pool)
{
- struct diff_cmd_baton *diff_cmd_baton = diff_baton;
+ diff_writer_info_t *diff_cmd_baton = diff_baton;
if (diff_cmd_baton->no_diff_deleted)
{
const char *index_path = diff_relpath;
- if (diff_cmd_baton->anchor)
- index_path = svn_dirent_join(diff_cmd_baton->anchor, diff_relpath,
+ if (diff_cmd_baton->ddi.anchor)
+ index_path = svn_dirent_join(diff_cmd_baton->ddi.anchor, diff_relpath,
scratch_pool);
SVN_ERR(svn_stream_printf_from_utf8(diff_cmd_baton->outstream,
@@ -1122,8 +1114,8 @@ diff_file_deleted(svn_wc_notify_state_t
if (tmpfile1)
SVN_ERR(diff_content_changed(&wrote_header, diff_relpath,
tmpfile1, tmpfile2,
- diff_cmd_baton->revnum1,
- diff_cmd_baton->revnum2,
+ diff_cmd_baton->ddi.revnum1,
+ diff_cmd_baton->ddi.revnum2,
mimetype1, mimetype2,
svn_diff_op_deleted, FALSE,
NULL, SVN_INVALID_REVNUM,
@@ -1138,8 +1130,8 @@ diff_file_deleted(svn_wc_notify_state_t
original_props, scratch_pool));
SVN_ERR(diff_props_changed(diff_relpath,
- diff_cmd_baton->revnum1,
- diff_cmd_baton->revnum2,
+ diff_cmd_baton->ddi.revnum1,
+ diff_cmd_baton->ddi.revnum2,
wrote_header, prop_changes,
original_props, ! wrote_header,
diff_cmd_baton, scratch_pool));
@@ -1621,6 +1613,7 @@ unsupported_diff_error(svn_error_t *chil
All other options are the same as those passed to svn_client_diff6(). */
static svn_error_t *
diff_wc_wc(const char **anchor_path,
+ struct diff_driver_info_t *ddi,
const char *path1,
const svn_opt_revision_t *revision1,
const char *path2,
@@ -1628,7 +1621,6 @@ diff_wc_wc(const char **anchor_path,
svn_depth_t depth,
svn_boolean_t ignore_ancestry,
const apr_array_header_t *changelists,
- struct diff_cmd_baton *callback_baton,
const svn_diff_tree_processor_t *diff_processor,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
@@ -1652,15 +1644,15 @@ diff_wc_wc(const char **anchor_path,
"and its working files are supported at this time"
)));
- if (callback_baton)
+ if (ddi)
{
svn_node_kind_t kind;
svn_error_t *err;
/* Resolve named revisions to real numbers. */
- err = svn_client__get_revision_number(&callback_baton->revnum1, NULL,
- ctx->wc_ctx, abspath1, NULL,
- revision1, scratch_pool);
+ err = svn_client__get_revision_number(&ddi->revnum1, NULL,
+ ctx->wc_ctx, abspath1, NULL,
+ revision1, scratch_pool);
/* In case of an added node, we have no base rev, and we show a revision
* number of 0. Note that this code is currently always asking for
@@ -1669,20 +1661,20 @@ diff_wc_wc(const char **anchor_path,
if (err && (err->apr_err == SVN_ERR_CLIENT_BAD_REVISION))
{
svn_error_clear(err);
- callback_baton->revnum1 = 0;
+ ddi->revnum1 = 0;
}
else
SVN_ERR(err);
- callback_baton->revnum2 = SVN_INVALID_REVNUM; /* WC */
+ ddi->revnum2 = SVN_INVALID_REVNUM; /* WC */
SVN_ERR(svn_wc_read_kind2(&kind, ctx->wc_ctx, abspath1,
TRUE, FALSE, scratch_pool));
if (kind != svn_node_dir)
- callback_baton->anchor = svn_dirent_dirname(path1, scratch_pool);
+ ddi->anchor = svn_dirent_dirname(path1, scratch_pool);
else
- callback_baton->anchor = path1;
+ ddi->anchor = path1;
}
SVN_ERR(svn_wc__diff7(anchor_path, ctx->wc_ctx,
@@ -1706,7 +1698,7 @@ diff_wc_wc(const char **anchor_path,
All other options are the same as those passed to svn_client_diff6(). */
static svn_error_t *
diff_repos_repos(const char **anchor_path_or_url,
- struct diff_cmd_baton *callback_baton,
+ struct diff_driver_info_t *ddi,
const char *path_or_url1,
const char *path_or_url2,
const svn_opt_revision_t *revision1,
@@ -1759,18 +1751,20 @@ diff_repos_repos(const char **anchor_pat
/* Set up the repos_diff editor on BASE_PATH, if available.
Otherwise, we just use "". */
- if (callback_baton)
+ if (ddi)
{
/* Get actual URLs. */
- callback_baton->orig_path_1 = url1;
- callback_baton->orig_path_2 = url2;
+ ddi->orig_path_1 = url1;
+ ddi->orig_path_2 = url2;
/* Get numeric revisions. */
- callback_baton->revnum1 = rev1;
- callback_baton->revnum2 = rev2;
+ ddi->revnum1 = rev1;
+ ddi->revnum2 = rev2;
- callback_baton->ra_session = ra_session;
- callback_baton->anchor = base_path;
+ ddi->anchor = base_path;
+
+ SVN_ERR(svn_ra_get_session_url(ra_session, &ddi->anchor_url,
+ result_pool));
}
/* The repository can bring in a new working copy, but not delete
@@ -1833,6 +1827,21 @@ diff_repos_repos(const char **anchor_pat
}
}
+ if (ddi)
+ {
+ const char *repos_root_url;
+ const char *session_url;
+
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
+ scratch_pool));
+ SVN_ERR(svn_ra_get_session_url(ra_session, &session_url,
+ scratch_pool));
+
+ ddi->session_relpath = svn_uri_skip_ancestor(repos_root_url,
+ session_url,
+ result_pool);
+ }
+
SVN_ERR(svn_client__get_diff_editor2(
&diff_editor, &diff_edit_baton,
extra_ra_session, depth,
@@ -1870,6 +1879,7 @@ diff_repos_repos(const char **anchor_pat
All other options are the same as those passed to svn_client_diff6(). */
static svn_error_t *
diff_repos_wc(const char **anchor_path,
+ struct diff_driver_info_t *ddi,
const char *path_or_url1,
const svn_opt_revision_t *revision1,
const svn_opt_revision_t *peg_revision,
@@ -1879,7 +1889,6 @@ diff_repos_wc(const char **anchor_path,
svn_depth_t depth,
svn_boolean_t ignore_ancestry,
const apr_array_header_t *changelists,
- struct diff_cmd_baton *cmd_baton,
const svn_diff_tree_processor_t *diff_processor,
svn_client_ctx_t *ctx,
apr_pool_t *result_pool,
@@ -1946,22 +1955,21 @@ diff_repos_wc(const char **anchor_path,
ctx, pool));
}
- if (cmd_baton)
+ if (ddi)
{
- cmd_baton->ra_session = ra_session;
- cmd_baton->anchor = anchor;
+ ddi->anchor = anchor;
if (!reverse)
{
- cmd_baton->orig_path_1 = url1;
- cmd_baton->orig_path_2 =
+ ddi->orig_path_1 = url1;
+ ddi->orig_path_2 =
svn_path_url_add_component2(anchor_url, target, pool);
}
else
{
- cmd_baton->orig_path_1 =
+ ddi->orig_path_1 =
svn_path_url_add_component2(anchor_url, target, pool);
- cmd_baton->orig_path_2 = url1;
+ ddi->orig_path_2 = url1;
}
}
@@ -1972,12 +1980,12 @@ diff_repos_wc(const char **anchor_path,
(strcmp(path_or_url1, url1) == 0)
? NULL : abspath_or_url1,
ra_session, revision1, pool));
- if (cmd_baton)
+ if (ddi)
{
if (!reverse)
- cmd_baton->revnum1 = rev;
+ ddi->revnum1 = rev;
else
- cmd_baton->revnum2 = rev;
+ ddi->revnum2 = rev;
}
/* Check if our diff target is a copied node. */
@@ -2024,8 +2032,8 @@ diff_repos_wc(const char **anchor_path,
const char *copyfrom_parent_url;
const char *copyfrom_basename;
- if (cmd_baton)
- cmd_baton->repos_wc_diff_target_is_copy = TRUE;
+ if (ddi)
+ ddi->repos_wc_diff_target_is_copy = TRUE;
/* We're diffing a locally copied/moved node.
* Describe the copy source to the reporter instead of the copy itself.
@@ -2050,6 +2058,21 @@ diff_repos_wc(const char **anchor_path,
}
SVN_ERR(svn_ra_reparent(ra_session, copyfrom_parent_url, pool));
+ if (ddi)
+ {
+ const char *repos_root_url;
+ const char *session_url;
+
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
+ scratch_pool));
+ SVN_ERR(svn_ra_get_session_url(ra_session, &session_url,
+ scratch_pool));
+
+ ddi->session_relpath = svn_uri_skip_ancestor(repos_root_url,
+ session_url,
+ result_pool);
+ }
+
/* Tell the RA layer we want a delta to change our txn to URL1 */
SVN_ERR(svn_ra_do_diff3(ra_session,
&reporter, &reporter_baton,
@@ -2083,6 +2106,21 @@ diff_repos_wc(const char **anchor_path,
}
else
{
+ if (ddi)
+ {
+ const char *repos_root_url;
+ const char *session_url;
+
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url,
+ scratch_pool));
+ SVN_ERR(svn_ra_get_session_url(ra_session, &session_url,
+ scratch_pool));
+
+ ddi->session_relpath = svn_uri_skip_ancestor(repos_root_url,
+ session_url,
+ result_pool);
+ }
+
/* Tell the RA layer we want a delta to change our txn to URL1 */
SVN_ERR(svn_ra_do_diff3(ra_session,
&reporter, &reporter_baton,
@@ -2113,7 +2151,7 @@ diff_repos_wc(const char **anchor_path,
/* This is basically just the guts of svn_client_diff[_peg]6(). */
static svn_error_t *
do_diff(const char **anchor_path,
- struct diff_cmd_baton *callback_baton,
+ diff_writer_info_t *dwi,
const char *path_or_url1,
const char *path_or_url2,
const svn_opt_revision_t *revision1,
@@ -2142,7 +2180,7 @@ do_diff(const char **anchor_path,
{
/* ### Ignores 'show_copies_as_adds'. */
SVN_ERR(diff_repos_repos(anchor_path,
- callback_baton,
+ &dwi->ddi,
path_or_url1, path_or_url2,
revision1, revision2,
peg_revision, depth, ignore_ancestry,
@@ -2160,12 +2198,10 @@ do_diff(const char **anchor_path,
if (show_copies_as_adds || use_git_diff_format)
ignore_ancestry = FALSE;
- SVN_ERR(diff_repos_wc(anchor_path,
+ SVN_ERR(diff_repos_wc(anchor_path, &dwi->ddi,
path_or_url1, revision1, peg_revision,
path_or_url2, revision2, FALSE, depth,
- ignore_ancestry,
- changelists,
- callback_baton,
+ ignore_ancestry, changelists,
diff_processor, ctx,
result_pool, scratch_pool));
}
@@ -2182,12 +2218,10 @@ do_diff(const char **anchor_path,
if (show_copies_as_adds || use_git_diff_format)
ignore_ancestry = FALSE;
- SVN_ERR(diff_repos_wc(anchor_path,
+ SVN_ERR(diff_repos_wc(anchor_path, &dwi->ddi,
path_or_url2, revision2, peg_revision,
path_or_url1, revision1, TRUE, depth,
- ignore_ancestry,
- changelists,
- callback_baton,
+ ignore_ancestry, changelists,
diff_processor, ctx,
result_pool, scratch_pool));
}
@@ -2225,11 +2259,11 @@ do_diff(const char **anchor_path,
if (use_git_diff_format || show_copies_as_adds)
ignore_ancestry = FALSE;
- SVN_ERR(diff_wc_wc(anchor_path,
+ SVN_ERR(diff_wc_wc(anchor_path, &dwi->ddi,
path_or_url1, revision1,
path_or_url2, revision2,
depth, ignore_ancestry, changelists,
- callback_baton, diff_processor, ctx,
+ diff_processor, ctx,
result_pool, scratch_pool));
}
}
@@ -2279,21 +2313,19 @@ do_diff_summarize(svn_client_diff_summar
diff_processor, ctx,
pool, pool));
else
- SVN_ERR(diff_repos_wc(anchor_path,
+ SVN_ERR(diff_repos_wc(anchor_path, NULL,
path_or_url1, revision1, peg_revision,
path_or_url2, revision2, FALSE /* reverse*/,
- depth, ignore_ancestry,
- changelists, NULL,
+ depth, ignore_ancestry, changelists,
diff_processor, ctx, pool, pool));
}
else /* ! is_repos1 */
{
if (is_repos2)
- SVN_ERR(diff_repos_wc(anchor_path,
+ SVN_ERR(diff_repos_wc(anchor_path, NULL,
path_or_url2, revision2, peg_revision,
path_or_url1, revision1, TRUE /* reverse */,
- depth, ignore_ancestry,
- changelists, NULL,
+ depth, ignore_ancestry, changelists,
diff_processor, ctx, pool, pool));
else
{
@@ -2312,11 +2344,10 @@ do_diff_summarize(svn_client_diff_summar
ctx, pool, pool));
}
else
- SVN_ERR(diff_wc_wc(anchor_path,
+ SVN_ERR(diff_wc_wc(anchor_path, NULL,
path_or_url1, revision1,
path_or_url2, revision2,
- depth, ignore_ancestry,
- changelists, NULL,
+ depth, ignore_ancestry, changelists,
diff_processor, ctx, pool, pool));
}
}
@@ -2325,15 +2356,15 @@ do_diff_summarize(svn_client_diff_summar
}
-/* Initialize DIFF_CMD_BATON.diff_cmd and DIFF_CMD_BATON.options,
+/* Initialize DWI.diff_cmd and DWI.options,
* according to OPTIONS and CONFIG. CONFIG and OPTIONS may be null.
- * Allocate the fields in POOL, which should be at least as long-lived
- * as the pool DIFF_CMD_BATON itself is allocated in.
+ * Allocate the fields in RESULT_POOL, which should be at least as long-lived
+ * as the pool DWI itself is allocated in.
*/
static svn_error_t *
-set_up_diff_cmd_and_options(struct diff_cmd_baton *diff_cmd_baton,
- const apr_array_header_t *options,
- apr_hash_t *config, apr_pool_t *pool)
+create_diff_writer_info(diff_writer_info_t *dwi,
+ const apr_array_header_t *options,
+ apr_hash_t *config, apr_pool_t *result_pool)
{
const char *diff_cmd = NULL;
@@ -2349,41 +2380,41 @@ set_up_diff_cmd_and_options(struct diff_
svn_config_get(cfg, &diff_extensions, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF_EXTENSIONS, NULL);
if (diff_extensions)
- options = svn_cstring_split(diff_extensions, " \t\n\r", TRUE, pool);
+ options = svn_cstring_split(diff_extensions, " \t\n\r", TRUE,
+ result_pool);
}
}
if (options == NULL)
- options = apr_array_make(pool, 0, sizeof(const char *));
+ options = apr_array_make(result_pool, 0, sizeof(const char *));
if (diff_cmd)
- SVN_ERR(svn_path_cstring_to_utf8(&diff_cmd_baton->diff_cmd, diff_cmd,
- pool));
+ SVN_ERR(svn_path_cstring_to_utf8(&dwi->diff_cmd, diff_cmd,
+ result_pool));
else
- diff_cmd_baton->diff_cmd = NULL;
+ dwi->diff_cmd = NULL;
/* If there was a command, arrange options to pass to it. */
- if (diff_cmd_baton->diff_cmd)
+ if (dwi->diff_cmd)
{
const char **argv = NULL;
int argc = options->nelts;
if (argc)
{
int i;
- argv = apr_palloc(pool, argc * sizeof(char *));
+ argv = apr_palloc(result_pool, argc * sizeof(char *));
for (i = 0; i < argc; i++)
SVN_ERR(svn_utf_cstring_to_utf8(&argv[i],
- APR_ARRAY_IDX(options, i, const char *), pool));
+ APR_ARRAY_IDX(options, i, const char *), result_pool));
}
- diff_cmd_baton->options.for_external.argv = argv;
- diff_cmd_baton->options.for_external.argc = argc;
+ dwi->options.for_external.argv = argv;
+ dwi->options.for_external.argc = argc;
}
else /* No command, so arrange options for internal invocation instead. */
{
- diff_cmd_baton->options.for_internal
- = svn_diff_file_options_create(pool);
- SVN_ERR(svn_diff_file_options_parse
- (diff_cmd_baton->options.for_internal, options, pool));
+ dwi->options.for_internal = svn_diff_file_options_create(result_pool);
+ SVN_ERR(svn_diff_file_options_parse(dwi->options.for_internal,
+ options, result_pool));
}
return SVN_NO_ERROR;
@@ -2448,7 +2479,7 @@ svn_client_diff6(const apr_array_header_
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- struct diff_cmd_baton diff_cmd_baton = { 0 };
+ diff_writer_info_t diff_cmd_baton = { 0 };
svn_opt_revision_t peg_revision;
const svn_diff_tree_processor_t *diff_processor;
@@ -2461,17 +2492,17 @@ svn_client_diff6(const apr_array_header_
peg_revision.kind = svn_opt_revision_unspecified;
/* setup callback and baton */
- diff_cmd_baton.orig_path_1 = path_or_url1;
- diff_cmd_baton.orig_path_2 = path_or_url2;
+ diff_cmd_baton.ddi.orig_path_1 = path_or_url1;
+ diff_cmd_baton.ddi.orig_path_2 = path_or_url2;
- SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
- ctx->config, pool));
+ SVN_ERR(create_diff_writer_info(&diff_cmd_baton, options,
+ ctx->config, pool));
diff_cmd_baton.pool = pool;
diff_cmd_baton.outstream = outstream;
diff_cmd_baton.errstream = errstream;
diff_cmd_baton.header_encoding = header_encoding;
- diff_cmd_baton.revnum1 = SVN_INVALID_REVNUM;
- diff_cmd_baton.revnum2 = SVN_INVALID_REVNUM;
+ diff_cmd_baton.ddi.revnum1 = SVN_INVALID_REVNUM;
+ diff_cmd_baton.ddi.revnum2 = SVN_INVALID_REVNUM;
diff_cmd_baton.force_binary = ignore_content_type;
diff_cmd_baton.ignore_properties = ignore_properties;
@@ -2483,8 +2514,8 @@ svn_client_diff6(const apr_array_header_
diff_cmd_baton.no_copyfrom_on_add = show_copies_as_adds;
diff_cmd_baton.wc_ctx = ctx->wc_ctx;
- diff_cmd_baton.ra_session = NULL;
- diff_cmd_baton.anchor = NULL;
+ diff_cmd_baton.ddi.session_relpath = NULL;
+ diff_cmd_baton.ddi.anchor = NULL;
SVN_ERR(svn_wc__wrap_diff_callbacks(&diff_processor,
&diff_callbacks, &diff_cmd_baton,
@@ -2523,7 +2554,7 @@ svn_client_diff_peg6(const apr_array_hea
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- struct diff_cmd_baton diff_cmd_baton = { 0 };
+ diff_writer_info_t diff_cmd_baton = { 0 };
const svn_diff_tree_processor_t *diff_processor;
if (ignore_properties && properties_only)
@@ -2532,17 +2563,17 @@ svn_client_diff_peg6(const apr_array_hea
"properties at the same time"));
/* setup callback and baton */
- diff_cmd_baton.orig_path_1 = path_or_url;
- diff_cmd_baton.orig_path_2 = path_or_url;
+ diff_cmd_baton.ddi.orig_path_1 = path_or_url;
+ diff_cmd_baton.ddi.orig_path_2 = path_or_url;
- SVN_ERR(set_up_diff_cmd_and_options(&diff_cmd_baton, options,
- ctx->config, pool));
+ SVN_ERR(create_diff_writer_info(&diff_cmd_baton, options,
+ ctx->config, pool));
diff_cmd_baton.pool = pool;
diff_cmd_baton.outstream = outstream;
diff_cmd_baton.errstream = errstream;
diff_cmd_baton.header_encoding = header_encoding;
- diff_cmd_baton.revnum1 = SVN_INVALID_REVNUM;
- diff_cmd_baton.revnum2 = SVN_INVALID_REVNUM;
+ diff_cmd_baton.ddi.revnum1 = SVN_INVALID_REVNUM;
+ diff_cmd_baton.ddi.revnum2 = SVN_INVALID_REVNUM;
diff_cmd_baton.force_binary = ignore_content_type;
diff_cmd_baton.ignore_properties = ignore_properties;
@@ -2554,8 +2585,8 @@ svn_client_diff_peg6(const apr_array_hea
diff_cmd_baton.no_copyfrom_on_add = show_copies_as_adds;
diff_cmd_baton.wc_ctx = ctx->wc_ctx;
- diff_cmd_baton.ra_session = NULL;
- diff_cmd_baton.anchor = NULL;
+ diff_cmd_baton.ddi.session_relpath = NULL;
+ diff_cmd_baton.ddi.anchor = NULL;
SVN_ERR(svn_wc__wrap_diff_callbacks(&diff_processor,
&diff_callbacks, &diff_cmd_baton,