You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/12/14 05:14:20 UTC

svn commit: r1421664 [2/4] - in /subversion/branches/in-repo-authz: ./ build/ build/ac-macros/ contrib/server-side/svncutter/ subversion/bindings/swig/ subversion/bindings/swig/python/tests/ subversion/bindings/swig/ruby/libsvn_swig_ruby/ subversion/in...

Modified: subversion/branches/in-repo-authz/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_client/merge.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_client/merge.c Fri Dec 14 04:14:09 2012
@@ -8511,6 +8511,8 @@ remove_noop_subtree_ranges(const merge_s
   svn_merge_range_t *youngest_gap_rev;
   svn_rangelist_t *inoperative_ranges;
   apr_pool_t *iterpool;
+  const char *longest_common_subtree_ancestor = NULL;
+  svn_error_t *err;
 
   assert(session_url_is(ra_session, source->loc2->url, scratch_pool));
 
@@ -8549,6 +8551,19 @@ remove_noop_subtree_ranges(const merge_s
 
       svn_pool_clear(iterpool);
 
+      /* Issue #4269: Keep track of the longest common ancestor of all the
+         subtrees which require merges.  This may be a child of
+         TARGET->ABSPATH, which will allow us to narrow the log request
+         below. */
+      if (child->remaining_ranges && child->remaining_ranges->nelts)
+        {
+          if (longest_common_subtree_ancestor)
+            longest_common_subtree_ancestor = svn_dirent_get_longest_ancestor(
+              longest_common_subtree_ancestor, child->abspath, scratch_pool);
+          else
+            longest_common_subtree_ancestor = child->abspath;
+        }
+
       /* CHILD->REMAINING_RANGES will be NULL if child is absent. */
       if (child->remaining_ranges && child->remaining_ranges->nelts)
         SVN_ERR(svn_rangelist_merge2(subtree_remaining_ranges,
@@ -8589,24 +8604,53 @@ remove_noop_subtree_ranges(const merge_s
                                                   sizeof(svn_revnum_t *));
   log_gap_baton.pool = svn_pool_create(scratch_pool);
 
+  /* Find the longest common ancestor of all subtrees relative to
+     RA_SESSION's URL. */
+  if (longest_common_subtree_ancestor)
+    longest_common_subtree_ancestor =
+      svn_dirent_skip_ancestor(target->abspath,
+                               longest_common_subtree_ancestor);
+  else
+    longest_common_subtree_ancestor = "";
+
   /* Invoke the svn_log_entry_receiver_t receiver log_noop_revs() from
      oldest to youngest.  The receiver is optimized to add ranges to
      log_gap_baton.merged_ranges and log_gap_baton.operative_ranges, but
      requires that the revs arrive oldest to youngest -- see log_noop_revs()
      and rangelist_merge_revision(). */
-  SVN_ERR(get_log(ra_session, "", oldest_gap_rev->start + 1,
-                  youngest_gap_rev->end, TRUE,
-                  log_noop_revs, &log_gap_baton, scratch_pool));
-
-  inoperative_ranges = svn_rangelist__initialize(oldest_gap_rev->start,
-                                                 youngest_gap_rev->end,
-                                                 TRUE, scratch_pool);
-  SVN_ERR(svn_rangelist_remove(&(inoperative_ranges),
-                               log_gap_baton.operative_ranges,
-                               inoperative_ranges, FALSE, scratch_pool));
+  err = get_log(ra_session, longest_common_subtree_ancestor,
+                oldest_gap_rev->start + 1, youngest_gap_rev->end, TRUE,
+                log_noop_revs, &log_gap_baton, scratch_pool);
+
+  /* It's possible that the only subtrees with mergeinfo in TARGET don't have
+     any corresponding subtree in SOURCE between SOURCE->REV1 < SOURCE->REV2.
+     So it's also possible that we may ask for the logs of non-existent paths.
+     If we do, then assume that no subtree requires any ranges that are not
+     already required by the TARGET. */
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_FS_NOT_FOUND
+          && longest_common_subtree_ancestor[0] != '\0')
+        return svn_error_trace(err);
 
-  SVN_ERR(svn_rangelist_merge2(log_gap_baton.merged_ranges, inoperative_ranges,
-                               scratch_pool, scratch_pool));
+      /* Asked about a non-existent subtree in SOURCE. */
+      svn_error_clear(err);
+      log_gap_baton.merged_ranges =
+        svn_rangelist__initialize(oldest_gap_rev->start,
+                                  youngest_gap_rev->end,
+                                  TRUE, scratch_pool);
+    }
+  else
+    {
+      inoperative_ranges = svn_rangelist__initialize(oldest_gap_rev->start,
+                                                     youngest_gap_rev->end,
+                                                     TRUE, scratch_pool);
+      SVN_ERR(svn_rangelist_remove(&(inoperative_ranges),
+                                   log_gap_baton.operative_ranges,
+                                   inoperative_ranges, FALSE, scratch_pool));
+      SVN_ERR(svn_rangelist_merge2(log_gap_baton.merged_ranges, inoperative_ranges,
+                                   scratch_pool, scratch_pool));
+    }
 
   for (i = 1; i < children_with_mergeinfo->nelts; i++)
     {

Modified: subversion/branches/in-repo-authz/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_fs/fs-loader.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_fs/fs-loader.c Fri Dec 14 04:14:09 2012
@@ -120,8 +120,8 @@ load_module(fs_init_func_t *initfunc, co
                                  _("Invalid name for FS type '%s'"),
                                  name);
 
-    libname = apr_psprintf(pool, "libsvn_fs_%s-%d.so.0",
-                           name, SVN_VER_MAJOR);
+    libname = apr_psprintf(pool, "libsvn_fs_%s-%d.so.%d",
+                           name, SVN_VER_MAJOR, SVN_SOVERSION);
     funcname = apr_psprintf(pool, "svn_fs_%s__init", name);
 
     /* Find/load the specified library.  If we get an error, assume

Modified: subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.c Fri Dec 14 04:14:09 2012
@@ -579,7 +579,7 @@ svn_fs_base__dag_get_proplist(apr_hash_t
 
 svn_error_t *
 svn_fs_base__dag_set_proplist(dag_node_t *node,
-                              apr_hash_t *proplist,
+                              const apr_hash_t *proplist,
                               const char *txn_id,
                               trail_t *trail,
                               apr_pool_t *pool)

Modified: subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.h?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.h (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_fs_base/dag.h Fri Dec 14 04:14:09 2012
@@ -150,7 +150,7 @@ svn_error_t *svn_fs_base__dag_get_propli
    node being changed must be mutable.  TXN_ID is the Subversion
    transaction under which this occurs.  */
 svn_error_t *svn_fs_base__dag_set_proplist(dag_node_t *node,
-                                           apr_hash_t *proplist,
+                                           const apr_hash_t *proplist,
                                            const char *txn_id,
                                            trail_t *trail,
                                            apr_pool_t *pool);

Modified: subversion/branches/in-repo-authz/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_fs_fs/fs_fs.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_fs_fs/fs_fs.c Fri Dec 14 04:14:09 2012
@@ -7110,6 +7110,7 @@ choose_delta_base(representation_t **rep
   int walk;
   node_revision_t *base;
   fs_fs_data_t *ffd = fs->fsap_data;
+  svn_boolean_t maybe_shared_rep = FALSE;
 
   /* If we have no predecessors, then use the empty stream as a
      base. */
@@ -7149,12 +7150,83 @@ choose_delta_base(representation_t **rep
      walk back two predecessors.) */
   base = noderev;
   while ((count++) < noderev->predecessor_count)
-    SVN_ERR(svn_fs_fs__get_node_revision(&base, fs,
-                                         base->predecessor_id, pool));
+    {
+      SVN_ERR(svn_fs_fs__get_node_revision(&base, fs,
+                                           base->predecessor_id, pool));
+
+      /* If there is a shared rep along the way, we need to limit the
+       * length of the deltification chain.
+       * 
+       * Please note that copied nodes - such as branch directories - will
+       * look the same (false positive) while reps shared within the same
+       * revision will not be caught (false negative).
+       */
+      if (props)
+        {
+          if (   base->prop_rep
+              && svn_fs_fs__id_rev(base->id) > base->prop_rep->revision)
+            maybe_shared_rep = TRUE;
+        }
+      else
+        {
+          if (   base->data_rep
+              && svn_fs_fs__id_rev(base->id) > base->data_rep->revision)
+            maybe_shared_rep = TRUE;
+        }
+    }
 
   /* return a suitable base representation */
   *rep = props ? base->prop_rep : base->data_rep;
 
+  /* if we encountered a shared rep, it's parent chain may be different
+   * from the node-rev parent chain. */
+  if (*rep && maybe_shared_rep)
+    {
+      /* Check whether the length of the deltification chain is acceptable.
+       * Otherwise, shared reps may form a non-skipping delta chain in
+       * extreme cases. */
+      apr_pool_t *sub_pool = svn_pool_create(pool);
+      representation_t base_rep = **rep;
+      
+      /* Some reasonable limit, depending on how acceptable longer linear
+       * chains are in this repo.  Also, allow for some minimal chain. */
+      int max_chain_length = 2 * (int)ffd->max_linear_deltification + 2;
+
+      /* re-use open files between iterations */
+      svn_revnum_t rev_hint = SVN_INVALID_REVNUM;
+      apr_file_t *file_hint = NULL;
+
+      /* follow the delta chain towards the end but for at most
+       * MAX_CHAIN_LENGTH steps. */
+      for (; max_chain_length; --max_chain_length)
+        {
+          struct rep_state *rep_state;
+          struct rep_args *rep_args;
+
+          SVN_ERR(create_rep_state_body(&rep_state,
+                                        &rep_args,
+                                        &file_hint,
+                                        &rev_hint,
+                                        &base_rep,
+                                        fs,
+                                        sub_pool));
+          if (!rep_args->is_delta  || !rep_args->base_revision)
+            break;
+
+          base_rep.revision = rep_args->base_revision;
+          base_rep.offset = rep_args->base_offset;
+          base_rep.size = rep_args->base_length;
+          base_rep.txn_id = NULL;
+        }
+
+      /* start new delta chain if the current one has grown too long */
+      if (max_chain_length == 0)
+        *rep = NULL;
+
+      apr_pool_destroy(sub_pool);
+    }
+
+  /* verify that the reps don't form a degenerated '*/
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra/compat.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra/compat.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra/compat.c Fri Dec 14 04:14:09 2012
@@ -630,7 +630,6 @@ fr_log_message_receiver(void *baton,
 {
   struct fr_log_message_baton *lmb = baton;
   struct rev *rev;
-  apr_hash_index_t *hi;
 
   rev = apr_palloc(lmb->pool, sizeof(*rev));
   rev->revision = log_entry->revision;
@@ -639,17 +638,7 @@ fr_log_message_receiver(void *baton,
   lmb->eldest = rev;
 
   /* Duplicate log_entry revprops into rev->props */
-  rev->props = apr_hash_make(lmb->pool);
-  for (hi = apr_hash_first(pool, log_entry->revprops); hi;
-       hi = apr_hash_next(hi))
-    {
-      void *val;
-      const void *key;
-
-      apr_hash_this(hi, &key, NULL, &val);
-      apr_hash_set(rev->props, apr_pstrdup(lmb->pool, key), APR_HASH_KEY_STRING,
-                   svn_string_dup(val, lmb->pool));
-    }
+  rev->props = svn_prop_hash_dup(log_entry->revprops, lmb->pool);
 
   return prev_log_path(&lmb->path, &lmb->action,
                        &lmb->copyrev, log_entry->changed_paths2,

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra/ra_loader.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra/ra_loader.c Fri Dec 14 04:14:09 2012
@@ -140,8 +140,8 @@ load_ra_module(svn_ra__init_func_t *func
     const char *compat_funcname;
     apr_status_t status;
 
-    libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.0",
-                           ra_name, SVN_VER_MAJOR);
+    libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.%d",
+                           ra_name, SVN_VER_MAJOR, SVN_SOVERSION);
     funcname = apr_psprintf(pool, "svn_ra_%s__init", ra_name);
     compat_funcname = apr_psprintf(pool, "svn_ra_%s_init", ra_name);
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/commit.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/commit.c Fri Dec 14 04:14:09 2012
@@ -2261,7 +2261,6 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_delta_editor_t *editor;
   commit_context_t *ctx;
-  apr_hash_index_t *hi;
   const char *repos_root;
   const char *base_relpath;
   svn_boolean_t supports_ephemeral_props;
@@ -2273,17 +2272,7 @@ svn_ra_serf__get_commit_editor(svn_ra_se
   ctx->session = session;
   ctx->conn = session->conns[0];
 
-  ctx->revprop_table = apr_hash_make(pool);
-  for (hi = apr_hash_first(pool, revprop_table); hi; hi = apr_hash_next(hi))
-    {
-      const void *key;
-      apr_ssize_t klen;
-      void *val;
-
-      apr_hash_this(hi, &key, &klen, &val);
-      apr_hash_set(ctx->revprop_table, apr_pstrdup(pool, key), klen,
-                   svn_string_dup(val, pool));
-    }
+  ctx->revprop_table = svn_prop_hash_dup(revprop_table, pool);
 
   /* If the server supports ephemeral properties, add some carrying
      interesting version information. */

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/ra_serf.h?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/ra_serf.h Fri Dec 14 04:14:09 2012
@@ -94,10 +94,12 @@ typedef struct svn_ra_serf__connection_t
 
 } svn_ra_serf__connection_t;
 
-/** Max. number of connctions we'll open to the server. 
- *  Note: minimum 2 connections are required for ra_serf to function correctly!
+/** Maximum value we'll allow for the http-max-connections config option.
+ *
+ * Note: minimum 2 connections are required for ra_serf to function
+ * correctly!
  */
-#define MAX_NR_OF_CONNS 4
+#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
 
 /*
  * The master serf RA session.
@@ -111,6 +113,10 @@ struct svn_ra_serf__session_t {
   /* The current context */
   serf_context_t *context;
 
+  /* The maximum number of connections we'll use for parallelized
+     fetch operations (updates, etc.) */
+  apr_int64_t max_connections;
+
   /* Are we using ssl */
   svn_boolean_t using_ssl;
 
@@ -121,7 +127,7 @@ struct svn_ra_serf__session_t {
   const char *useragent;
 
   /* The current connection */
-  svn_ra_serf__connection_t *conns[MAX_NR_OF_CONNS];
+  svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
   int num_conns;
   int cur_conn;
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/replay.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/replay.c Fri Dec 14 04:14:09 2012
@@ -698,8 +698,8 @@ svn_ra_serf__replay(svn_ra_session_t *ra
  * optimally. Originally we used 5 as the max. number of outstanding
  * requests, but this turned out to be too low.
  *
- * Serf doesn't exit out of the serf_context_run loop as long as it
- * has data to send or receive. With small responses (revs of a few
+ * Serf doesn't exit out of the svn_ra_serf__context_run_wait loop as long as
+ * it has data to send or receive. With small responses (revs of a few
  * kB), serf doesn't come out of this loop at all. So with
  * MAX_OUTSTANDING_REQUESTS set to a low number, there's a big chance
  * that serf handles those requests completely in its internal loop,
@@ -732,14 +732,11 @@ svn_ra_serf__replay_range(svn_ra_session
   svn_revnum_t rev = start_revision;
   const char *report_target;
   int active_reports = 0;
-  apr_interval_time_t waittime_left = session->timeout;
 
   SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
 
   while (active_reports || rev <= end_revision)
     {
-      apr_status_t status;
-      svn_error_t *err;
       svn_ra_serf__list_t *done_list;
       svn_ra_serf__list_t *done_reports = NULL;
       replay_context_t *replay_ctx;
@@ -834,62 +831,8 @@ svn_ra_serf__replay_range(svn_ra_session
           active_reports++;
         }
 
-      /* Run the serf loop, send outgoing and process incoming requests.
-         This request will block when there are no more requests to send or
-         responses to receive, so we have to be careful on our bookkeeping.
-
-         ### we should probably adjust this timeout. if we get (say) 3
-         ### requests completed, then we want to exit immediately rather
-         ### than block for a few seconds. that will allow us to clear up
-         ### those 3 requests. if we have queued all of our revisions,
-         ### then we may want to block until timeout since we really don't
-         ### have much work other than destroying memory. (though that
-         ### is important, as we could end up with 50 src_rev_pool pools)
-
-         ### idea: when a revision is marked DONE, we can probably destroy
-         ### most of the memory. that will reduce pressue to have serf
-         ### return control to us, to complete the major memory disposal.
-
-         ### theoretically, we should use an iterpool here, but it turns
-         ### out that serf doesn't even use the pool param. if we grow
-         ### an iterpool in this loop for other purposes, then yeah: go
-         ### ahead and apply it here, too, in case serf eventually uses
-         ### that parameter.
-      */
-      status = serf_context_run(session->context,
-                                SVN_RA_SERF__CONTEXT_RUN_DURATION,
-                                pool);
-
-      err = session->pending_error;
-      session->pending_error = NULL;
-
-      /* If the context duration timeout is up, we'll subtract that
-         duration from the total time alloted for such things.  If
-         there's no time left, we fail with a message indicating that
-         the connection timed out.  */
-      if (APR_STATUS_IS_TIMEUP(status))
-        {
-          svn_error_clear(err);
-          err = SVN_NO_ERROR;
-          status = 0;
-
-          if (session->timeout)
-            {
-              if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
-                {
-                  waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
-                }
-              else
-                {
-                  return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
-                                          _("Connection timed out"));
-                }
-            }
-        }
-      else
-        {
-          waittime_left = session->timeout;
-        }
+      /* Run the serf loop. */
+      SVN_ERR(svn_ra_serf__context_run_wait(&replay_ctx->done, session, pool));
 
       /* Substract the number of completely handled responses from our
          total nr. of open requests', so we'll know when to stop this loop.
@@ -904,12 +847,6 @@ svn_ra_serf__replay_range(svn_ra_session
           active_reports--;
         }
 
-      SVN_ERR(err);
-      if (status)
-        {
-          return svn_ra_serf__wrap_err(status,
-                                       _("Error retrieving replay REPORT"));
-        }
       done_reports = NULL;
     }
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/serf.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/serf.c Fri Dec 14 04:14:09 2012
@@ -148,7 +148,6 @@ load_config(svn_ra_serf__session_t *sess
   const char *timeout_str = NULL;
   const char *exceptions;
   apr_port_t proxy_port;
-  svn_boolean_t is_exception = FALSE;
 
   if (config_hash)
     {
@@ -191,23 +190,21 @@ load_config(svn_ra_serf__session_t *sess
                  SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, NULL);
   if (exceptions)
     {
-      apr_array_header_t *l = svn_cstring_split(exceptions, ",", TRUE, pool);
-      is_exception = svn_cstring_match_glob_list(session->session_url.hostname,
-                                                 l);
-    }
-  if (! is_exception)
-    {
-      /* Load the global proxy server settings, if set. */
-      svn_config_get(config, &proxy_host, SVN_CONFIG_SECTION_GLOBAL,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
-      svn_config_get(config, &port_str, SVN_CONFIG_SECTION_GLOBAL,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
-      svn_config_get(config, &session->proxy_username,
-                     SVN_CONFIG_SECTION_GLOBAL,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
-      svn_config_get(config, &session->proxy_password,
-                     SVN_CONFIG_SECTION_GLOBAL,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
+      if (! svn_cstring_match_glob_list(session->session_url.hostname,
+                                        svn_cstring_split(exceptions, ",",
+                                                          TRUE, pool)))
+        {
+          svn_config_get(config, &proxy_host, SVN_CONFIG_SECTION_GLOBAL,
+                         SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
+          svn_config_get(config, &port_str, SVN_CONFIG_SECTION_GLOBAL,
+                         SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
+          svn_config_get(config, &session->proxy_username,
+                         SVN_CONFIG_SECTION_GLOBAL,
+                         SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
+          svn_config_get(config, &session->proxy_password,
+                         SVN_CONFIG_SECTION_GLOBAL,
+                         SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
+        }
     }
 
   /* Load the global ssl settings, if set. */
@@ -222,9 +219,15 @@ load_config(svn_ra_serf__session_t *sess
      to skelta updates. */
   SVN_ERR(svn_config_get_bool(config, &session->bulk_updates,
                               SVN_CONFIG_SECTION_GLOBAL,
-                              SVN_CONFIG_OPTION_BULK_UPDATES,
+                              SVN_CONFIG_OPTION_HTTP_BULK_UPDATES,
                               FALSE));
 
+  /* Load the maximum number of parallel session connections. */
+  svn_config_get_int64(config, &session->max_connections,
+                       SVN_CONFIG_SECTION_GLOBAL,
+                       SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
+                       SVN_CONFIG_DEFAULT_OPTION_HTTP_MAX_CONNECTIONS);
+
   if (config)
     server_group = svn_config_find_group(config,
                                          session->session_url.hostname,
@@ -244,30 +247,50 @@ load_config(svn_ra_serf__session_t *sess
       svn_auth_set_parameter(session->wc_callbacks->auth_baton,
                              SVN_AUTH_PARAM_SERVER_GROUP, server_group);
 
-      /* Load the group proxy server settings, overriding global settings. */
+      /* Load the group proxy server settings, overriding global
+         settings.  We intentionally ignore 'http-proxy-exceptions'
+         here because, well, if this site was an exception, why is
+         there a per-server proxy configuration for it?  */
       svn_config_get(config, &proxy_host, server_group,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
+                     SVN_CONFIG_OPTION_HTTP_PROXY_HOST, proxy_host);
       svn_config_get(config, &port_str, server_group,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
+                     SVN_CONFIG_OPTION_HTTP_PROXY_PORT, port_str);
       svn_config_get(config, &session->proxy_username, server_group,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
+                     SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME,
+                     session->proxy_username);
       svn_config_get(config, &session->proxy_password, server_group,
-                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
+                     SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD,
+                     session->proxy_password);
 
       /* Load the group ssl settings. */
       SVN_ERR(svn_config_get_bool(config, &session->trust_default_ca,
                                   server_group,
                                   SVN_CONFIG_OPTION_SSL_TRUST_DEFAULT_CA,
-                                  TRUE));
+                                  session->trust_default_ca));
       svn_config_get(config, &session->ssl_authorities, server_group,
-                     SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES, NULL);
+                     SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES,
+                     session->ssl_authorities);
 
       /* Load the group bulk updates flag. */
       SVN_ERR(svn_config_get_bool(config, &session->bulk_updates,
                                   server_group,
-                                  SVN_CONFIG_OPTION_BULK_UPDATES,
-                                  FALSE));
-    }
+                                  SVN_CONFIG_OPTION_HTTP_BULK_UPDATES,
+                                  session->bulk_updates));
+
+      /* Load the maximum number of parallel session connections,
+         overriding global values. */
+      svn_config_get_int64(config, &session->max_connections,
+                           server_group, SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
+                           session->max_connections);
+    }
+
+  /* Don't allow the http-max-connections value to be larger than our
+     compiled-in limit, or to be too small to operate.  Broken
+     functionality and angry administrators are equally undesirable. */
+  if (session->max_connections > SVN_RA_SERF__MAX_CONNECTIONS_LIMIT)
+    session->max_connections = SVN_RA_SERF__MAX_CONNECTIONS_LIMIT;
+  if (session->max_connections < 2)
+    session->max_connections = 2;
 
   /* Parse the connection timeout value, if any. */
   session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT);
@@ -307,7 +330,9 @@ load_config(svn_ra_serf__session_t *sess
       proxy_port = (apr_port_t) port;
     }
   else
-    proxy_port = 80;
+    {
+      proxy_port = 80;
+    }
 
   if (proxy_host)
     {
@@ -327,7 +352,9 @@ load_config(svn_ra_serf__session_t *sess
       serf_config_proxy(session->context, proxy_addr);
     }
   else
-    session->using_proxy = FALSE;
+    {
+      session->using_proxy = FALSE;
+    }
 
   /* Setup authentication. */
   SVN_ERR(load_http_auth_types(pool, config, server_group,

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/update.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_serf/update.c Fri Dec 14 04:14:09 2012
@@ -2858,7 +2858,7 @@ finish_report(void *report_baton,
         }
 
       /* Open extra connections if we have enough requests to send. */
-      if (sess->num_conns < MAX_NR_OF_CONNS)
+      if (sess->num_conns < sess->max_connections)
         SVN_ERR(open_connection_if_needed(sess, report->num_active_fetches +
                                           report->num_active_propfinds));
 
@@ -3199,7 +3199,7 @@ make_update_reporter(svn_ra_session_t *r
                             "xmlns:S", SVN_XML_NAMESPACE,
                             NULL);
       /* Subversion 1.8+ servers can be told to send properties for newly
-       added items inline even when doing a skelta response. */
+         added items inline even when doing a skelta response. */
       make_simple_xml_tag(&buf, "S:include-props", "yes", scratch_pool);
     }
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_ra_svn/cyrus_auth.c Fri Dec 14 04:14:09 2012
@@ -179,7 +179,7 @@ svn_ra_svn__sasl_common_init(apr_pool_t 
                  sasl_mutex_unlock_cb,
                  sasl_mutex_free_cb);
   free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
-  return svn_mutex__init(&array_mutex, TRUE, sasl_pool);
+  SVN_ERR(svn_mutex__init(&array_mutex, TRUE, sasl_pool));
 
 #endif /* APR_HAS_THREADS */
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/auth.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/auth.c Fri Dec 14 04:14:09 2012
@@ -422,9 +422,9 @@ svn_auth_get_platform_specific_provider(
       const char *library_label, *library_name;
       const char *provider_function_name, *version_function_name;
       library_name = apr_psprintf(pool,
-                                  "libsvn_auth_%s-%d.so.0",
+                                  "libsvn_auth_%s-%d.so.%d",
                                   provider_name,
-                                  SVN_VER_MAJOR);
+                                  SVN_VER_MAJOR, SVN_SOVERSION);
       library_label = apr_psprintf(pool, "svn_%s", provider_name);
       provider_function_name = apr_psprintf(pool,
                                             "svn_auth_get_%s_%s_provider",

Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c Fri Dec 14 04:14:09 2012
@@ -803,6 +803,9 @@ svn_config_ensure(const char *config_dir
         "###   http-timeout               Timeout for HTTP requests in seconds"
                                                                              NL
         "###   http-compression           Whether to compress HTTP requests" NL
+        "###   http-max-connections       Maximum number of parallel server" NL
+        "###                              connections to use for any given"  NL
+        "###                              HTTP operation."                   NL
         "###   neon-debug-mask            Debug mask for Neon HTTP library"  NL
         "###   ssl-authority-files        List of files, each of a trusted CA"
                                                                              NL
@@ -814,10 +817,9 @@ svn_config_ensure(const char *config_dir
         "###   http-library               Which library to use for http/https"
                                                                              NL
         "###                              connections."                      NL
-        "###   bulk-updates               Whether to request bulk update" NL
-        "###                              responses, or fetch each file in "
-                                                                             NL
-        "###                              an individual request. "           NL
+        "###   http-bulk-updates          Whether to request bulk update"    NL
+        "###                              responses or to fetch each file"   NL
+        "###                              in an individual request. "        NL
         "###   store-passwords            Specifies whether passwords used"  NL
         "###                              to authenticate against a"         NL
         "###                              Subversion server may be cached"   NL
@@ -837,8 +839,7 @@ svn_config_ensure(const char *config_dir
         "###                              unencrypted (i.e., as plaintext)." NL
 #endif
         "###   store-auth-creds           Specifies whether any auth info"   NL
-        "###                              (passwords as well as server certs)"
-                                                                             NL
+        "###                              (passwords, server certs, etc.)"   NL
         "###                              may be cached to disk."            NL
         "###   username                   Specifies the default username."   NL
         "###"                                                                NL

Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/skel.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/skel.c Fri Dec 14 04:14:09 2012
@@ -784,7 +784,7 @@ svn_skel__parse_prop(svn_string_t **prop
 
 svn_error_t *
 svn_skel__unparse_proplist(svn_skel_t **skel_p,
-                           apr_hash_t *proplist,
+                           const apr_hash_t *proplist,
                            apr_pool_t *pool)
 {
   svn_skel_t *skel = svn_skel__make_empty_list(pool);
@@ -794,7 +794,8 @@ svn_skel__unparse_proplist(svn_skel_t **
   if (proplist)
     {
       /* Loop over hash entries */
-      for (hi = apr_hash_first(pool, proplist); hi; hi = apr_hash_next(hi))
+      for (hi = apr_hash_first(pool, (apr_hash_t *)proplist); hi;
+           hi = apr_hash_next(hi))
         {
           const void *key;
           void *val;

Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/sqlite.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/sqlite.c Fri Dec 14 04:14:09 2012
@@ -472,8 +472,7 @@ svn_sqlite__bind_properties(svn_sqlite__
   if (props == NULL)
     return svn_error_trace(svn_sqlite__bind_blob(stmt, slot, NULL, 0));
 
-  SVN_ERR(svn_skel__unparse_proplist(&skel, (apr_hash_t *)props,
-                                     scratch_pool));
+  SVN_ERR(svn_skel__unparse_proplist(&skel, props, scratch_pool));
   properties = svn_skel__unparse(skel, scratch_pool);
   return svn_error_trace(svn_sqlite__bind_blob(stmt,
                                                slot,
@@ -582,6 +581,21 @@ svn_sqlite__column_token(svn_sqlite__stm
   return svn_token__from_word_strict(map, word);
 }
 
+int
+svn_sqlite__column_token_null(svn_sqlite__stmt_t *stmt,
+                              int column,
+                              const svn_token_map_t *map,
+                              int null_val)
+{
+  /* cast from 'unsigned char' to regular 'char'  */
+  const char *word = (const char *)sqlite3_column_text(stmt->s3stmt, column);
+
+  if (!word)
+    return null_val;
+
+  return svn_token__from_word_strict(map, word);
+}
+
 svn_error_t *
 svn_sqlite__column_properties(apr_hash_t **props,
                               svn_sqlite__stmt_t *stmt,

Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/sysinfo.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/sysinfo.c Fri Dec 14 04:14:09 2012
@@ -133,10 +133,14 @@ svn_sysinfo__linked_libs(apr_pool_t *poo
   lib->compiled_version = APR_VERSION_STRING;
   lib->runtime_version = apr_pstrdup(pool, apr_version_string());
 
+/* Don't list APR-Util if it isn't linked in, which it may not be if
+ * we're using APR 2.x+ which combined APR-Util into APR. */
+#ifdef APU_VERSION_STRING
   lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
   lib->name = "APR-Util";
   lib->compiled_version = APU_VERSION_STRING;
   lib->runtime_version = apr_pstrdup(pool, apu_version_string());
+#endif
 
   lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
   lib->name = "SQLite";

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/adm_ops.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/adm_ops.c Fri Dec 14 04:14:09 2012
@@ -903,8 +903,6 @@ static svn_error_t *
 add_from_disk(svn_wc__db_t *db,
               const char *local_abspath,
               svn_node_kind_t kind,
-              svn_wc_notify_func2_t notify_func,
-              void *notify_baton,
               apr_pool_t *scratch_pool)
 {
   if (kind == svn_node_file)
@@ -1275,7 +1273,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 
   if (!copyfrom_url)  /* Case 2a: It's a simple add */
     {
-      SVN_ERR(add_from_disk(db, local_abspath, kind, notify_func, notify_baton,
+      SVN_ERR(add_from_disk(db, local_abspath, kind,
                             scratch_pool));
       if (kind == svn_node_dir && !db_row_exists)
         {
@@ -1361,7 +1359,6 @@ svn_wc_add_from_disk(svn_wc_context_t *w
   SVN_ERR(check_can_add_to_parent(NULL, NULL, wc_ctx->db, local_abspath,
                                   scratch_pool, scratch_pool));
   SVN_ERR(add_from_disk(wc_ctx->db, local_abspath, kind,
-                        notify_func, notify_baton,
                         scratch_pool));
 
   /* Report the addition to the caller. */

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.c Fri Dec 14 04:14:09 2012
@@ -409,10 +409,10 @@ svn_wc__conflict_skel_add_prop_conflict(
                                         svn_wc__db_t *db,
                                         const char *wri_abspath,
                                         const char *marker_abspath,
-                                        apr_hash_t *mine_props,
-                                        apr_hash_t *their_old_props,
-                                        apr_hash_t *their_props,
-                                        apr_hash_t *conflicted_prop_names,
+                                        const apr_hash_t *mine_props,
+                                        const apr_hash_t *their_old_props,
+                                        const apr_hash_t *their_props,
+                                        const apr_hash_t *conflicted_prop_names,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool)
 {
@@ -464,7 +464,7 @@ svn_wc__conflict_skel_add_prop_conflict(
     svn_skel__prepend_str("", prop_conflict, result_pool); /* No old_props */
 
   conflict_names = svn_skel__make_empty_list(result_pool);
-  for (hi = apr_hash_first(scratch_pool, conflicted_prop_names);
+  for (hi = apr_hash_first(scratch_pool, (apr_hash_t *)conflicted_prop_names);
        hi;
        hi = apr_hash_next(hi))
     {
@@ -2865,3 +2865,19 @@ svn_wc_resolved_conflict5(svn_wc_context
                                                    notify_func, notify_baton,
                                                    scratch_pool));
 }
+
+/* Constructor for the result-structure returned by conflict callbacks. */
+svn_wc_conflict_result_t *
+svn_wc_create_conflict_result(svn_wc_conflict_choice_t choice,
+                              const char *merged_file,
+                              apr_pool_t *pool)
+{
+  svn_wc_conflict_result_t *result = apr_pcalloc(pool, sizeof(*result));
+  result->choice = choice;
+  result->merged_file = merged_file;
+  result->save_merged = FALSE;
+
+  /* If we add more fields to svn_wc_conflict_result_t, add them here. */
+
+  return result;
+}

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.h?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/conflicts.h Fri Dec 14 04:14:09 2012
@@ -182,10 +182,10 @@ svn_wc__conflict_skel_add_prop_conflict(
                                         svn_wc__db_t *db,
                                         const char *wri_abspath,
                                         const char *marker_abspath,
-                                        apr_hash_t *mine_props,
-                                        apr_hash_t *their_old_props,
-                                        apr_hash_t *their_props,
-                                        apr_hash_t *conflicted_prop_names,
+                                        const apr_hash_t *mine_props,
+                                        const apr_hash_t *their_old_props,
+                                        const apr_hash_t *their_props,
+                                        const apr_hash_t *conflicted_prop_names,
                                         apr_pool_t *result_pool,
                                         apr_pool_t *scratch_pool);
 

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/deprecated.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/deprecated.c Fri Dec 14 04:14:09 2012
@@ -2471,27 +2471,36 @@ svn_wc_merge_props2(svn_wc_notify_state_
 {
   const char *local_abspath;
   svn_error_t *err;
+  svn_wc_context_t *wc_ctx;
   struct conflict_func_1to2_baton conflict_wrapper;
 
+  if (base_merge && !dry_run)
+    return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                            U_("base_merge=TRUE is no longer supported; "
+                               "see notes/api-errata/1.7/wc006.txt"));
+
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
 
   conflict_wrapper.inner_func = conflict_func;
   conflict_wrapper.inner_baton = conflict_baton;
 
-  err = svn_wc__perform_props_merge(state,
-                                    svn_wc__adm_get_db(adm_access),
-                                    local_abspath,
-                                    NULL /* left_version */,
-                                    NULL /* right_version */,
-                                    baseprops,
-                                    propchanges,
-                                    base_merge,
-                                    dry_run,
-                                    conflict_func ? conflict_func_1to2_wrapper
-                                                  : NULL,
-                                    &conflict_wrapper,
-                                    NULL, NULL,
-                                    scratch_pool);
+  SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
+                                         svn_wc__adm_get_db(adm_access),
+                                         scratch_pool));
+
+  err = svn_wc_merge_props3(state,
+                            wc_ctx,
+                            local_abspath,
+                            NULL /* left_version */,
+                            NULL /* right_version */,
+                            baseprops,
+                            propchanges,
+                            dry_run,
+                            conflict_func ? conflict_func_1to2_wrapper
+                                          : NULL,
+                            &conflict_wrapper,
+                            NULL, NULL,
+                            scratch_pool);
 
   if (err)
     switch(err->apr_err)
@@ -2501,7 +2510,9 @@ svn_wc_merge_props2(svn_wc_notify_state_
           err->apr_err = SVN_ERR_UNVERSIONED_RESOURCE;
           break;
       }
-  return svn_error_trace(err);
+  return svn_error_trace(
+            svn_error_compose_create(err,
+                                     svn_wc_context_destroy(wc_ctx)));
 }
 
 svn_error_t *

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/merge.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/merge.c Fri Dec 14 04:14:09 2012
@@ -1323,20 +1323,3 @@ svn_wc_merge5(enum svn_wc_merge_outcome_
   
   return SVN_NO_ERROR;
 }
-
-
-/* Constructor for the result-structure returned by conflict callbacks. */
-svn_wc_conflict_result_t *
-svn_wc_create_conflict_result(svn_wc_conflict_choice_t choice,
-                              const char *merged_file,
-                              apr_pool_t *pool)
-{
-  svn_wc_conflict_result_t *result = apr_pcalloc(pool, sizeof(*result));
-  result->choice = choice;
-  result->merged_file = merged_file;
-  result->save_merged = FALSE;
-
-  /* If we add more fields to svn_wc_conflict_result_t, add them here. */
-
-  return result;
-}

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/props.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/props.c Fri Dec 14 04:14:09 2012
@@ -181,33 +181,32 @@ combine_forked_mergeinfo_props(const svn
 
 
 svn_error_t *
-svn_wc__perform_props_merge(svn_wc_notify_state_t *state,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            const svn_wc_conflict_version_t *left_version,
-                            const svn_wc_conflict_version_t *right_version,
-                            apr_hash_t *baseprops,
-                            const apr_array_header_t *propchanges,
-                            svn_boolean_t base_merge,
-                            svn_boolean_t dry_run,
-                            svn_wc_conflict_resolver_func2_t conflict_func,
-                            void *conflict_baton,
-                            svn_cancel_func_t cancel_func,
-                            void *cancel_baton,
-                            apr_pool_t *scratch_pool)
+svn_wc_merge_props3(svn_wc_notify_state_t *state,
+                    svn_wc_context_t *wc_ctx,
+                    const char *local_abspath,
+                    const svn_wc_conflict_version_t *left_version,
+                    const svn_wc_conflict_version_t *right_version,
+                    apr_hash_t *baseprops,
+                    const apr_array_header_t *propchanges,
+                    svn_boolean_t dry_run,
+                    svn_wc_conflict_resolver_func2_t conflict_func,
+                    void *conflict_baton,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    apr_pool_t *scratch_pool)
 {
   int i;
   svn_wc__db_status_t status;
   svn_kind_t kind;
   apr_hash_t *pristine_props = NULL;
   apr_hash_t *actual_props;
-  apr_hash_t *new_pristine_props;
   apr_hash_t *new_actual_props;
   svn_boolean_t had_props, props_mod;
   svn_boolean_t have_base;
   svn_boolean_t conflicted;
   svn_skel_t *work_items = NULL;
   svn_skel_t *conflict_skel = NULL;
+  svn_wc__db_t *db = wc_ctx->db;
 
   /* IMPORTANT: svn_wc_merge_prop_diffs relies on the fact that baseprops
      may be NULL. */
@@ -294,8 +293,7 @@ svn_wc__perform_props_merge(svn_wc_notif
   /* Note that while this routine does the "real" work, it's only
      prepping tempfiles and writing log commands.  */
   SVN_ERR(svn_wc__merge_props(&conflict_skel, state,
-                              base_merge ? &new_pristine_props : NULL,
-                              &new_actual_props,
+                              NULL, &new_actual_props,
                               db, local_abspath,
                               baseprops /* server_baseprops */,
                               pristine_props,
@@ -308,6 +306,18 @@ svn_wc__perform_props_merge(svn_wc_notif
       return SVN_NO_ERROR;
     }
 
+  {
+    const char *dir_abspath;
+
+    if (kind == svn_kind_dir)
+      dir_abspath = local_abspath;
+    else
+      dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+
+    /* Verify that we're holding this directory's write lock.  */
+    SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
+  }
+
   if (conflict_skel)
     {
       svn_skel_t *work_item;
@@ -325,44 +335,18 @@ svn_wc__perform_props_merge(svn_wc_notif
       work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
     }
 
-  {
-    const char *dir_abspath;
-
-    if (kind == svn_kind_dir)
-      dir_abspath = local_abspath;
-    else
-      dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
-    /* Verify that we're holding this directory's write lock.  */
-    SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
-
-    /* After a (not-dry-run) merge, we ALWAYS have props to save.  */
-    SVN_ERR_ASSERT(new_pristine_props != NULL && new_actual_props != NULL);
+  /* After a (not-dry-run) merge, we ALWAYS have props to save.  */
+  SVN_ERR_ASSERT(new_actual_props != NULL);
 
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-    if (status == svn_wc__db_status_added)
-      SVN_ERR(svn_wc__db_temp_working_set_props(
-                db, local_abspath, new_pristine_props, scratch_pool));
-    else
-      SVN_ERR(svn_wc__db_temp_base_set_props(
-                db, local_abspath, new_pristine_props, scratch_pool));
-#else
-    if (base_merge)
-      return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                              U_("base_merge=TRUE is no longer supported"));
-#endif
-
-    SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
-                                    svn_wc__has_magic_property(propchanges),
-                                    conflict_skel,
-                                    work_items,
-                                    scratch_pool));
+  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, new_actual_props,
+                                  svn_wc__has_magic_property(propchanges),
+                                  conflict_skel,
+                                  work_items,
+                                  scratch_pool));
 
-    if (work_items != NULL)
-      SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
-                             scratch_pool));
-  }
+  if (work_items != NULL)
+    SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
+                           scratch_pool));
 
   if (conflict_skel && conflict_func)
     SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, conflict_skel,
@@ -374,36 +358,6 @@ svn_wc__perform_props_merge(svn_wc_notif
 }
 
 
-svn_error_t *
-svn_wc_merge_props3(svn_wc_notify_state_t *state,
-                    svn_wc_context_t *wc_ctx,
-                    const char *local_abspath,
-                    const svn_wc_conflict_version_t *left_version,
-                    const svn_wc_conflict_version_t *right_version,
-                    apr_hash_t *baseprops,
-                    const apr_array_header_t *propchanges,
-                    svn_boolean_t dry_run,
-                    svn_wc_conflict_resolver_func2_t conflict_func,
-                    void *conflict_baton,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_wc__perform_props_merge(
-                           state,
-                           wc_ctx->db,
-                           local_abspath,
-                           left_version, right_version,
-                           baseprops,
-                           propchanges,
-                           FALSE /* base_merge */,
-                           dry_run,
-                           conflict_func, conflict_baton,
-                           cancel_func, cancel_baton,
-                           scratch_pool));
-}
-
-
 /* Generate a message to describe the property conflict among these four
    values.
 
@@ -784,33 +738,26 @@ set_prop_merge_state(svn_wc_notify_state
   *state = new_value;
 }
 
-/* Add the property with name PROPNAME to the set of ACTUAL_PROPS on
- * DB/LOCAL_ABSPATH, setting *STATE or *CONFLICT_REMAINS according to
- * the merge outcome.
- *
- * *STATE is an input and output parameter, its value is to be
- * set using set_merge_prop_state().
- *
- * BASE_VAL contains the working copy base property value
+/* Apply the addition of a property with name PROPNAME and value NEW_VAL to
+ * the existing property with value WORKING_VAL, that originally had value
+ * PRISTINE_VAL.
  *
- * NEW_VAL contains the value to be set.
+ * Sets *RESULT_VAL to the resulting value.
+ * Sets *CONFLICT_REMAINS to TRUE if the change caused a conflict.
+ * Sets *DID_MERGE to true if the result is caused by a merge
  */
 static svn_error_t *
-apply_single_prop_add(svn_wc_notify_state_t *state,
+apply_single_prop_add(const svn_string_t **result_val,
                       svn_boolean_t *conflict_remains,
-                      svn_wc__db_t *db,
-                      const char *local_abspath,
-                      apr_hash_t *actual_props,
+                      svn_boolean_t *did_merge,
                       const char *propname,
-                      const svn_string_t *base_val,
+                      const svn_string_t *pristine_val,
                       const svn_string_t *new_val,
+                      const svn_string_t *working_val,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 
 {
-  svn_string_t *working_val
-    = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
   *conflict_remains = FALSE;
 
   if (working_val)
@@ -819,7 +766,7 @@ apply_single_prop_add(svn_wc_notify_stat
 
       if (svn_string_compare(working_val, new_val))
         /* The value we want is already there, so it's a merge. */
-        set_prop_merge_state(state, svn_wc_notify_state_merged);
+        *did_merge = TRUE;
 
       else
         {
@@ -849,9 +796,8 @@ apply_single_prop_add(svn_wc_notify_stat
               else
                 {
                   merged_prop = TRUE;
-                  apr_hash_set(actual_props, propname,
-                               APR_HASH_KEY_STRING, merged_val);
-                  set_prop_merge_state(state, svn_wc_notify_state_merged);
+                  *result_val = merged_val;
+                  *did_merge = TRUE;
                 }
             }
 
@@ -859,43 +805,34 @@ apply_single_prop_add(svn_wc_notify_stat
             *conflict_remains = TRUE;
         }
     }
-  else if (base_val)
+  else if (pristine_val)
     *conflict_remains = TRUE;
   else  /* property doesn't yet exist in actual_props...  */
     /* so just set it */
-    apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
+    *result_val = new_val;
 
   return SVN_NO_ERROR;
 }
 
 
-/* Delete the property with name PROPNAME from the set of ACTUAL_PROPS on
- * DB/LOCAL_ABSPATH, setting *STATE or *CONFLICT_REMAINS according to
- * the merge outcome.
- *
- * *STATE is an input and output parameter, its value is to be
- * set using set_merge_prop_state().
+/* Apply the deletion of a property with name PROPNAME to the existing
+ * property with value WORKING_VAL, that originally had value PRISTINE_VAL.
  *
- * BASE_VAL contains the working copy base property value
- *
- * OLD_VAL contains the value the of the property the server
- * thinks it's deleting.
+ * Sets *RESULT_VAL to the resulting value.
+ * Sets *CONFLICT_REMAINS to TRUE if the change caused a conflict.
+ * Sets *DID_MERGE to true if the result is caused by a merge
  */
 static svn_error_t *
-apply_single_prop_delete(svn_wc_notify_state_t *state,
+apply_single_prop_delete(const svn_string_t **result_val,
                          svn_boolean_t *conflict_remains,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_hash_t *actual_props,
+                         svn_boolean_t *did_merge,
                          const char *propname,
                          const svn_string_t *base_val,
                          const svn_string_t *old_val,
+                         const svn_string_t *working_val,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
-  svn_string_t *working_val
-    = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
   *conflict_remains = FALSE;
 
   if (! base_val)
@@ -908,11 +845,11 @@ apply_single_prop_delete(svn_wc_notify_s
         }
       else
         {
-          apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, NULL);
+          *result_val = NULL;
           if (old_val)
             /* This is a merge, merging a delete into non-existent
                property or a local addition of same prop value. */
-            set_prop_merge_state(state, svn_wc_notify_state_merged);
+            *did_merge = TRUE;
         }
     }
 
@@ -922,14 +859,14 @@ apply_single_prop_delete(svn_wc_notify_s
          {
            if (svn_string_compare(working_val, old_val))
              /* they have the same values, so it's an update */
-             apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, NULL);
+             *result_val = NULL;
            else
              *conflict_remains = TRUE;
          }
        else
          /* The property is locally deleted from the same value, so it's
             a merge */
-         set_prop_merge_state(state, svn_wc_notify_state_merged);
+         *did_merge = TRUE;
     }
 
   else
@@ -947,21 +884,17 @@ apply_single_prop_delete(svn_wc_notify_s
    were not followed for this property, but with no attempt to rationalize
    the remainder. */
 static svn_error_t *
-apply_single_mergeinfo_prop_change(svn_wc_notify_state_t *state,
+apply_single_mergeinfo_prop_change(const svn_string_t **result_val,
                                    svn_boolean_t *conflict_remains,
-                                   svn_wc__db_t *db,
-                                   const char *local_abspath,
-                                   apr_hash_t *actual_props,
+                                   svn_boolean_t *did_merge,
                                    const char *propname,
                                    const svn_string_t *base_val,
                                    const svn_string_t *old_val,
                                    const svn_string_t *new_val,
+                                   const svn_string_t *working_val,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool)
 {
-  svn_string_t *working_val
-    = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
   if ((working_val && ! base_val)
       || (! working_val && base_val)
       || (working_val && base_val
@@ -972,24 +905,22 @@ apply_single_mergeinfo_prop_change(svn_w
         {
           if (svn_string_compare(working_val, new_val))
             /* The new value equals the changed value: a no-op merge */
-            set_prop_merge_state(state, svn_wc_notify_state_merged);
+            *did_merge = TRUE;
           else
             {
-                  /* We have base, WC, and new values.  Discover
-                     deltas between base <-> WC, and base <->
-                     incoming.  Combine those deltas, and apply
-                     them to base to get the new value. */
-                  SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
-                                                         working_val,
-                                                         new_val,
-                                                         result_pool,
-                                                         scratch_pool));
-                  apr_hash_set(actual_props, propname,
-                               APR_HASH_KEY_STRING, new_val);
-                  set_prop_merge_state(state, svn_wc_notify_state_merged);
+              /* We have base, WC, and new values.  Discover
+                 deltas between base <-> WC, and base <->
+                 incoming.  Combine those deltas, and apply
+                 them to base to get the new value. */
+              SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
+                                                     working_val,
+                                                     new_val,
+                                                     result_pool,
+                                                     scratch_pool));
+              *result_val = new_val;
+              *did_merge = TRUE;
             }
         }
-
       else
         {
           /* There is a base_val but no working_val */
@@ -1000,39 +931,36 @@ apply_single_mergeinfo_prop_change(svn_w
   else if (! working_val) /* means !working_val && !base_val due
                              to conditions above: no prop at all */
     {
-          /* Discover any mergeinfo additions in the
-             incoming value relative to the base, and
-             "combine" those with the empty WC value. */
-          svn_mergeinfo_t deleted_mergeinfo, added_mergeinfo;
-          svn_string_t *mergeinfo_string;
-
-          SVN_ERR(diff_mergeinfo_props(&deleted_mergeinfo,
-                                       &added_mergeinfo,
-                                       old_val, new_val, scratch_pool));
-          SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string,
-                                          added_mergeinfo, result_pool));
-          apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING,
-                       mergeinfo_string);
+      /* Discover any mergeinfo additions in the
+         incoming value relative to the base, and
+         "combine" those with the empty WC value. */
+      svn_mergeinfo_t deleted_mergeinfo, added_mergeinfo;
+      svn_string_t *mergeinfo_string;
+
+      SVN_ERR(diff_mergeinfo_props(&deleted_mergeinfo,
+                                   &added_mergeinfo,
+                                   old_val, new_val, scratch_pool));
+      SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string,
+                                      added_mergeinfo, result_pool));
+      *result_val = mergeinfo_string;
     }
 
   else /* means working && base && svn_string_compare(working, base) */
     {
       if (svn_string_compare(old_val, base_val))
-        apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
-
+        *result_val = new_val;
       else
         {
-              /* We have base, WC, and new values.  Discover
-                 deltas between base <-> WC, and base <->
-                 incoming.  Combine those deltas, and apply
-                 them to base to get the new value. */
-              SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
-                                                     working_val,
-                                                     new_val, result_pool,
-                                                     scratch_pool));
-              apr_hash_set(actual_props, propname,
-                           APR_HASH_KEY_STRING, new_val);
-              set_prop_merge_state(state, svn_wc_notify_state_merged);
+          /* We have base, WC, and new values.  Discover
+             deltas between base <-> WC, and base <->
+             incoming.  Combine those deltas, and apply
+             them to base to get the new value. */
+          SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
+                                                 working_val,
+                                                 new_val, result_pool,
+                                                 scratch_pool));
+          *result_val = new_val;
+          *did_merge = TRUE;
         }
     }
 
@@ -1046,21 +974,17 @@ apply_single_mergeinfo_prop_change(svn_w
    The definition of the arguments and behaviour is the same as
    apply_single_prop_change(). */
 static svn_error_t *
-apply_single_generic_prop_change(svn_wc_notify_state_t *state,
+apply_single_generic_prop_change(const svn_string_t **result_val,
                                  svn_boolean_t *conflict_remains,
-                                 svn_wc__db_t *db,
-                                 const char *local_abspath,
-                                 apr_hash_t *actual_props,
+                                 svn_boolean_t *did_merge,
                                  const char *propname,
                                  const svn_string_t *base_val,
                                  const svn_string_t *old_val,
                                  const svn_string_t *new_val,
+                                 const svn_string_t *working_val,
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
 {
-  svn_string_t *working_val
-    = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
-
   SVN_ERR_ASSERT(old_val != NULL);
 
   /* If working_val is the same as new_val already then there is
@@ -1070,14 +994,14 @@ apply_single_generic_prop_change(svn_wc_
     {
       /* All values identical is a trivial, non-notifiable merge */
       if (! old_val || ! svn_string_compare(old_val, new_val))
-        set_prop_merge_state(state, svn_wc_notify_state_merged);
+        *did_merge = TRUE;
     }
   /* If working_val is the same as old_val... */
   else if (working_val && old_val
       && svn_string_compare(working_val, old_val))
     {
       /* A trivial update: change it to new_val. */
-      apr_hash_set(actual_props, propname, APR_HASH_KEY_STRING, new_val);
+      *result_val = new_val;
     }
   else
     {
@@ -1088,9 +1012,8 @@ apply_single_generic_prop_change(svn_wc_
   return SVN_NO_ERROR;
 }
 
-/* Change the property with name PROPNAME in the set of ACTUAL_PROPS on
- * DB/LOCAL_ABSPATH, setting *STATE or *CONFLICT_REMAINS according to
- * the merge outcome.
+/* Change the property with name PROPNAME in the set of ACTUAL_PROPS,
+ * setting *STATE or *CONFLICT_REMAINS according to the merge outcome.
  *
  * *STATE is an input and output parameter, its value is to be
  * set using set_prop_merge_state(). (May be null.).
@@ -1103,15 +1026,14 @@ apply_single_generic_prop_change(svn_wc_
  * NEW_VAL contains the value to be set. (Not null.)
  */
 static svn_error_t *
-apply_single_prop_change(svn_wc_notify_state_t *state,
+apply_single_prop_change(const svn_string_t **result_val,
                          svn_boolean_t *conflict_remains,
-                         svn_wc__db_t *db,
-                         const char *local_abspath,
-                         apr_hash_t *actual_props,
+                         svn_boolean_t *did_merge,
                          const char *propname,
                          const svn_string_t *base_val,
                          const svn_string_t *old_val,
                          const svn_string_t *new_val,
+                         const svn_string_t *working_val,
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
@@ -1134,14 +1056,14 @@ apply_single_prop_change(svn_wc_notify_s
          gracefully' might thwart us.  If bogus mergeinfo is present we
          can't merge intelligently, so let the standard method deal with
          it instead. */
-      svn_error_t *err = apply_single_mergeinfo_prop_change(state,
+      svn_error_t *err = apply_single_mergeinfo_prop_change(result_val,
                                                             conflict_remains,
-                                                            db, local_abspath,
-                                                            actual_props,
+                                                            did_merge,
                                                             propname,
                                                             base_val,
                                                             old_val,
                                                             new_val,
+                                                            working_val,
                                                             result_pool,
                                                             scratch_pool);
        if (err)
@@ -1162,11 +1084,10 @@ apply_single_prop_change(svn_wc_notify_s
       /* The standard method: perform a simple update automatically, but
          pass any other kind of merge to maybe_generate_propconflict(). */
 
-      SVN_ERR(apply_single_generic_prop_change(state, conflict_remains,
-                                               db, local_abspath,
-                                               actual_props,
+      SVN_ERR(apply_single_generic_prop_change(result_val, conflict_remains,
+                                               did_merge,
                                                propname, base_val, old_val,
-                                               new_val,
+                                               new_val, working_val,
                                                result_pool, scratch_pool));
     }
 
@@ -1224,6 +1145,9 @@ svn_wc__merge_props(svn_skel_t **conflic
       const svn_string_t *base_val; /* Pristine in WC */
       const svn_string_t *from_val; /* Merge left */
       const svn_string_t *to_val; /* Merge right */
+      const svn_string_t *working_val; /* Mine */
+      const svn_string_t *result_val;
+      svn_boolean_t did_merge = FALSE;
 
       svn_pool_clear(iterpool);
 
@@ -1235,39 +1159,45 @@ svn_wc__merge_props(svn_skel_t **conflic
       from_val = apr_hash_get(server_baseprops, propname, APR_HASH_KEY_STRING);
 
       base_val = apr_hash_get(pristine_props, propname, APR_HASH_KEY_STRING);
+      working_val = apr_hash_get(actual_props, propname, APR_HASH_KEY_STRING);
 
       if (new_pristine_props)
         apr_hash_set(*new_pristine_props, propname, APR_HASH_KEY_STRING,
                      to_val);
 
       apr_hash_set(their_props, propname, APR_HASH_KEY_STRING, to_val);
+      
 
       /* We already know that state is at least `changed', so mark
          that, but remember that we may later upgrade to `merged' or
          even `conflicted'. */
       set_prop_merge_state(state, svn_wc_notify_state_changed);
 
+      result_val = working_val;
+
       if (! from_val)  /* adding a new property */
-        SVN_ERR(apply_single_prop_add(state, &conflict_remains,
-                                      db, local_abspath,
-                                      *new_actual_props,
-                                      propname, base_val, to_val,
+        SVN_ERR(apply_single_prop_add(&result_val, &conflict_remains,
+                                      &did_merge, propname,
+                                      base_val, to_val, working_val,
                                       result_pool, iterpool));
 
       else if (! to_val) /* delete an existing property */
-        SVN_ERR(apply_single_prop_delete(state, &conflict_remains,
-                                         db, local_abspath,
-                                         *new_actual_props,
-                                         propname, base_val, from_val,
+        SVN_ERR(apply_single_prop_delete(&result_val, &conflict_remains,
+                                         &did_merge, propname,
+                                         base_val, from_val, working_val,
                                          result_pool, iterpool));
 
       else  /* changing an existing property */
-        SVN_ERR(apply_single_prop_change(state, &conflict_remains,
-                                         db, local_abspath,
-                                         *new_actual_props,
-                                         propname, base_val, from_val, to_val,
+        SVN_ERR(apply_single_prop_change(&result_val, &conflict_remains,
+                                         &did_merge, propname,
+                                         base_val, from_val, to_val, working_val,
                                          result_pool, iterpool));
 
+      if (result_val != working_val)
+        apr_hash_set(*new_actual_props, propname, APR_HASH_KEY_STRING,
+                     result_val);
+      if (did_merge)
+        set_prop_merge_state(state, svn_wc_notify_state_merged);
 
       /* merging logic complete, now we need to possibly log conflict
          data to tmpfiles.  */

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/props.h?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/props.h Fri Dec 14 04:14:09 2012
@@ -37,18 +37,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-/* BASE_MERGE is a pre-1.7 concept on property merging. It allowed callers
-   to alter the pristine properties *outside* of an editor drive. That is
-   very dangerous: the pristines should always correspond to something from
-   the repository, and that should only arrive through the update editor.
-
-   For 1.7, we're removing this support. Some old code is being left around
-   in case we decide to change this.
-
-   For more information, see ^/notes/api-errata/1.7/wc006.txt
-*/
-#undef SVN__SUPPORT_BASE_MERGE
-
 /* Internal function for diffing props. See svn_wc_get_prop_diffs2(). */
 svn_error_t *
 svn_wc__internal_propdiff(apr_array_header_t **propchanges,
@@ -87,7 +75,7 @@ svn_wc__internal_propget(const svn_strin
    Append any conflicts of the actual props to *CONFLICT_SKEL.  (First
    allocate *CONFLICT_SKEL from RESULT_POOL if it is initially NULL.
    CONFLICT_SKEL itself must not be NULL.)  (Changes made to the pristine
-   properties, if BASE_MERGE is TRUE, do not generate conficts.)
+   properties, if NEW_PRISTINE_PROPS is non-null, do not generate conficts.)
 
    If STATE is non-null, set *STATE to the state of the local properties
    after the merge.  */
@@ -134,30 +122,6 @@ svn_wc__create_prejfile(const char **tmp
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
-
-/* Just like svn_wc_merge_props3(), but WITH a BASE_MERGE parameter.
-
-   If SVN__SUPPORT_BASE_MERGE is defined and BASE_MERGE is true, then
-   also use PROPCHANGES to modify the node's pristine properties.  (That
-   cannot generate conficts.)  If SVN__SUPPORT_BASE_MERGE is not defined
-   and BASE_MERGE is true, throw an error.
- */
-svn_error_t *
-svn_wc__perform_props_merge(svn_wc_notify_state_t *state,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            const svn_wc_conflict_version_t *left_version,
-                            const svn_wc_conflict_version_t *right_version,
-                            apr_hash_t *baseprops,
-                            const apr_array_header_t *propchanges,
-                            svn_boolean_t base_merge,
-                            svn_boolean_t dry_run,
-                            svn_wc_conflict_resolver_func2_t conflict_func,
-                            void *conflict_baton,
-                            svn_cancel_func_t cancel_func,
-                            void *cancel_baton,
-                            apr_pool_t *scratch_pool);
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/upgrade.c?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/upgrade.c Fri Dec 14 04:14:09 2012
@@ -1169,7 +1169,8 @@ bump_to_23(void *baton, svn_sqlite__db_t
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_HAS_WORKING_NODES));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_UPGRADE_23_HAS_WORKING_NODES));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_ERR(svn_sqlite__reset(stmt));
   if (have_row)

Modified: subversion/branches/in-repo-authz/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_wc/wc-metadata.sql?rev=1421664&r1=1421663&r2=1421664&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_wc/wc-metadata.sql Fri Dec 14 04:14:09 2012
@@ -181,8 +181,8 @@ CREATE TABLE ACTUAL_NODE (
   PRIMARY KEY (wc_id, local_relpath)
   );
 
-CREATE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath);
-CREATE INDEX I_ACTUAL_CHANGELIST ON ACTUAL_NODE (changelist);
+CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath,
+                                                    local_relpath);
 
 
 /* ------------------------------------------------------------------------- */
@@ -408,8 +408,11 @@ CREATE TABLE NODES (
   /* the kind of the new node. may be "unknown" if the node is not present. */
   kind  TEXT NOT NULL,
 
-  /* serialized skel of this node's properties. NULL if we
-     have no information about the properties (a non-present node). */
+  /* serialized skel of this node's properties (when presence is 'normal' or
+     'incomplete'); an empty skel or NULL indicates no properties.  NULL if
+     we have no information about the properties (any other presence).
+     TODO: Choose & require a single representation for 'no properties'.
+  */
   properties  BLOB,
 
   /* NULL depth means "default" (typically svn_depth_infinity) */
@@ -483,7 +486,8 @@ CREATE TABLE NODES (
 
   );
 
-CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, op_depth);
+CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath,
+                                             local_relpath, op_depth);
 /* I_NODES_MOVED is introduced in format 30 */
 CREATE UNIQUE INDEX I_NODES_MOVED ON NODES (wc_id, moved_to, op_depth);
 
@@ -553,7 +557,7 @@ CREATE TABLE EXTERNALS (
   /* Repository location fields */
   repos_id  INTEGER NOT NULL REFERENCES REPOSITORY (id),
 
-  /* Either 'normal' or 'excluded' */
+  /* Either MAP_NORMAL or MAP_EXCLUDED */
   presence  TEXT NOT NULL,
 
   /* the kind of the external. */
@@ -574,7 +578,6 @@ CREATE TABLE EXTERNALS (
   PRIMARY KEY (wc_id, local_relpath)
 );
 
-CREATE INDEX I_EXTERNALS_PARENT ON EXTERNALS (wc_id, parent_relpath);
 CREATE UNIQUE INDEX I_EXTERNALS_DEFINED ON EXTERNALS (wc_id,
                                                       def_local_relpath,
                                                       local_relpath);
@@ -667,6 +670,9 @@ PRAGMA user_version = 22;
 -- STMT_UPGRADE_TO_23
 PRAGMA user_version = 23;
 
+-- STMT_UPGRADE_23_HAS_WORKING_NODES
+SELECT 1 FROM nodes WHERE op_depth > 0
+LIMIT 1
 
 /* ------------------------------------------------------------------------- */
 
@@ -820,6 +826,8 @@ WHERE wc_id = ?1 and local_relpath = ?2
    inherited properties */
 -- STMT_UPGRADE_TO_31
 ALTER TABLE NODES ADD COLUMN inherited_props BLOB;
+DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST;
+DROP INDEX IF EXISTS I_EXTERNALS_PARENT;
 
 PRAGMA user_version = 31;
 
@@ -846,6 +854,23 @@ WHERE (l.local_relpath = '' AND l.repos_
                                  '/'))
 
 /* ------------------------------------------------------------------------- */
+/* Format 32 ....  */
+-- STMT_UPGRADE_TO_32
+
+/* Drop old index. ### Remove this part from the upgrade to 31 once bumped */
+DROP INDEX IF EXISTS I_ACTUAL_CHANGELIST;
+DROP INDEX IF EXISTS I_EXTERNALS_PARENT;
+CREATE INDEX I_EXTERNALS_PARENT ON EXTERNALS (wc_id, parent_relpath);
+
+DROP INDEX I_NODES_PARENT;
+CREATE UNIQUE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath,
+                                             local_relpath, op_depth);
+
+DROP INDEX I_ACTUAL_PARENT;
+CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL (wc_id, parent_relpath,
+                                               local_relpath);
+
+/* ------------------------------------------------------------------------- */
 
 /* Format YYY introduces new handling for conflict information.  */
 -- format: YYY
@@ -902,8 +927,8 @@ CREATE TABLE ACTUAL_NODE (
   PRIMARY KEY (wc_id, local_relpath)
   );
 
-CREATE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath);
-CREATE INDEX I_ACTUAL_CHANGELIST ON ACTUAL_NODE (changelist);
+CREATE UNIQUE INDEX I_ACTUAL_PARENT ON ACTUAL_NODE (wc_id, parent_relpath,
+                                                    local_relpath);
 
 INSERT INTO ACTUAL_NODE SELECT
   wc_id, local_relpath, parent_relpath, properties, conflict_old,