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

[PATCH][MERGE-TRACKING] Step 2 of repos to repos copy mergeinfo recording

From: Madan U Sreenivasan <madan_at_collab.net>
Date: 2006-10-24 00:32:46 CEST

Hi,

    Please find attached the step 2 of repos to repos copy mergeinfo
recording. The following items are pending to complete the same:

    - Obtain the mergeinfo of the source from the repository and merge with
the copyfrom info before
      recording the mergeinfo of the newly created node
    - Python tests to verify the same (of course, I test it too, but I have
a handy shell script that does it for me now :)

    Also please note that if
http://svn.haxx.se/dev/archive-2006-10/0205.shtml get committed, we could
further simplify the get_copyfrom_merge_info() functions.

Regards,
Madan.

PS: Am a little unhappy with having to convert svn_stringbuf_t to
svn_string_t in calculate_target_merge_info(). This is because
svn_mergeinfo_to_string() returns a svn_stringbuf_t, while we need a
svn_string_t to set the mergeinfo ( path_driver_cb_func() of
subversion/libsvn_client/copy.c) requires a svn_string_t (for
change_file_prop/change_dir_prop). I would be glad if somebody could tell
me why we use two different versions of svn_string* even within our API -
apart from the fact that stringbuf is 'growable' as the name implies.

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.

Reviewed By: dlr
             Kamesh Jayachandran <kamesh@collab.net>

Index: subversion/libsvn_client/copy.c
===================================================================
--- subversion/libsvn_client/copy.c (revision 22040)
+++ subversion/libsvn_client/copy.c (working copy)
@@ -185,8 +185,96 @@
   svn_string_t *mergeinfo;
 };
 
+/* A log callback conforming to the svn_log_message_receiver_t
+ interface for obtaining the copyfrom revision of a given path and
+ storing it in *BATON (an svn_revnum_t). */
+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 merge info of the given path in COPYFROM_MERGEINFO. */
 static svn_error_t *
+get_copyfrom_merge_info(svn_ra_session_t *ra_session,
+ apr_hash_t **copyfrom_mergeinfo,
+ const char *rel_path,
+ const char *copyfrom_path,
+ svn_revnum_t rev,
+ apr_pool_t *pool)
+{
+ svn_revnum_t oldest_rev = SVN_INVALID_REVNUM;
+ svn_merge_range_t *copyfrom_range;
+ apr_array_header_t *copyfrom_rangelist;
+ apr_array_header_t *rel_paths = apr_array_make(pool, 1,
+ sizeof(rel_paths));
+
+ APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
+
+ /* Trace back in history to find the revision at which this node
+ was created (copied or added). */
+ SVN_ERR(svn_ra_get_log(ra_session, rel_paths, 1, rev,
+ 1, FALSE, TRUE, copyfrom_receiver,
+ &oldest_rev, pool));
+
+ copyfrom_range = apr_palloc(pool, sizeof(*copyfrom_range));
+ copyfrom_range->start = oldest_rev;
+ copyfrom_range->end = rev;
+ copyfrom_rangelist = apr_array_make(pool, 1,
+ sizeof(copyfrom_range));
+ APR_ARRAY_PUSH(copyfrom_rangelist, svn_merge_range_t *)
+ = copyfrom_range;
+ *copyfrom_mergeinfo = apr_hash_make(pool);
+ apr_hash_set(*copyfrom_mergeinfo, copyfrom_path,
+ APR_HASH_KEY_STRING, copyfrom_rangelist);
+
+ return SVN_NO_ERROR;
+}
+
+/* Obtain the copyfrom merge info and the existing merge info of
+ the source path, merge them and set as a svn_string_t in
+ TARGET_MERGEINFO. */
+static svn_error_t *
+calculate_target_merge_info(svn_ra_session_t *ra_session,
+ svn_string_t **target_mergeinfo,
+ const char *copyfrom_url,
+ const char *src_rel_path,
+ svn_revnum_t src_revnum,
+ apr_pool_t *pool)
+{
+ const char *repos_root;
+ const char *copyfrom_path = copyfrom_url;
+ apr_hash_t *copyfrom_mergeinfo;
+ svn_stringbuf_t *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_merge_info(ra_session, &copyfrom_mergeinfo,
+ src_rel_path, copyfrom_path,
+ src_revnum, pool));
+
+ /* TODO: Obtain existing mergeinfo via svn_ra_get_merge_info() */
+ /* TODO: Merge copyfrom and existing mergeinfo to fill target_mergeinfo
+ using svn_mergeinfo_merge() */
+ /* For now, stringify copyfrom_mergeinfo and return */
+ SVN_ERR(svn_mergeinfo_to_string(&mergeinfo, copyfrom_mergeinfo, pool));
+ *target_mergeinfo = svn_string_create_from_buf(mergeinfo, pool);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 path_driver_cb_func(void **dir_baton,
                     void *parent_baton,
                     void *callback_baton,
@@ -458,8 +546,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_merge_info(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 Tue Oct 24 00:03:36 2006

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.