Author: rhuijben
Date: Thu May 10 15:31:10 2012
New Revision: 1336745

URL: http://svn.apache.org/viewvc?rev=1336745&view=rev
Log:
First commit of breaking apart the merge_props_changed() function in the
libsvn_client merge code. This will allow providing the text and property
merge information to libsvn_wc in a single call, for atomic behavior and
for introducing conflicts in a single location.
(This will remove the need to combine multiple conflicts on a single node)

* subversion/libsvn_client/merge.c
  (merge_props_changed): Break apart into...
  (prepare_merge_props_changed): ... this and the old function itself.
  (merge_dir_props_changed,
   merge_file_changed): Update callers.

Modified:
    subversion/trunk/subversion/libsvn_client/merge.c

Modified: subversion/trunk/subversion/libsvn_client/merge.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/merge.c?rev=1336745&r1=1336744&r2=1336745&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/merge.c (original)
+++ subversion/trunk/subversion/libsvn_client/merge.c Thu May 10 15:31:10 2012
@@ -1133,17 +1133,14 @@ filter_self_referential_mergeinfo(apr_ar
 
 /* Used for both file and directory property merges. */
 static svn_error_t *
-merge_props_changed(svn_wc_notify_state_t *state,
-                    svn_boolean_t *tree_conflicted,
-                    const char *local_abspath,
-                    const apr_array_header_t *propchanges,
-                    apr_hash_t *original_props,
-                    void *baton,
-                    apr_pool_t *scratch_pool)
+prepare_merge_props_changed(const apr_array_header_t **prop_updates,
+                            const char *local_abspath,
+                            const apr_array_header_t *propchanges,
+                            void *baton,
+                            apr_pool_t *scratch_pool)
 {
   apr_array_header_t *props;
   merge_cmd_baton_t *merge_b = baton;
-  svn_client_ctx_t *ctx = merge_b->ctx;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
@@ -1175,8 +1172,6 @@ merge_props_changed(svn_wc_notify_state_
      definition, 'svn merge' shouldn't touch any data within .svn/  */
   if (props->nelts)
     {
-      svn_error_t *err;
-
       /* If this is a forward merge then don't add new mergeinfo to
          PATH that is already part of PATH's own history, see
          http://svn.haxx.se/dev/archive-2008-09/0006.shtml.  If the
@@ -1192,7 +1187,29 @@ merge_props_changed(svn_wc_notify_state_
                                                   merge_b->ra_session2,
                                                   merge_b->ctx,
                                                   scratch_pool));
+    }
+  *prop_updates = props;
 
+  return SVN_NO_ERROR;
+}
+static svn_error_t *
+merge_props_changed(svn_wc_notify_state_t *state,
+                    svn_boolean_t *tree_conflicted,
+                    const apr_array_header_t *props,
+                    const char *local_abspath,
+                    const apr_array_header_t *propchanges,
+                    apr_hash_t *original_props,
+                    void *baton,
+                    apr_pool_t *scratch_pool)
+{
+  merge_cmd_baton_t *merge_b = baton;
+  svn_client_ctx_t *ctx = merge_b->ctx;
+
+  /* We only want to merge "regular" version properties:  by
+     definition, 'svn merge' shouldn't touch any pristine data  */
+  if (props->nelts)
+    {
+      svn_error_t *err;
       err = svn_wc_merge_props3(state, ctx->wc_ctx, local_abspath, NULL, NULL,
                                 original_props, props, merge_b->dry_run,
                                 ctx->conflict_func2, ctx->conflict_baton2,
@@ -1216,6 +1233,7 @@ merge_props_changed(svn_wc_notify_state_
                   svn_boolean_t has_pristine_mergeinfo = FALSE;
                   apr_hash_t *pristine_props;
 
+                  /* ### Erroring here will leak err */
                   SVN_ERR(svn_wc_get_pristine_props(&pristine_props,
                                                     ctx->wc_ctx,
                                                     local_abspath,
@@ -1289,6 +1307,7 @@ merge_dir_props_changed(svn_wc_notify_st
                         apr_pool_t *scratch_pool)
 {
   merge_cmd_baton_t *merge_b = diff_baton;
+  apr_array_header_t *props;
   const char *local_abspath = svn_dirent_join(merge_b->target->abspath,
                                               local_relpath, scratch_pool);
   svn_wc_notify_state_t obstr_state;
@@ -1312,8 +1331,11 @@ merge_dir_props_changed(svn_wc_notify_st
       return SVN_NO_ERROR; /* We can't do a real prop merge for added dirs */
     }
 
+  SVN_ERR(prepare_merge_props_changed(&props, local_abspath, propchanges,
+                                      diff_baton, scratch_pool));
   return svn_error_trace(merge_props_changed(state,
                                              tree_conflicted,
+                                             props,
                                              local_abspath,
                                              propchanges,
                                              original_props,
@@ -1602,8 +1624,12 @@ merge_file_changed(svn_wc_notify_state_t
   if (prop_changes->nelts > 0)
     {
       svn_boolean_t tree_conflicted2 = FALSE;
+      const apr_array_header_t *props;
+
+      SVN_ERR(prepare_merge_props_changed(&props, mine_abspath, prop_changes,
+                                          baton, scratch_pool));
 
-      SVN_ERR(merge_props_changed(prop_state, &tree_conflicted2,
+      SVN_ERR(merge_props_changed(prop_state, &tree_conflicted2, props,
                                   mine_abspath, prop_changes, original_props,
                                   baton, scratch_pool));
 


Reply via email to