subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cmpil...@apache.org
Subject svn commit: r1414433 [2/4] - in /subversion/branches/issue-4194-dev: ./ build/ac-macros/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ subversion/libsvn_diff/ subversion/libsvn_fs_fs/ subversion/libs...
Date Tue, 27 Nov 2012 22:13:38 GMT
Modified: subversion/branches/issue-4194-dev/subversion/libsvn_diff/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_diff/util.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_diff/util.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_diff/util.c Tue Nov 27 22:13:24 2012
@@ -25,6 +25,10 @@
 #include <apr.h>
 #include <apr_general.h>
 
+#include "svn_pools.h"
+#include "svn_dirent_uri.h"
+#include "svn_props.h"
+#include "svn_mergeinfo.h"
 #include "svn_error.h"
 #include "svn_diff.h"
 #include "svn_types.h"
@@ -32,8 +36,12 @@
 #include "svn_utf.h"
 #include "svn_version.h"
 
+#include "private/svn_diff_private.h"
 #include "diff.h"
 
+#include "svn_private_config.h"
+
+
 svn_boolean_t
 svn_diff_contains_conflicts(svn_diff_t *diff)
 {
@@ -342,9 +350,8 @@ svn_diff__unified_append_no_newline_msg(
 
   SVN_ERR(svn_utf_cstring_from_utf8_ex2(
             &out_str,
-            /* The string below is intentionally not marked for translation,
-               for wider interoperability with patch(1) programs. */
-            APR_EOL_STR "\\ No newline at end of file" APR_EOL_STR,
+            APR_EOL_STR
+            SVN_DIFF__NO_NEWLINE_AT_END_OF_FILE APR_EOL_STR,
             header_encoding, scratch_pool));
   svn_stringbuf_appendcstr(stringbuf, out_str);
   return SVN_NO_ERROR;
@@ -411,6 +418,170 @@ svn_diff__unidiff_write_header(svn_strea
   return SVN_NO_ERROR;
 }
 
+/* A helper function for display_prop_diffs.  Output the differences between
+   the mergeinfo stored in ORIG_MERGEINFO_VAL and NEW_MERGEINFO_VAL in a
+   human-readable form to OUTSTREAM, using ENCODING.  Use POOL for temporary
+   allocations. */
+static svn_error_t *
+display_mergeinfo_diff(const char *old_mergeinfo_val,
+                       const char *new_mergeinfo_val,
+                       const char *encoding,
+                       svn_stream_t *outstream,
+                       apr_pool_t *pool)
+{
+  apr_hash_t *old_mergeinfo_hash, *new_mergeinfo_hash, *added, *deleted;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_hash_index_t *hi;
+
+  if (old_mergeinfo_val)
+    SVN_ERR(svn_mergeinfo_parse(&old_mergeinfo_hash, old_mergeinfo_val, pool));
+  else
+    old_mergeinfo_hash = NULL;
+
+  if (new_mergeinfo_val)
+    SVN_ERR(svn_mergeinfo_parse(&new_mergeinfo_hash, new_mergeinfo_val, pool));
+  else
+    new_mergeinfo_hash = NULL;
+
+  SVN_ERR(svn_mergeinfo_diff2(&deleted, &added, old_mergeinfo_hash,
+                              new_mergeinfo_hash,
+                              TRUE, pool, pool));
+
+  for (hi = apr_hash_first(pool, deleted);
+       hi; hi = apr_hash_next(hi))
+    {
+      const char *from_path = svn__apr_hash_index_key(hi);
+      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
+      svn_string_t *merge_revstr;
+
+      svn_pool_clear(iterpool);
+      SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray,
+                                      iterpool));
+
+      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
+                                          _("   Reverse-merged %s:r%s%s"),
+                                          from_path, merge_revstr->data,
+                                          APR_EOL_STR));
+    }
+
+  for (hi = apr_hash_first(pool, added);
+       hi; hi = apr_hash_next(hi))
+    {
+      const char *from_path = svn__apr_hash_index_key(hi);
+      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
+      svn_string_t *merge_revstr;
+
+      svn_pool_clear(iterpool);
+      SVN_ERR(svn_rangelist_to_string(&merge_revstr, merge_revarray,
+                                      iterpool));
+
+      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
+                                          _("   Merged %s:r%s%s"),
+                                          from_path, merge_revstr->data,
+                                          APR_EOL_STR));
+    }
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_diff__display_prop_diffs(svn_stream_t *outstream,
+                             const char *encoding,
+                             const apr_array_header_t *propchanges,
+                             apr_hash_t *original_props,
+                             svn_boolean_t pretty_print_mergeinfo,
+                             apr_pool_t *pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  int i;
+
+  for (i = 0; i < propchanges->nelts; i++)
+    {
+      const char *action;
+      const svn_string_t *original_value;
+      const svn_prop_t *propchange
+        = &APR_ARRAY_IDX(propchanges, i, svn_prop_t);
+
+      if (original_props)
+        original_value = apr_hash_get(original_props,
+                                      propchange->name, APR_HASH_KEY_STRING);
+      else
+        original_value = NULL;
+
+      /* If the property doesn't exist on either side, or if it exists
+         with the same value, skip it.  This can happen if the client is
+         hitting an old mod_dav_svn server that doesn't understand the
+         "send-all" REPORT style. */
+      if ((! (original_value || propchange->value))
+          || (original_value && propchange->value
+              && svn_string_compare(original_value, propchange->value)))
+        continue;
+
+      svn_pool_clear(iterpool);
+
+      if (! original_value)
+        action = "Added";
+      else if (! propchange->value)
+        action = "Deleted";
+      else
+        action = "Modified";
+      SVN_ERR(svn_stream_printf_from_utf8(outstream, encoding, iterpool,
+                                          "%s: %s%s", action,
+                                          propchange->name, APR_EOL_STR));
+
+      if (pretty_print_mergeinfo
+          && strcmp(propchange->name, SVN_PROP_MERGEINFO) == 0)
+        {
+          const char *orig = original_value ? original_value->data : NULL;
+          const char *val = propchange->value ? propchange->value->data : NULL;
+          svn_error_t *err = display_mergeinfo_diff(orig, val, encoding,
+                                                    outstream, iterpool);
+
+          /* Issue #3896: If we can't pretty-print mergeinfo differences
+             because invalid mergeinfo is present, then don't let the diff
+             fail, just print the diff as any other property. */
+          if (err && err->apr_err == SVN_ERR_MERGEINFO_PARSE_ERROR)
+            {
+              svn_error_clear(err);
+            }
+          else
+            {
+              SVN_ERR(err);
+              continue;
+            }
+        }
+
+      {
+        svn_diff_t *diff;
+        svn_diff_file_options_t options = { 0 };
+        const svn_string_t *orig
+          = original_value ? original_value
+                           : svn_string_create_empty(iterpool);
+        const svn_string_t *val
+          = propchange->value ? propchange->value
+                              : svn_string_create_empty(iterpool);
+
+        SVN_ERR(svn_diff_mem_string_diff(&diff, orig, val, &options,
+                                         iterpool));
+
+        /* UNIX patch will try to apply a diff even if the diff header
+         * is missing. It tries to be helpful by asking the user for a
+         * target filename when it can't determine the target filename
+         * from the diff header. But there usually are no files which
+         * UNIX patch could apply the property diff to, so we use "##"
+         * instead of "@@" as the default hunk delimiter for property diffs.
+         * We also supress the diff header. */
+        SVN_ERR(svn_diff_mem_string_output_unified2(
+                  outstream, diff, FALSE /* no header */, "##", NULL, NULL,
+                  encoding, orig, val, iterpool));
+      }
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* Return the library version number. */
 const svn_version_t *

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/fs_fs.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/fs_fs.c Tue Nov 27 22:13:24 2012
@@ -2238,8 +2238,10 @@ get_cached_node_revision_body(node_revis
     }
   else
     {
-      pair_cache_key_t key = { svn_fs_fs__id_rev(id),
-                               svn_fs_fs__id_offset(id) };
+      pair_cache_key_t key;
+
+      key.revision = svn_fs_fs__id_rev(id);
+      key.second = svn_fs_fs__id_offset(id);
       SVN_ERR(svn_cache__get((void **) noderev_p,
                             is_cached,
                             ffd->node_revision_cache,
@@ -2265,8 +2267,10 @@ set_cached_node_revision_body(node_revis
 
   if (ffd->node_revision_cache && !svn_fs_fs__id_txn_id(id))
     {
-      pair_cache_key_t key = { svn_fs_fs__id_rev(id),
-                               svn_fs_fs__id_offset(id) };
+      pair_cache_key_t key;
+
+      key.revision = svn_fs_fs__id_rev(id);
+      key.second = svn_fs_fs__id_offset(id);
       return svn_cache__set(ffd->node_revision_cache,
                             &key,
                             noderev_p,
@@ -3529,9 +3533,11 @@ parse_revprop(apr_hash_t **properties,
   SVN_ERR(svn_hash_read2(*properties, stream, SVN_HASH_TERMINATOR, pool));
   if (has_revprop_cache(fs, pool))
     {
-      pair_cache_key_t key = {revision, generation};
       fs_fs_data_t *ffd = fs->fsap_data;
+      pair_cache_key_t key;
 
+      key.revision = revision;
+      key.second = generation;
       SVN_ERR(svn_cache__set(ffd->revprop_cache, &key, *properties,
                              scratch_pool));
     }
@@ -3831,10 +3837,11 @@ get_revision_proplist(apr_hash_t **propl
   if (has_revprop_cache(fs, pool))
     {
       svn_boolean_t is_cached;
-      pair_cache_key_t key = { rev, 0};
+      pair_cache_key_t key;
 
       SVN_ERR(read_revprop_generation(&generation, fs, pool));
 
+      key.revision = rev;
       key.second = generation;
       SVN_ERR(svn_cache__get((void **) proplist_p, &is_cached,
                              ffd->revprop_cache, &key, pool));
@@ -5183,10 +5190,12 @@ read_representation(svn_stream_t **conte
   else
     {
       fs_fs_data_t *ffd = fs->fsap_data;
-      pair_cache_key_t fulltext_cache_key = {rep->revision, rep->offset};
+      pair_cache_key_t fulltext_cache_key;
       svn_filesize_t len = rep->expanded_size ? rep->expanded_size : rep->size;
       struct rep_read_baton *rb;
 
+      fulltext_cache_key.revision = rep->revision;
+      fulltext_cache_key.second = rep->offset;
       if (ffd->fulltext_cache && SVN_IS_VALID_REVNUM(rep->revision)
           && fulltext_size_is_cachable(ffd, len))
         {
@@ -5355,14 +5364,18 @@ svn_fs_fs__try_process_file_contents(svn
   if (rep)
     {
       fs_fs_data_t *ffd = fs->fsap_data;
-      pair_cache_key_t fulltext_cache_key = {rep->revision, rep->offset};
+      pair_cache_key_t fulltext_cache_key;
 
+      fulltext_cache_key.revision = rep->revision;
+      fulltext_cache_key.second = rep->offset;
       if (ffd->fulltext_cache && SVN_IS_VALID_REVNUM(rep->revision)
           && fulltext_size_is_cachable(ffd, rep->expanded_size))
         {
-          cache_access_wrapper_baton_t wrapper_baton = {processor, baton};
+          cache_access_wrapper_baton_t wrapper_baton;
           void *dummy = NULL;
 
+          wrapper_baton.func = processor;
+          wrapper_baton.baton = baton;
           return svn_cache__get_partial(&dummy, success,
                                         ffd->fulltext_cache,
                                         &fulltext_cache_key,
@@ -5658,8 +5671,10 @@ svn_fs_fs__get_proplist(apr_hash_t **pro
     {
       fs_fs_data_t *ffd = fs->fsap_data;
       representation_t *rep = noderev->prop_rep;
-      
-      pair_cache_key_t key = { rep->revision, rep->offset };
+      pair_cache_key_t key;
+
+      key.revision = rep->revision;
+      key.second = rep->offset;
       if (ffd->properties_cache && SVN_IS_VALID_REVNUM(rep->revision))
         {
           svn_boolean_t is_cached;

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.c Tue Nov 27 22:13:24 2012
@@ -88,27 +88,6 @@ svn_fs_fs__combine_number_and_string(apr
   return key;
 }
 
-const char*
-svn_fs_fs__combine_two_numbers(apr_int64_t a,
-                               apr_int64_t b,
-                               apr_pool_t *pool)
-{
-  /* encode numbers as 2x 10x7 bits + 1 space + 1 terminating \0*/
-  char *key_buffer = apr_palloc(pool, 22);
-  const char *key = key_buffer;
-
-  /* combine the numbers. Since the separator is disjoint from any part
-   * of the encoded numbers, there is no other combination that can yield
-   * the same result */
-  key_buffer = encode_number(a, key_buffer);
-  *++key_buffer = ' ';
-  key_buffer = encode_number(b, ++key_buffer);
-  *++key_buffer = '\0';
-
-  /* return the start of the key */
-  return key;
-}
-
 /* Utility function to serialize string S in the given serialization CONTEXT.
  */
 static void

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_fs_fs/temp_serializer.h Tue Nov 27 22:13:24 2012
@@ -36,16 +36,6 @@ svn_fs_fs__combine_number_and_string(apr
                                      apr_pool_t *pool);
 
 /**
- * Combine the numbers @a a and @a b in a space efficient way such that no
- * other combination of numbers can produce the same result.
- * Allocate temporaries as well as the result from @a pool.
- */
-const char*
-svn_fs_fs__combine_two_numbers(apr_int64_t a,
-                               apr_int64_t b,
-                               apr_pool_t *pool);
-
-/**
  * Serialize a @a noderev_p within the serialization @a context.
  */
 void

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/inherited_props.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/inherited_props.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/inherited_props.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/inherited_props.c Tue Nov 27 22:13:24 2012
@@ -277,8 +277,7 @@ svn_ra_serf__get_inherited_props(svn_ra_
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
 {
-  svn_error_t *err, *err2;
-
+  svn_error_t *err;
   iprops_context_t *iprops_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
@@ -293,6 +292,8 @@ svn_ra_serf__get_inherited_props(svn_ra_
                                       revision,
                                       result_pool, scratch_pool));
 
+  SVN_ERR_ASSERT(session->repos_root_str);
+
   iprops_ctx = apr_pcalloc(scratch_pool, sizeof(*iprops_ctx));
   iprops_ctx->done = FALSE;
   iprops_ctx->repos_root_url = session->repos_root_str;
@@ -329,20 +330,12 @@ svn_ra_serf__get_inherited_props(svn_ra_
   handler->response_handler = svn_ra_serf__handle_xml_parser;
   handler->response_baton = parser_ctx;
 
-  svn_ra_serf__request_create(handler);
-
-  err = svn_ra_serf__context_run_wait(&iprops_ctx->done, session,
-                                      scratch_pool);
-
-  err2 = svn_ra_serf__error_on_status(handler->sline.code, handler->path,
-                                      handler->location);
-  if (err2)
-    {
-      svn_error_clear(err);
-      return err2;
-    }
-
-  SVN_ERR(err);
+  err = svn_ra_serf__context_run_one(handler, scratch_pool);
+  SVN_ERR(svn_error_compose_create(
+                    svn_ra_serf__error_on_status(handler->sline.code,
+                                                 handler->path,
+                                                 handler->location),
+                    err));
 
   if (iprops_ctx->done)
     *iprops = iprops_ctx->iprops;

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/util.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_ra_serf/util.c Tue Nov 27 22:13:24 2012
@@ -657,6 +657,10 @@ setup_serf_req(serf_request_t *request,
       SVN_ERR(svn_ra_serf__copy_into_spillbuf(&buf, body_bkt,
                                               request_pool,
                                               scratch_pool));
+      /* Destroy original bucket since it content is already copied 
+         to spillbuf. */
+      serf_bucket_destroy(body_bkt);
+
       body_bkt = svn_ra_serf__create_sb_bucket(buf, allocator,
                                                request_pool,
                                                scratch_pool);

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_ra_svn/cyrus_auth.c Tue Nov 27 22:13:24 2012
@@ -871,12 +871,12 @@ svn_ra_svn__do_cyrus_auth(svn_ra_svn__se
 
   /* The username callback. */
   callbacks[0].id = SASL_CB_AUTHNAME;
-  callbacks[0].proc = (void*)get_username_cb;
+  callbacks[0].proc = (int (*)(void))get_username_cb;
   callbacks[0].context = &cred_baton;
 
   /* The password callback. */
   callbacks[1].id = SASL_CB_PASS;
-  callbacks[1].proc = (void*)get_password_cb;
+  callbacks[1].proc = (int (*)(void))get_password_cb;
   callbacks[1].context = &cred_baton;
 
   /* Mark the end of the array. */

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_repos/reporter.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_repos/reporter.c Tue Nov 27 22:13:24 2012
@@ -717,11 +717,13 @@ delta_files(report_baton_t *b, void *fil
              zero-copy code. */
           if (b->zero_copy_limit > 0 && s_path == NULL)
             {
-              zero_copy_baton_t baton = { b->zero_copy_limit
-                                        , dhandler
-                                        , dbaton
-                                        , FALSE};
+              zero_copy_baton_t baton;
               svn_boolean_t called = FALSE;
+
+              baton.zero_copy_limit = b->zero_copy_limit;
+              baton.dhandler = dhandler;
+              baton.dbaton = dbaton;
+              baton.zero_copy_succeeded = FALSE;
               SVN_ERR(svn_fs_try_process_file_contents(&called,
                                                        b->t_root, t_path,
                                                        send_zero_copy_delta,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/named_atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/named_atomic.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/named_atomic.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/named_atomic.c Tue Nov 27 22:13:24 2012
@@ -308,7 +308,7 @@ delete_lock_file(void *arg)
   const char *lock_name = NULL;
 
   /* locks have already been cleaned up. Simply close the file */
-  apr_file_close(mutex->lock_file);
+  apr_status_t status = apr_file_close(mutex->lock_file);
 
   /* Remove the file from disk. This will fail if there ares still other
    * users of this lock file, i.e. namespace. */
@@ -316,10 +316,12 @@ delete_lock_file(void *arg)
   if (lock_name)
     apr_file_remove(lock_name, mutex->pool);
 
-  return 0;
+  return status;
 }
 
-/* Validate the ATOMIC parameter, i.e it's address.
+/* Validate the ATOMIC parameter, i.e it's address.  Correct code will
+ * never need this but if someone should accidentally to use a NULL or
+ * incomplete structure, let's catch that here instead of segfaulting.
  */
 static svn_error_t *
 validate(svn_named_atomic__t *atomic)
@@ -416,7 +418,9 @@ svn_atomic_namespace__create(svn_atomic_
                            APR_OS_DEFAULT,
                            result_pool));
 
-  /* Make sure the last user of our lock file will actually remove it
+  /* Make sure the last user of our lock file will actually remove it.
+   * Please note that only the last file handle begin closed will actually
+   * remove the underlying file (see docstring for apr_file_remove).
    */
   apr_pool_cleanup_register(result_pool, &new_ns->mutex,
                             delete_lock_file,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/sqlite.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/sqlite.c Tue Nov 27 22:13:24 2012
@@ -168,7 +168,7 @@ exec_sql2(svn_sqlite__db_t *db, const ch
   if (sqlite_err != SQLITE_OK && sqlite_err != ignored_err)
     {
       svn_error_t *err = svn_error_createf(SQLITE_ERROR_CODE(sqlite_err), NULL,
-                                           _("%s, executing statement '%s'"),
+                                           _("sqlite: %s, executing statement '%s'"),
                                            err_msg, sql);
       sqlite3_free(err_msg);
       return err;
@@ -256,8 +256,8 @@ step_with_expectation(svn_sqlite__stmt_t
     return svn_error_create(SVN_ERR_SQLITE_ERROR,
                             svn_sqlite__reset(stmt),
                             expecting_row
-                              ? _("Expected database row missing")
-                              : _("Extra database row found"));
+                              ? _("sqlite: Expected database row missing")
+                              : _("sqlite: Extra database row found"));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/string.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/string.c Tue Nov 27 22:13:24 2012
@@ -37,30 +37,108 @@
 #include "svn_private_config.h"
 
 
-/* Our own realloc, since APR doesn't have one.  Note: this is a
-   generic realloc for memory pools, *not* for strings. */
-static void *
-my__realloc(char *data, apr_size_t oldsize, apr_size_t request,
-            apr_pool_t *pool)
-{
-  void *new_area;
-
-  /* kff todo: it's a pity APR doesn't give us this -- sometimes it
-     could realloc the block merely by extending in place, sparing us
-     a memcpy(), but only the pool would know enough to be able to do
-     this.  We should add a realloc() to APR if someone hasn't
-     already. */
-
-  /* malloc new area */
-  new_area = apr_palloc(pool, request);
 
-  /* copy data to new area */
-  memcpy(new_area, data, oldsize);
+/* Allocate the space for a memory buffer from POOL.
+ * Return a pointer to the new buffer in *DATA and its size in *SIZE.
+ * The buffer size will be at least MINIMUM_SIZE.
+ *
+ * N.B.: The stringbuf creation functions use this, but since stringbufs
+ *       always consume at least 1 byte for the NUL terminator, the
+ *       resulting data pointers will never be NULL.
+ */
+static APR_INLINE void
+membuf_create(void **data, apr_size_t *size,
+              apr_size_t minimum_size, apr_pool_t *pool)
+{
+  /* apr_palloc will allocate multiples of 8.
+   * Thus, we would waste some of that memory if we stuck to the
+   * smaller size. Note that this is safe even if apr_palloc would
+   * use some other aligment or none at all. */
+  minimum_size = APR_ALIGN_DEFAULT(minimum_size);
+  *data = (!minimum_size ? NULL : apr_palloc(pool, minimum_size));
+  *size = minimum_size;
+}
+
+/* Ensure that the size of a given memory buffer is at least MINIMUM_SIZE
+ * bytes. If *SIZE is already greater than or equal to MINIMUM_SIZE,
+ * this function does nothing.
+ *
+ * If *SIZE is 0, the allocated buffer size will be MINIMUM_SIZE
+ * rounded up to the nearest APR alignment boundary. Otherwse, *SIZE
+ * will be multiplied by a power of two such that the result is
+ * greater or equal to MINIMUM_SIZE. The pointer to the new buffer
+ * will be returned in *DATA, and its size in *SIZE.
+ */
+static APR_INLINE void
+membuf_ensure(void **data, apr_size_t *size,
+              apr_size_t minimum_size, apr_pool_t *pool)
+{
+  if (minimum_size > *size)
+    {
+      apr_size_t new_size = *size;
+
+      if (new_size == 0)
+        /* APR will increase odd allocation sizes to the next
+         * multiple for 8, for instance. Take advantage of that
+         * knowledge and allow for the extra size to be used. */
+        new_size = minimum_size;
+      else
+        while (new_size < minimum_size)
+          {
+            /* new_size is aligned; doubling it should keep it aligned */
+            const apr_size_t prev_size = new_size;
+            new_size *= 2;
+
+            /* check for apr_size_t overflow */
+            if (prev_size > new_size)
+              {
+                new_size = minimum_size;
+                break;
+              }
+          }
 
-  /* I'm NOT freeing old area here -- cuz we're using pools, ugh. */
+      membuf_create(data, size, new_size, pool);
+    }
+}
 
-  /* return new area */
-  return new_area;
+void
+svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool)
+{
+  membuf_create(&membuf->data, &membuf->size, size, pool);
+  membuf->pool = pool;
+}
+
+void
+svn_membuf__ensure(svn_membuf_t *membuf, apr_size_t size)
+{
+  membuf_ensure(&membuf->data, &membuf->size, size, membuf->pool);
+}
+
+void
+svn_membuf__resize(svn_membuf_t *membuf, apr_size_t size)
+{
+  const void *const old_data = membuf->data;
+  const apr_size_t old_size = membuf->size;
+
+  membuf_ensure(&membuf->data, &membuf->size, size, membuf->pool);
+  if (membuf->data && old_data && old_data != membuf->data)
+    memcpy(membuf->data, old_data, old_size);
+}
+
+/* Always provide an out-of-line implementation of svn_membuf__zero */
+#undef svn_membuf__zero
+void
+svn_membuf__zero(svn_membuf_t *membuf)
+{
+  SVN_MEMBUF__ZERO(membuf);
+}
+
+/* Always provide an out-of-line implementation of svn_membuf__nzero */
+#undef svn_membuf__nzero
+void
+svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size)
+{
+  SVN_MEMBUF__NZERO(membuf, size);
 }
 
 static APR_INLINE svn_boolean_t
@@ -283,28 +361,6 @@ svn_stringbuf__morph_into_string(svn_str
 
 /* svn_stringbuf functions */
 
-/* Create a stringbuf referring to (not copying) an existing block of memory
- * at DATA, of which SIZE bytes are the user data and BLOCKSIZE bytes are
- * allocated in total.  DATA[SIZE] must be a zero byte. */
-static svn_stringbuf_t *
-create_stringbuf(char *data, apr_size_t size, apr_size_t blocksize,
-                 apr_pool_t *pool)
-{
-  svn_stringbuf_t *new_string;
-
-  new_string = apr_palloc(pool, sizeof(*new_string));
-
-  SVN_ERR_ASSERT_NO_RETURN(size < blocksize);
-  SVN_ERR_ASSERT_NO_RETURN(data[size] == '\0');
-
-  new_string->data = data;
-  new_string->len = size;
-  new_string->blocksize = blocksize;
-  new_string->pool = pool;
-
-  return new_string;
-}
-
 svn_stringbuf_t *
 svn_stringbuf_create_empty(apr_pool_t *pool)
 {
@@ -317,24 +373,17 @@ svn_stringbuf_create_ensure(apr_size_t b
   void *mem;
   svn_stringbuf_t *new_string;
 
-  /* apr_palloc will allocate multiples of 8.
-   * Thus, we would waste some of that memory if we stuck to the
-   * smaller size. Note that this is safe even if apr_palloc would
-   * use some other aligment or none at all. */
-
   ++blocksize; /* + space for '\0' */
-  blocksize = APR_ALIGN_DEFAULT(blocksize);
 
   /* Allocate memory for svn_string_t and data in one chunk. */
-  mem = apr_palloc(pool, sizeof(*new_string) + blocksize);
+  membuf_create(&mem, &blocksize, blocksize + sizeof(*new_string), pool);
 
   /* Initialize header and string */
   new_string = mem;
-
   new_string->data = (char*)mem + sizeof(*new_string);
   new_string->data[0] = '\0';
   new_string->len = 0;
-  new_string->blocksize = blocksize;
+  new_string->blocksize = blocksize - sizeof(*new_string);
   new_string->pool = pool;
 
   return new_string;
@@ -375,9 +424,15 @@ svn_stringbuf_createv(apr_pool_t *pool, 
 {
   char *data = apr_pvsprintf(pool, fmt, ap);
   apr_size_t size = strlen(data);
+  svn_stringbuf_t *new_string;
+
+  new_string = apr_palloc(pool, sizeof(*new_string));
+  new_string->data = data;
+  new_string->len = size;
+  new_string->blocksize = size + 1;
+  new_string->pool = pool;
 
-  /* wrap an svn_stringbuf_t around the new data */
-  return create_stringbuf(data, size, size + 1, pool);
+  return new_string;
 }
 
 
@@ -444,38 +499,15 @@ svn_stringbuf_isempty(const svn_stringbu
 void
 svn_stringbuf_ensure(svn_stringbuf_t *str, apr_size_t minimum_size)
 {
+  void *mem = NULL;
   ++minimum_size;  /* + space for '\0' */
 
-  /* Keep doubling capacity until have enough. */
-  if (str->blocksize < minimum_size)
+  membuf_ensure(&mem, &str->blocksize, minimum_size, str->pool);
+  if (mem && mem != str->data)
     {
-      if (str->blocksize == 0)
-        /* APR will increase odd allocation sizes to the next
-         * multiple for 8, for instance. Take advantage of that
-         * knowledge and allow for the extra size to be used. */
-        str->blocksize = APR_ALIGN_DEFAULT(minimum_size);
-      else
-        while (str->blocksize < minimum_size)
-          {
-            /* str->blocksize is aligned;
-             * doubling it should keep it aligned */
-            apr_size_t prev_size = str->blocksize;
-            str->blocksize *= 2;
-
-            /* check for apr_size_t overflow */
-            if (prev_size > str->blocksize)
-              {
-                str->blocksize = minimum_size;
-                break;
-              }
-          }
-
-      str->data = (char *) my__realloc(str->data,
-                                       str->len + 1,
-                                       /* We need to maintain (and thus copy)
-                                          the trailing nul */
-                                       str->blocksize,
-                                       str->pool);
+      if (str->data)
+        memcpy(mem, str->data, str->len + 1);
+      str->data = mem;
     }
 }
 
@@ -1134,3 +1166,108 @@ svn__i64toa_sep(apr_int64_t number, char
   return apr_pstrdup(pool, buffer);
 }
 
+unsigned int
+svn_cstring__similarity(const char *stra, const char *strb,
+                        svn_membuf_t *buffer, apr_size_t *rlcs)
+{
+  svn_string_t stringa, stringb;
+  stringa.data = stra;
+  stringa.len = strlen(stra);
+  stringb.data = strb;
+  stringb.len = strlen(strb);
+  return svn_string__similarity(&stringa, &stringb, buffer, rlcs);
+}
+
+unsigned int
+svn_string__similarity(const svn_string_t *stringa,
+                       const svn_string_t *stringb,
+                       svn_membuf_t *buffer, apr_size_t *rlcs)
+{
+  const char *stra = stringa->data;
+  const char *strb = stringb->data;
+  const apr_size_t lena = stringa->len;
+  const apr_size_t lenb = stringb->len;
+  const apr_size_t total = lena + lenb;
+  const char *enda = stra + lena;
+  const char *endb = strb + lenb;
+  apr_size_t lcs = 0;
+
+  /* Skip the common prefix ... */
+  while (stra < enda && strb < endb && *stra == *strb)
+    {
+      ++stra; ++strb;
+      ++lcs;
+    }
+
+  /* ... and the common suffix */
+  while (stra < enda && strb < endb)
+    {
+      --enda; --endb;
+      if (*enda != *endb)
+        {
+          ++enda; ++endb;
+          break;
+        }
+
+      ++lcs;
+    }
+
+  if (stra < enda && strb < endb)
+    {
+      const apr_size_t resta = enda - stra;
+      const apr_size_t restb = endb - strb;
+      const apr_size_t slots = (resta > restb ? restb : resta);
+      apr_size_t *curr, *prev;
+      const char *pstr;
+
+      /* The outer loop must iterate on the longer string. */
+      if (resta < restb)
+        {
+          pstr = stra;
+          stra = strb;
+          strb = pstr;
+
+          pstr = enda;
+          enda = endb;
+          endb = pstr;
+        }
+
+      /* Allocate two columns in the LCS matrix
+         ### Optimize this to (slots + 2) instesd of 2 * (slots + 1) */
+      svn_membuf__ensure(buffer, 2 * (slots + 1) * sizeof(apr_size_t));
+      svn_membuf__nzero(buffer, (slots + 2) * sizeof(apr_size_t));
+      prev = buffer->data;
+      curr = prev + slots + 1;
+
+      /* Calculate LCS length of the remainder */
+      for (pstr = stra; pstr < enda; ++pstr)
+        {
+          int i;
+          for (i = 1; i <= slots; ++i)
+            {
+              if (*pstr == strb[i-1])
+                curr[i] = prev[i-1] + 1;
+              else
+                curr[i] = (curr[i-1] > prev[i] ? curr[i-1] : prev[i]);
+            }
+
+          /* Swap the buffers, making the previous one current */
+          {
+            apr_size_t *const temp = prev;
+            prev = curr;
+            curr = temp;
+          }
+        }
+
+      lcs += prev[slots];
+    }
+
+  if (rlcs)
+    *rlcs = lcs;
+
+  /* Return similarity ratio rounded to 4 significant digits */
+  if (total)
+    return(unsigned int)((2000 * lcs + total/2) / total);
+  else
+    return 1000;
+}

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/temp_serializer.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/temp_serializer.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/temp_serializer.c Tue Nov 27 22:13:24 2012
@@ -86,11 +86,11 @@ align_buffer_end(svn_temp_serializer__co
 {
   apr_size_t current_len = context->buffer->len;
   apr_size_t aligned_len = APR_ALIGN_DEFAULT(current_len);
-  if (aligned_len != current_len)
-    {
-      svn_stringbuf_ensure(context->buffer, aligned_len);
-      context->buffer->len = aligned_len;
-    }
+
+  if (aligned_len + 1 > context->buffer->blocksize)
+    svn_stringbuf_ensure(context->buffer, aligned_len);
+
+   context->buffer->len = aligned_len;
 }
 
 /* Begin the serialization process for the SOURCE_STRUCT and all objects

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crashrpt.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crashrpt.c Tue Nov 27 22:13:24 2012
@@ -21,6 +21,9 @@
  * ====================================================================
  */
 
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_crashrpt__dummy;
+
 #ifdef WIN32
 #ifdef SVN_USE_WIN32_CRASHHANDLER
 

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crypto.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_crypto.c Tue Nov 27 22:13:24 2012
@@ -21,6 +21,9 @@
  * ====================================================================
  */
 
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_crypto__dummy;
+
 /* ==================================================================== */
 
 #if defined(WIN32) && !defined(__MINGW32__)

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_xlate.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_xlate.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_xlate.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_subr/win32_xlate.c Tue Nov 27 22:13:24 2012
@@ -21,6 +21,9 @@
  * ====================================================================
  */
 
+/* prevent "empty compilation unit" warning on e.g. UNIX */
+typedef int win32_xlate__dummy;
+
 #ifdef WIN32
 
 /* Define _WIN32_DCOM for CoInitializeEx(). */

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/deprecated.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/deprecated.c Tue Nov 27 22:13:24 2012
@@ -3196,6 +3196,38 @@ svn_wc_get_actual_target(const char *pat
   return svn_error_trace(svn_wc_context_destroy(wc_ctx));
 }
 
+/* This function has no internal variant as its behavior on switched
+   non-directories is not what you would expect. But this happens to
+   be the legacy behavior of this function. */
+svn_error_t *
+svn_wc_is_wc_root2(svn_boolean_t *wc_root,
+                   svn_wc_context_t *wc_ctx,
+                   const char *local_abspath,
+                   apr_pool_t *scratch_pool)
+{
+  svn_boolean_t is_root;
+  svn_boolean_t is_switched;
+  svn_kind_t kind;
+  svn_error_t *err;
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+  err = svn_wc__check_wc_root(&is_root, &kind, &is_switched,
+                              wc_ctx->db, local_abspath, scratch_pool);
+
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND &&
+          err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
+        return svn_error_trace(err);
+
+      return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, err, err->message);
+    }
+
+  *wc_root = is_root || (kind == svn_kind_dir && is_switched);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc_is_wc_root(svn_boolean_t *wc_root,
                   const char *path,

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/lock.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/lock.c Tue Nov 27 22:13:24 2012
@@ -1066,75 +1066,21 @@ child_is_disjoint(svn_boolean_t *disjoin
                   const char *local_abspath,
                   apr_pool_t *scratch_pool)
 {
-  const char *node_repos_root, *node_repos_relpath, *node_repos_uuid;
-  const char *parent_repos_root, *parent_repos_relpath, *parent_repos_uuid;
-  svn_wc__db_status_t parent_status;
-  const char *parent_abspath, *base;
+  svn_boolean_t is_switched;
 
   /* Check if the parent directory knows about this node */
-  SVN_ERR(svn_wc__db_is_wcroot(disjoint, db, local_abspath, scratch_pool));
+  SVN_ERR(svn_wc__db_is_switched(disjoint, &is_switched, NULL,
+                                 db, local_abspath, scratch_pool));
 
   if (*disjoint)
     return SVN_NO_ERROR;
 
-  svn_dirent_split(&parent_abspath, &base, local_abspath, scratch_pool);
-
-  SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &node_repos_relpath,
-                               &node_repos_root, &node_repos_uuid, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               db, local_abspath,
-                               scratch_pool, scratch_pool));
-
-  /* If the node does not have its own repos_relpath, its value is inherited
-     from a parent node, which implies that the node is not disjoint. */
-  if (node_repos_relpath == NULL)
-    {
-      *disjoint = FALSE;
-      return SVN_NO_ERROR;
-    }
-
-  SVN_ERR(svn_wc__db_read_info(&parent_status, NULL, NULL,
-                               &parent_repos_relpath, &parent_repos_root,
-                               &parent_repos_uuid, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               db, parent_abspath,
-                               scratch_pool, scratch_pool));
-
-  if (parent_repos_relpath == NULL)
-    {
-      if (parent_status == svn_wc__db_status_added)
-        SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &parent_repos_relpath,
-                                         &parent_repos_root,
-                                         &parent_repos_uuid,
-                                         NULL, NULL, NULL, NULL, NULL, NULL,
-                                         db, parent_abspath,
-                                         scratch_pool, scratch_pool));
-      else
-        SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,
-                                           &parent_repos_root,
-                                           &parent_repos_uuid,
-                                           db, parent_abspath,
-                                           scratch_pool, scratch_pool));
-    }
-
-  if (strcmp(parent_repos_root, node_repos_root) != 0 ||
-      strcmp(parent_repos_uuid, node_repos_uuid) != 0 ||
-      strcmp(svn_relpath_join(parent_repos_relpath, base, scratch_pool),
-             node_repos_relpath) != 0)
-    {
-      *disjoint = TRUE;
-    }
-  else
-    *disjoint = FALSE;
+  if (is_switched)
+    *disjoint = TRUE;
 
   return SVN_NO_ERROR;
 }
 
-
 /* */
 static svn_error_t *
 open_anchor(svn_wc_adm_access_t **anchor_access,
@@ -1522,13 +1468,25 @@ svn_wc__acquire_write_lock(const char **
                            apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
+  svn_boolean_t is_wcroot;
+  svn_boolean_t is_switched;
   svn_kind_t kind;
   svn_error_t *err;
 
-  SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
-                               (lock_root_abspath != NULL) /* allow_missing*/,
-                               FALSE /* show_hidden */,
-                               scratch_pool));
+  err = svn_wc__db_is_switched(&is_wcroot, &is_switched, &kind,
+                               db, local_abspath, scratch_pool);
+
+  if (err)
+    {
+      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+        return svn_error_trace(err);
+
+      svn_error_clear(err);
+
+      kind = svn_kind_none;
+      is_wcroot = FALSE;
+      is_switched = FALSE;
+    }
 
   if (!lock_root_abspath && kind != svn_kind_dir)
     return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,
@@ -1538,15 +1496,6 @@ svn_wc__acquire_write_lock(const char **
 
   if (lock_anchor && kind == svn_kind_dir)
     {
-      svn_boolean_t is_wcroot;
-
-      SVN_ERR_ASSERT(lock_root_abspath != NULL);
-
-      /* Perform a cheap check to avoid looking for a parent working copy,
-         which might be very expensive in some specific scenarios */
-      SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
-                                   scratch_pool));
-
       if (is_wcroot)
         lock_anchor = FALSE;
     }
@@ -1554,58 +1503,48 @@ svn_wc__acquire_write_lock(const char **
   if (lock_anchor)
     {
       const char *parent_abspath;
-      svn_kind_t parent_kind;
-
       SVN_ERR_ASSERT(lock_root_abspath != NULL);
 
       parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-      err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
-                                 TRUE /* allow_missing */,
-                                 FALSE /* show_missing */,
-                                 scratch_pool);
-      if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+
+      if (kind == svn_kind_dir)
         {
-          svn_error_clear(err);
-          parent_kind = svn_kind_unknown;
+          if (! is_switched)
+            local_abspath = parent_abspath;
+        }
+      else if (kind != svn_kind_none && kind != svn_kind_unknown)
+        {
+          /* In the single-DB world we know parent exists */
+          local_abspath = parent_abspath;
         }
       else
-        SVN_ERR(err);
-
-      if (kind == svn_kind_dir && parent_kind == svn_kind_dir)
         {
-          svn_boolean_t disjoint;
-          SVN_ERR(child_is_disjoint(&disjoint, wc_ctx->db, local_abspath,
-                                    scratch_pool));
-          if (!disjoint)
-            local_abspath = parent_abspath;
+          /* Can't lock parents that don't exist */
+          svn_kind_t parent_kind;
+          err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
+                                     TRUE /* allow_missing */,
+                                     FALSE /* show_hidden */,
+                                     scratch_pool);
+          if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+            {
+              svn_error_clear(err);
+              parent_kind = svn_kind_unknown;
+            }
+          else
+            SVN_ERR(err);
+
+          if (parent_kind != svn_kind_dir)
+            return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
+                                     _("'%s' is not a working copy"),
+                                     svn_dirent_local_style(local_abspath,
+                                                            scratch_pool));
+
+          local_abspath = parent_abspath;
         }
-      else if (parent_kind == svn_kind_dir)
-        local_abspath = parent_abspath;
-      else if (kind != svn_kind_dir)
-        return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
-                                 _("'%s' is not a working copy"),
-                                 svn_dirent_local_style(local_abspath,
-                                                        scratch_pool));
     }
   else if (kind != svn_kind_dir)
     {
       local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
-      /* Can't lock parents that don't exist */
-      if (kind == svn_kind_unknown)
-        {
-          SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
-                                       FALSE /* allow_missing */,
-                                       FALSE /* show_hidden */,
-                                       scratch_pool));
-
-          if (kind != svn_kind_dir)
-            return svn_error_createf(
-                             SVN_ERR_WC_NOT_DIRECTORY, NULL,
-                             _("Can't obtain lock on non-directory '%s'."),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-        }
     }
 
   if (lock_root_abspath)

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/props.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/props.c Tue Nov 27 22:13:24 2012
@@ -2338,129 +2338,6 @@ svn_wc__has_magic_property(const apr_arr
   return FALSE;
 }
 
-/* Remove all prop name value pairs from PROP_HASH where the property
-   name is not PROPNAME. */
-static void
-filter_unwanted_props(apr_hash_t *prop_hash,
-                      const char * propname,
-                      apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-
-  for (hi = apr_hash_first(scratch_pool, prop_hash);
-       hi;
-       hi = apr_hash_next(hi))
-    {
-      const char *ipropname = svn__apr_hash_index_key(hi);
-
-      if (strcmp(ipropname, propname) != 0)
-        apr_hash_set(prop_hash, ipropname, APR_HASH_KEY_STRING, NULL);
-    }
-  return;
-}
-
-svn_error_t *
-svn_wc__internal_get_iprops(apr_array_header_t **inherited_props,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            const char *propname,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
-{
-  int i;
-  apr_array_header_t *cached_iprops = NULL;
-  const char *parent_abspath = local_abspath;
-  svn_boolean_t is_wc_root = FALSE;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
-  SVN_ERR_ASSERT(inherited_props);
-  *inherited_props = apr_array_make(result_pool, 1,
-                                    sizeof(svn_prop_inherited_item_t *));
-
-  /* Walk up to the root of the WC looking for inherited properties.  When we
-     reach the WC root also check for cached inherited properties. */
-  while (TRUE)
-    {
-      apr_hash_t *actual_props;
-
-      svn_pool_clear(iterpool);
-
-      SVN_ERR(svn_wc__internal_is_wc_root(&is_wc_root, db, parent_abspath,
-                                          iterpool));
-
-      if (is_wc_root)
-        {
-          /* If the WC root is also the root of the repository then by
-             definition there are no inheritable properties to be had,
-             but checking for that is just as expensive as fetching them
-             anyway. */
-
-          /* Grab the cached inherited properties for the WC root. */
-          SVN_ERR(svn_wc__db_read_cached_iprops(&cached_iprops, db,
-                                                parent_abspath,
-                                                scratch_pool, iterpool));
-        }
-
-      /* If PARENT_ABSPATH is a true parent of LOCAL_ABSPATH, then
-         LOCAL_ABSPATH can inherit properties from it. */
-      if (strcmp(local_abspath, parent_abspath) != 0)
-        {
-          SVN_ERR(svn_wc__db_read_props(&actual_props, db, parent_abspath,
-                                        result_pool, iterpool));
-          if (actual_props)
-            {
-              /* If we only want PROPNAME filter out any other properties. */
-              if (propname)
-                filter_unwanted_props(actual_props, propname, iterpool);
-
-              if (apr_hash_count(actual_props))
-                {
-                  svn_prop_inherited_item_t *iprop_elt =
-                    apr_pcalloc(result_pool,
-                                sizeof(svn_prop_inherited_item_t));
-                  iprop_elt->path_or_url = apr_pstrdup(result_pool,
-                                                       parent_abspath);
-                  iprop_elt->prop_hash = actual_props;
-                  /* Build the output array in depth-first order. */
-                  svn_sort__array_insert(&iprop_elt, *inherited_props, 0);
-                }
-            }
-        }
-
-      /* Inheritance only goes as far as the nearest WC root. */
-      if (is_wc_root)
-        break;
-
-      /* Keep looking for the WC root. */
-      parent_abspath = svn_dirent_dirname(parent_abspath, scratch_pool);
-    }
-
-  if (cached_iprops)
-    {
-      for (i = cached_iprops->nelts - 1; i >= 0; i--)
-        {
-          svn_prop_inherited_item_t *cached_iprop =
-            APR_ARRAY_IDX(cached_iprops, i, svn_prop_inherited_item_t *);
-
-          /* An empty property hash in the iprops cache means there are no
-             inherited properties. */
-          if (apr_hash_count(cached_iprop->prop_hash) == 0)
-            continue;
-
-          if (propname)
-            filter_unwanted_props(cached_iprop->prop_hash, propname,
-                                  scratch_pool);
-
-          /* If we didn't filter everything then keep this iprop. */
-          if (apr_hash_count(cached_iprop->prop_hash))
-            svn_sort__array_insert(&cached_iprop, *inherited_props, 0);
-        }
-    }
-
-  svn_pool_destroy(iterpool);
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_wc__get_iprops(apr_array_header_t **inherited_props,
                    svn_wc_context_t *wc_ctx,
@@ -2469,9 +2346,11 @@ svn_wc__get_iprops(apr_array_header_t **
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_wc__internal_get_iprops(inherited_props, wc_ctx->db,
-                                               local_abspath, propname,
-                                               result_pool, scratch_pool));
+  return svn_error_trace(
+            svn_wc__db_read_inherited_props(inherited_props,
+                                            wc_ctx->db, local_abspath,
+                                            propname,
+                                            result_pool, scratch_pool));
 }
 
 svn_error_t *

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/status.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/status.c Tue Nov 27 22:13:24 2012
@@ -1028,9 +1028,10 @@ collect_ignore_patterns(apr_array_header
                                      FALSE, result_pool);      
         }
 
-      SVN_ERR(svn_wc__internal_get_iprops(&inherited_props, db, local_abspath,
-                                          SVN_PROP_INHERITABLE_IGNORES,
-                                          scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__db_read_inherited_props(&inherited_props,
+                                              db, local_abspath,
+                                              SVN_PROP_INHERITABLE_IGNORES,
+                                              scratch_pool, scratch_pool));
       for (i = 0; i < inherited_props->nelts; i++)
         {
           apr_hash_index_t *hi;

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/update_editor.c?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/update_editor.c Tue Nov 27 22:13:24 2012
@@ -3975,6 +3975,7 @@ close_file(void *file_baton,
   apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */
   svn_boolean_t keep_recorded_info = FALSE;
   const svn_checksum_t *new_checksum;
+  apr_array_header_t *iprops = NULL;
 
   if (fb->skip_this)
     {
@@ -4299,6 +4300,22 @@ close_file(void *file_baton,
                                         scratch_pool);
     }
 
+  /* Any inherited props to be set set for this base node? */
+  if (eb->wcroot_iprops)
+    {
+      iprops = apr_hash_get(eb->wcroot_iprops, fb->local_abspath,
+                            APR_HASH_KEY_STRING);
+
+      /* close_edit may also update iprops for switched nodes, catching
+         those for which close_directory is never called (e.g. a switch
+         with no changes).  So as a minor optimization we remove any
+         iprops from the hash so as not to set them again in
+         close_edit. */
+      if (iprops)
+        apr_hash_set(eb->wcroot_iprops, fb->local_abspath,
+                     APR_HASH_KEY_STRING, NULL);
+    }
+
   SVN_ERR(svn_wc__db_base_add_file(eb->db, fb->local_abspath,
                                    eb->wcroot_abspath,
                                    fb->new_relpath,
@@ -4317,6 +4334,7 @@ close_file(void *file_baton,
                                    (fb->add_existed && fb->adding_file),
                                    (! fb->shadowed) && new_base_props,
                                    new_actual_props,
+                                   iprops,
                                    keep_recorded_info,
                                    (fb->shadowed && fb->obstruction_found),
                                    conflict_skel,
@@ -4998,147 +5016,25 @@ svn_wc__check_wc_root(svn_boolean_t *wc_
                       const char *local_abspath,
                       apr_pool_t *scratch_pool)
 {
-  const char *parent_abspath, *name;
-  const char *repos_relpath, *repos_root, *repos_uuid;
-  svn_wc__db_status_t status;
-  svn_kind_t my_kind;
-
-  if (!kind)
-    kind = &my_kind;
-
-  /* Initialize our return values to the most common (code-wise) values. */
-  *wc_root = TRUE;
-  if (switched)
-    *switched = FALSE;
-
-  SVN_ERR(svn_wc__db_read_info(&status, kind, NULL, &repos_relpath,
-                               &repos_root, &repos_uuid, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL,
-                               db, local_abspath,
-                               scratch_pool, scratch_pool));
-
-  if (repos_relpath == NULL)
-    {
-      /* If we inherit our URL, then we can't be a root, nor switched.  */
-      *wc_root = FALSE;
-      return SVN_NO_ERROR;
-    }
-  if (*kind != svn_kind_dir)
-    {
-      /* File/symlinks cannot be a root.  */
-      *wc_root = FALSE;
-    }
-  else if (status == svn_wc__db_status_added
-           || status == svn_wc__db_status_deleted)
-    {
-      *wc_root = FALSE;
-    }
-  else if (status == svn_wc__db_status_server_excluded
-           || status == svn_wc__db_status_excluded
-           || status == svn_wc__db_status_not_present)
-    {
-      return svn_error_createf(
-                    SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                    _("The node '%s' was not found."),
-                    svn_dirent_local_style(local_abspath, scratch_pool));
-    }
-  else if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
-    return SVN_NO_ERROR;
-
-  if (!*wc_root && switched == NULL )
-    return SVN_NO_ERROR; /* No more info needed */
-
-  svn_dirent_split(&parent_abspath, &name, local_abspath, scratch_pool);
-
-  /* Check if the node is recorded in the parent */
-  if (*wc_root)
-    {
-      svn_boolean_t is_root;
-      SVN_ERR(svn_wc__db_is_wcroot(&is_root, db, local_abspath, scratch_pool));
-
-      if (is_root)
-        {
-          /* We're not in the (versioned) parent directory's list of
-             children, so we must be the root of a distinct working copy.  */
-          return SVN_NO_ERROR;
-        }
-    }
-
-  {
-    const char *parent_repos_root;
-    const char *parent_repos_relpath;
-    const char *parent_repos_uuid;
-
-    SVN_ERR(svn_wc__db_scan_base_repos(&parent_repos_relpath,
-                                       &parent_repos_root,
-                                       &parent_repos_uuid,
-                                       db, parent_abspath,
-                                       scratch_pool, scratch_pool));
-
-    if (strcmp(repos_root, parent_repos_root) != 0
-        || strcmp(repos_uuid, parent_repos_uuid) != 0)
-      {
-        /* This should never happen (### until we get mixed-repos working
-           copies). If we're in the parent, then we should be from the
-           same repository. For this situation, just declare us the root
-           of a separate, unswitched working copy.  */
-        return SVN_NO_ERROR;
-      }
-
-    *wc_root = FALSE;
-
-    if (switched)
-      {
-        const char *expected_relpath = svn_relpath_join(parent_repos_relpath,
-                                                        name, scratch_pool);
-
-        *switched = (strcmp(expected_relpath, repos_relpath) != 0);
-      }
-    }
-
-  return SVN_NO_ERROR;
+  return svn_error_trace(
+            svn_wc__db_is_switched(wc_root, switched, kind,
+                                   db, local_abspath,
+                                   scratch_pool));
 }
 
 svn_error_t *
-svn_wc__internal_is_wc_root(svn_boolean_t *wc_root,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            apr_pool_t *scratch_pool)
+svn_wc_check_root(svn_boolean_t *is_wcroot,
+                  svn_boolean_t *is_switched,
+                  svn_kind_t *kind,
+                  svn_wc_context_t *wc_ctx,
+                  const char *local_abspath,
+                  apr_pool_t *scratch_pool)
 {
-  svn_boolean_t is_root;
-  svn_boolean_t is_switched;
-  svn_kind_t kind;
-  svn_error_t *err;
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  err = svn_wc__check_wc_root(&is_root, &kind, &is_switched,
-                              db, local_abspath, scratch_pool);
-
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND &&
-          err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
-        return svn_error_trace(err);
-
-      return svn_error_create(SVN_ERR_ENTRY_NOT_FOUND, err, err->message);
-    }
-
-  *wc_root = is_root || is_switched;
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc_is_wc_root2(svn_boolean_t *wc_root,
-                   svn_wc_context_t *wc_ctx,
-                   const char *local_abspath,
-                   apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_wc__internal_is_wc_root(wc_root, wc_ctx->db,
-                                                     local_abspath,
-                                                     scratch_pool));
+  return svn_error_trace(svn_wc__db_is_switched(is_wcroot,is_switched, kind,
+                                                wc_ctx->db, local_abspath,
+                                                scratch_pool));
 }
 
 svn_error_t*

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc-queries.sql?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc-queries.sql Tue Nov 27 22:13:24 2012
@@ -29,7 +29,7 @@
 -- STMT_SELECT_NODE_INFO
 SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
-  symlink_target, last_mod_time, properties, moved_here
+  symlink_target, last_mod_time, properties, moved_here, inherited_props
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2
 ORDER BY op_depth DESC
@@ -38,6 +38,7 @@ ORDER BY op_depth DESC
 SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, moved_here,
+  inherited_props,
   /* All the columns until now must match those returned by
      STMT_SELECT_NODE_INFO. The implementation of svn_wc__db_read_info()
      assumes that these columns are followed by the lock information) */
@@ -798,9 +799,9 @@ INSERT OR REPLACE INTO nodes (
   wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
   revision, presence, depth, kind, changed_revision, changed_date,
   changed_author, checksum, properties, dav_cache, symlink_target,
-  file_external )
+  inherited_props, file_external )
 VALUES (?1, ?2, 0,
-        ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16,
+        ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17,
         (SELECT file_external FROM nodes
           WHERE wc_id = ?1
             AND local_relpath = ?2
@@ -1444,22 +1445,29 @@ SET inherited_props = ?3
 WHERE (wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0)
 
 /* Select a single path if its base node has cached inherited properties. */
--- STMT_SELECT_INODES
-SELECT local_relpath FROM nodes
+-- STMT_SELECT_IPROPS_NODE
+SELECT local_relpath, repos_path FROM nodes
 WHERE wc_id = ?1
   AND local_relpath = ?2
   AND op_depth = 0
   AND (inherited_props not null)
 
-/* Select all paths whose base nodes at or below a given path, which
+/* Select all paths whose base nodes are below a given path, which
    have cached inherited properties. */
--- STMT_SELECT_INODES_RECURSIVE
-SELECT local_relpath FROM nodes
+-- STMT_SELECT_IPROPS_RECURSIVE
+SELECT local_relpath, repos_path FROM nodes
 WHERE wc_id = ?1
   AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND op_depth = 0
   AND (inherited_props not null)
 
+-- STMT_SELECT_IPROPS_CHILDREN
+SELECT local_relpath, repos_path FROM nodes
+WHERE wc_id = ?1
+  AND parent_relpath = ?2
+  AND op_depth = 0
+  AND (inherited_props not null)
+
 /* ------------------------------------------------------------------------- */
 
 /* Grab all the statements related to the schema.  */

Modified: subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc.h?rev=1414433&r1=1414432&r2=1414433&view=diff
==============================================================================
--- subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/issue-4194-dev/subversion/libsvn_wc/wc.h Tue Nov 27 22:13:24 2012
@@ -607,23 +607,6 @@ svn_wc__internal_get_repos_relpath(const
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool);
 
-/* Internal version of svn_wc__get_iprops() */
-svn_error_t *
-svn_wc__internal_get_iprops(apr_array_header_t **inherited_props,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            const char *propname,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool);
-
-/* Internal version of svn_wc_is_wc_root2() */
-svn_error_t *
-svn_wc__internal_is_wc_root(svn_boolean_t *wc_root,
-                            svn_wc__db_t *db,
-                            const char *local_abspath,
-                            apr_pool_t *scratch_pool);
-
-
 /* Upgrade the wc sqlite database given in SDB for the wc located at
    WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT.
    After the upgrade is complete (to as far as the automatic upgrade will



Mime
View raw message