Hi,
Please find attached step 2 of the repos to repos copyfrom info
recording. This step obtains and readies the copyfrom information for the
source path.
Further steps include obtaining the existing mergeinfo and merging that
with the now available copyfrom mergeinfo.
I'm not sure if I have to hand-build the mergeinfo hash, as I have done
in the attached path. Maybe we could use svn_mergeinfo_parse(), but I dont
prefer this, because:
- The mergeinfo has to be built into a string to use
svn_mergeinfo_parse()
- This input string to svn_mergeinfo_parse() has to be in the format
"/trunk: 1-5", and this could become inconsistent if we decide to make
changes to the format later.
Please let me know what you think.
Regards,
Madan.
Step 2 of recording copyfrom history as mergeinfo on repos to repos copy.
This step
- obtains the copyfrom revision of the source path
- makes a mergeinfo hash out of it - this is required for further
merging with the existing mergeinfo.
On the merge-tracking branch:
* subversion/libsvn_client/copy.c
(copyfrom_receiver): New. Log callback to obtain the copyfrom revision.
(get_copyfrom_mergeinfo): New. Gets the copyfrom information of the given
path, and creates a mergeinfo hash out of it.
(calculate_target_mergeinfo): New. Currently calls get_copyfrom_mergeinfo()
to obtain the copyfrom mergeinfo of the source path.
(repos_to_repos_copy): Modified to use calculate_target_mergeinfo() to get
cb_baton.mergeinfo.
Index: subversion/libsvn_client/copy.c
===================================================================
--- subversion/libsvn_client/copy.c (revision 21626)
+++ subversion/libsvn_client/copy.c (working copy)
@@ -185,8 +185,92 @@
svn_string_t *mergeinfo;
};
+/* Log callback for obtaining the copyfrom revision of
+ a given path. */
+static svn_error_t *
+copyfrom_receiver(void *baton,
+ apr_hash_t *changed_paths,
+ svn_revnum_t revision,
+ const char *author,
+ const char *date,
+ const char *message,
+ apr_pool_t *pool)
+{
+ svn_revnum_t *svn_revnum = baton;
+ *svn_revnum = revision;
+ return SVN_NO_ERROR;
+}
+
+/* Obtain the copyfrom mergeinfo of the given path. */
static svn_error_t *
+get_copyfrom_mergeinfo(svn_ra_session_t *ra_session,
+ apr_hash_t **copyfrom_mergeinfo,
+ const char *rel_path,
+ const char *copyfrom_path,
+ svn_revnum_t src_revnum,
+ apr_pool_t *pool)
+{
+ svn_revnum_t copyfrom_rev;
+ svn_merge_range_t *copyfrom_mergerange;
+ apr_array_header_t *copyfrom_mergerange_list;
+ apr_array_header_t *rel_paths = apr_array_make(pool, 1,
+ sizeof(const char *));
+
+ *copyfrom_mergeinfo = NULL;
+
+ APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
+
+ /* Extract loginfo for finding the copyfrom rev */
+ SVN_ERR(svn_ra_get_log(ra_session, rel_paths, 1, src_revnum,
+ 1, FALSE, TRUE, copyfrom_receiver,
+ ©from_rev, pool));
+
+ copyfrom_mergerange = apr_palloc(pool, sizeof(*copyfrom_mergerange));
+ copyfrom_mergerange->start = copyfrom_rev;
+ copyfrom_mergerange->end = src_revnum;
+ copyfrom_mergerange_list = apr_array_make(pool, 1,
+ sizeof(copyfrom_mergerange));
+ APR_ARRAY_PUSH(copyfrom_mergerange_list, svn_merge_range_t *)
+ = copyfrom_mergerange;
+ *copyfrom_mergeinfo = apr_hash_make(pool);
+ apr_hash_set(*copyfrom_mergeinfo, copyfrom_path,
+ sizeof(copyfrom_mergerange_list), copyfrom_mergerange_list);
+
+ return SVN_NO_ERROR;
+}
+
+/* Obtain the copyfrom mergeinfo and the existing mergeinfo of
+ the source path, merge them and set as a svn_string_t in
+ TARGET_MERGEINFO. */
+static svn_error_t *
+calculate_target_mergeinfo(svn_ra_session_t *ra_session,
+ svn_string_t **target_mergeinfo,
+ const char *src_url,
+ const char *src_rel,
+ svn_revnum_t src_revnum,
+ apr_pool_t *pool)
+{
+ const char *repos_root;
+ const char *copyfrom_path = src_url;
+ apr_hash_t *copyfrom_mergeinfo;
+
+ /* Find src path relative to the repos root */
+ SVN_ERR(svn_ra_get_repos_root(ra_session, &repos_root, pool));
+ while (*copyfrom_path++ == *repos_root++ );
+ copyfrom_path--;
+
+ SVN_ERR(get_copyfrom_mergeinfo(ra_session, ©from_mergeinfo, src_rel,
+ copyfrom_path, src_revnum, pool));
+
+ /* TODO: Obtain existing mergeinfo */
+ /* TODO: Merge copyfrom and existing mergeinfo to fill target_mergeinfo */
+ *target_mergeinfo = NULL;
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
path_driver_cb_func(void **dir_baton,
void *parent_baton,
void *callback_baton,
@@ -458,8 +542,8 @@
cb_baton.is_move = is_move;
cb_baton.src_revnum = src_revnum;
cb_baton.resurrection = resurrection;
- /* ### TODO: calculate the mergeinfo to set on the target */
- cb_baton.mergeinfo = NULL;
+ SVN_ERR(calculate_target_mergeinfo(ra_session, &(cb_baton.mergeinfo),
+ src_url, src_rel, src_revnum, pool));
/* Call the path-based editor driver. */
err = svn_delta_path_driver(editor, edit_baton, youngest, paths,
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Sep 27 12:30:33 2006