Peter Lundblad requested that the changes to the protocol document be
submitted together with the code. This time, because I wanted to get
those changes in front of DannyB *before* I finished writing the code
(and am on a branch), I committed them earlier (in r20025). For
reference, here's that addition to the protocol document:
get-merge-info
params: ( ( path:string ) rev:number )
response: ( merge-info:string )
New in svn 1.5. If no paths are specified, an empty response is returned.
The first nested tuple should be a list. I think I need to add an
ellipses to indicate that.
Also, "rev" should be an optional parameter (the server defaults to
"youngest" -- the protocol doc might want to indicate that, too).
Does "rev" need to be placed in a tuple, or can it simply be preceded
by a question mark?
--- protocol (revision 20049)
+++ protocol (working copy)
@@ -279,7 +279,7 @@
New in svn 1.2. If path is non-existent, an empty response is returned.
get-merge-info
- params: ( ( path:string ) rev:number )
+ params: ( ( path:string ... ) ? rev:number )
response: ( merge-info:string )
New in svn 1.5. If no paths are specified, an empty response is returned.
Thoughts?
On Fri, 09 Jun 2006, dlr@tigris.org wrote:
> Author: dlr
> Date: Fri Jun 9 15:59:21 2006
> New Revision: 20033
>
> Modified:
> branches/merge-tracking/subversion/include/svn_repos.h
> branches/merge-tracking/subversion/libsvn_repos/fs-wrap.c
> branches/merge-tracking/subversion/svnserve/serve.c
>
> Log:
> On the merge-tracking branch: Punch a merge info retrieval operation
> through svnserve, via the repos, down to the FS.
>
> * subversion/include/svn_repos.h
> (svn_repos_fs_get_merge_info): Add function decl to fetch merge
> information for a set of paths.
>
> * subversion/libsvn_repos/fs-wrap.c
> (svn_repos_fs_get_merge_info): Implement function. While unreadable
> paths for which merge info are requested are filtered out,
> unreadable paths are NOT filtered out of the returned merge info.
>
> * subversion/svnserve/serve.c
> (get_merge_info): Add a new function to get the merge info for a
> list of paths at a specific revision.
>
> (main_commands): Add get_merge_info to the list as "get-merge-info".
>
>
> Modified: branches/merge-tracking/subversion/include/svn_repos.h
> URL: http://svn.collab.net/viewvc/svn/branches/merge-tracking/subversion/include/svn_repos.h?pathrev=20033&r1=20032&r2=20033
> ==============================================================================
> --- branches/merge-tracking/subversion/include/svn_repos.h (original)
> +++ branches/merge-tracking/subversion/include/svn_repos.h Fri Jun 9 15:59:21 2006
> @@ -1032,6 +1032,36 @@
>
> /* ---------------------------------------------------------------*/
>
> +/* Retrieving merge info. */
> +
> +/**
> + * Fetch the merge info for @a paths at @rev, and save it to @a
> + * mergeinfo (a mapping of char * paths to apr_array_header_t *'s of
> + * svn_merge_range_t * elements).
> + *
> + * If @a rev is @c SVN_INVALID_REVNUM, it defaults to youngest.
> + *
> + * If optional @a authz_read_func is non-NULL, then use this function
> + * (along with optional @a authz_read_baton) to check the readability
> + * of each path which merge info was requested for (from @a paths).
> + * Silently omit unreadable paths from the request for merge info.
> + *
> + * Use @a pool for temporary allocations.
> + *
> + * @since New in 1.5.
> + */
> +svn_error_t *
> +svn_repos_fs_get_merge_info(apr_hash_t **mergeinfo,
> + svn_repos_t *repos,
> + const apr_array_header_t *paths,
> + svn_revnum_t rev,
> + svn_repos_authz_func_t authz_read_func,
> + void *authz_read_baton,
> + apr_pool_t *pool);
> +
> +
> +/* ---------------------------------------------------------------*/
> +
> /* Retreiving multiple revisions of a file. */
>
> /**
>
> Modified: branches/merge-tracking/subversion/libsvn_repos/fs-wrap.c
> URL: http://svn.collab.net/viewvc/svn/branches/merge-tracking/subversion/libsvn_repos/fs-wrap.c?pathrev=20033&r1=20032&r2=20033
> ==============================================================================
> --- branches/merge-tracking/subversion/libsvn_repos/fs-wrap.c (original)
> +++ branches/merge-tracking/subversion/libsvn_repos/fs-wrap.c Fri Jun 9 15:59:21 2006
> @@ -570,6 +570,50 @@
> }
>
>
> +svn_error_t *
> +svn_repos_fs_get_merge_info(apr_hash_t **mergeinfo,
> + svn_repos_t *repos,
> + const apr_array_header_t *paths,
> + svn_revnum_t rev,
> + svn_repos_authz_func_t authz_read_func,
> + void *authz_read_baton,
> + apr_pool_t *pool)
> +{
> + apr_pool_t *subpool;
> + apr_array_header_t *readable_paths;
> + svn_fs_root_t *root;
> + int i;
> +
> + if (!SVN_IS_VALID_REVNUM(rev))
> + SVN_ERR(svn_fs_youngest_rev(&rev, repos->fs, pool));
> + SVN_ERR(svn_fs_revision_root(&root, repos->fs, rev, pool));
> + readable_paths = apr_array_make(pool, paths->nelts, sizeof(*readable_paths));
> + subpool = svn_pool_create(pool);
> +
> + /* Filter out unreadable paths before divining merge tracking info. */
> + for (i = 0; i < paths->nelts; i++)
> + {
> + svn_boolean_t readable;
> + const char *path = APR_ARRAY_IDX(paths, i, char *);
> + svn_pool_clear(subpool);
> + SVN_ERR(authz_read_func(&readable, root, path, authz_read_baton,
> + subpool));
> + if (readable)
> + APR_ARRAY_PUSH(readable_paths, const char *) = path;
> + }
> +
> + /* We consciously do not perform authz checks on the paths returned
> + in *MERGEINFO, avoiding massive authz overhead which would allow
> + us to protect the name of where a change was merged from, but not
> + the change itself. */
> + if (readable_paths->nelts > 0)
> + SVN_ERR(svn_fs_get_merge_info(root, readable_paths, rev, mergeinfo, pool));
> + else
> + *mergeinfo = NULL;
> +
> + apr_pool_destroy(subpool);
> + return SVN_NO_ERROR;
> +}
>
>
>
>
> Modified: branches/merge-tracking/subversion/svnserve/serve.c
> URL: http://svn.collab.net/viewvc/svn/branches/merge-tracking/subversion/svnserve/serve.c?pathrev=20033&r1=20032&r2=20033
> ==============================================================================
> --- branches/merge-tracking/subversion/svnserve/serve.c (original)
> +++ branches/merge-tracking/subversion/svnserve/serve.c Fri Jun 9 15:59:21 2006
> @@ -38,6 +38,7 @@
> #include "svn_md5.h"
> #include "svn_config.h"
> #include "svn_props.h"
> +#include "svn_mergeinfo.h"
> #include "svn_user.h"
>
> #include "server.h"
> @@ -1334,6 +1335,35 @@
> text_deltas, recurse, ignore_ancestry);
> }
>
> +/* ASSUMPTION: When performing a 'merge' with two URLs, the client
> + will call this command more than once. */
> +static svn_error_t *get_merge_info(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
> + apr_array_header_t *params, void *baton)
> +{
> + server_baton_t *b = baton;
> + svn_revnum_t rev = SVN_INVALID_REVNUM;
> + apr_array_header_t *paths;
> + apr_hash_t *mergeinfo;
> + int i;
> + svn_stringbuf_t *value;
> +
> + SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "l?r", &paths, &rev));
> + for (i = 0; i < paths->nelts; i++)
> + APR_ARRAY_IDX(paths, i, const char *) =
> + svn_path_canonicalize(APR_ARRAY_IDX(paths, i, const char *), pool);
> + SVN_ERR(trivial_auth_request(conn, pool, b));
> + SVN_CMD_ERR(svn_repos_fs_get_merge_info(&mergeinfo, b->repos, paths, rev,
> + authz_check_access_cb_func(b), b,
> + pool));
> + if (mergeinfo != NULL)
> + SVN_ERR(svn_mergeinfo_to_string(&value, mergeinfo, pool));
> + else
> + value = NULL;
> + SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "c",
> + value ? value->data : ""));
> + return SVN_NO_ERROR;
> +}
> +
> /* Send a log entry to the client. */
> static svn_error_t *log_receiver(void *baton, apr_hash_t *changed_paths,
> svn_revnum_t rev, const char *author,
> @@ -2007,6 +2037,7 @@
> { "switch", switch_cmd },
> { "status", status },
> { "diff", diff },
> + { "get-merge-info", get_merge_info },
> { "log", log_cmd },
> { "check-path", check_path },
> { "stat", stat },
- application/pgp-signature attachment: stored
Received on Mon Jun 12 21:14:35 2006