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 2014/04/30 01:36:46 UTC

svn commit: r1591144 [3/5] - in /subversion/branches/1.8.x-r1536931: ./ build/ build/ac-macros/ build/generator/ subversion/bindings/javahl/native/ subversion/bindings/swig/ subversion/bindings/swig/perl/native/ subversion/bindings/swig/ruby/libsvn_swi...

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_repos/reporter.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_repos/reporter.c Tue Apr 29 23:36:43 2014
@@ -1143,7 +1143,8 @@ delta_dirs(report_baton_t *b, svn_revnum
   svn_fs_root_t *s_root;
   apr_hash_t *s_entries = NULL, *t_entries;
   apr_hash_index_t *hi;
-  apr_pool_t *subpool;
+  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *iterpool;
   const char *name, *s_fullpath, *t_fullpath, *e_fullpath;
   path_info_t *info;
 
@@ -1152,7 +1153,8 @@ delta_dirs(report_baton_t *b, svn_revnum
 
      When we support directory locks, we must pass the lock token here. */
   SVN_ERR(delta_proplists(b, s_rev, start_empty ? NULL : s_path, t_path,
-                          NULL, change_dir_prop, dir_baton, pool));
+                          NULL, change_dir_prop, dir_baton, subpool));
+  svn_pool_clear(subpool);
 
   if (requested_depth > svn_depth_empty
       || requested_depth == svn_depth_unknown)
@@ -1161,19 +1163,19 @@ delta_dirs(report_baton_t *b, svn_revnum
       if (s_path && !start_empty)
         {
           SVN_ERR(get_source_root(b, &s_root, s_rev));
-          SVN_ERR(svn_fs_dir_entries(&s_entries, s_root, s_path, pool));
+          SVN_ERR(svn_fs_dir_entries(&s_entries, s_root, s_path, subpool));
         }
-      SVN_ERR(svn_fs_dir_entries(&t_entries, b->t_root, t_path, pool));
+      SVN_ERR(svn_fs_dir_entries(&t_entries, b->t_root, t_path, subpool));
 
       /* Iterate over the report information for this directory. */
-      subpool = svn_pool_create(pool);
+      iterpool = svn_pool_create(pool);
 
       while (1)
         {
           const svn_fs_dirent_t *s_entry, *t_entry;
 
-          svn_pool_clear(subpool);
-          SVN_ERR(fetch_path_info(b, &name, &info, e_path, subpool));
+          svn_pool_clear(iterpool);
+          SVN_ERR(fetch_path_info(b, &name, &info, e_path, iterpool));
           if (!name)
             break;
 
@@ -1193,10 +1195,10 @@ delta_dirs(report_baton_t *b, svn_revnum
               continue;
             }
 
-          e_fullpath = svn_relpath_join(e_path, name, subpool);
-          t_fullpath = svn_fspath__join(t_path, name, subpool);
+          e_fullpath = svn_relpath_join(e_path, name, iterpool);
+          t_fullpath = svn_fspath__join(t_path, name, iterpool);
           t_entry = svn_hash_gets(t_entries, name);
-          s_fullpath = s_path ? svn_fspath__join(s_path, name, subpool) : NULL;
+          s_fullpath = s_path ? svn_fspath__join(s_path, name, iterpool) : NULL;
           s_entry = s_entries ?
             svn_hash_gets(s_entries, name) : NULL;
 
@@ -1216,7 +1218,7 @@ delta_dirs(report_baton_t *b, svn_revnum
                                  t_entry, dir_baton, e_fullpath, info,
                                  info ? info->depth
                                       : DEPTH_BELOW_HERE(wc_depth),
-                                 DEPTH_BELOW_HERE(requested_depth), subpool));
+                                 DEPTH_BELOW_HERE(requested_depth), iterpool));
 
           /* Don't revisit this name in the target or source entries. */
           svn_hash_sets(t_entries, name, NULL);
@@ -1236,13 +1238,13 @@ delta_dirs(report_baton_t *b, svn_revnum
          target, for graceful handling of case-only renames. */
       if (s_entries)
         {
-          for (hi = apr_hash_first(pool, s_entries);
+          for (hi = apr_hash_first(subpool, s_entries);
                hi;
                hi = apr_hash_next(hi))
             {
               const svn_fs_dirent_t *s_entry;
 
-              svn_pool_clear(subpool);
+              svn_pool_clear(iterpool);
               s_entry = svn__apr_hash_index_val(hi);
 
               if (svn_hash_gets(t_entries, s_entry->name) == NULL)
@@ -1259,27 +1261,29 @@ delta_dirs(report_baton_t *b, svn_revnum
                     continue;
 
                   /* There is no corresponding target entry, so delete. */
-                  e_fullpath = svn_relpath_join(e_path, s_entry->name, subpool);
+                  e_fullpath = svn_relpath_join(e_path, s_entry->name, iterpool);
                   SVN_ERR(svn_repos_deleted_rev(svn_fs_root_fs(b->t_root),
                                                 svn_fspath__join(t_path,
                                                                  s_entry->name,
-                                                                 subpool),
+                                                                 iterpool),
                                                 s_rev, b->t_rev,
-                                                &deleted_rev, subpool));
+                                                &deleted_rev, iterpool));
 
                   SVN_ERR(b->editor->delete_entry(e_fullpath,
                                                   deleted_rev,
-                                                  dir_baton, subpool));
+                                                  dir_baton, iterpool));
                 }
             }
         }
 
       /* Loop over the dirents in the target. */
-      for (hi = apr_hash_first(pool, t_entries); hi; hi = apr_hash_next(hi))
+      for (hi = apr_hash_first(subpool, t_entries);
+           hi;
+           hi = apr_hash_next(hi))
         {
           const svn_fs_dirent_t *s_entry, *t_entry;
 
-          svn_pool_clear(subpool);
+          svn_pool_clear(iterpool);
           t_entry = svn__apr_hash_index_val(hi);
 
           if (is_depth_upgrade(wc_depth, requested_depth, t_entry->kind))
@@ -1307,24 +1311,27 @@ delta_dirs(report_baton_t *b, svn_revnum
                   svn_hash_gets(s_entries, t_entry->name)
                   : NULL;
               s_fullpath = s_entry ?
-                  svn_fspath__join(s_path, t_entry->name, subpool) : NULL;
+                  svn_fspath__join(s_path, t_entry->name, iterpool) : NULL;
             }
 
           /* Compose the report, editor, and target paths for this entry. */
-          e_fullpath = svn_relpath_join(e_path, t_entry->name, subpool);
-          t_fullpath = svn_fspath__join(t_path, t_entry->name, subpool);
+          e_fullpath = svn_relpath_join(e_path, t_entry->name, iterpool);
+          t_fullpath = svn_fspath__join(t_path, t_entry->name, iterpool);
 
           SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
                                t_entry, dir_baton, e_fullpath, NULL,
                                DEPTH_BELOW_HERE(wc_depth),
                                DEPTH_BELOW_HERE(requested_depth),
-                               subpool));
+                               iterpool));
         }
 
 
       /* Destroy iteration subpool. */
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(iterpool);
     }
+
+  svn_pool_destroy(subpool);
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/auth.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/auth.c Tue Apr 29 23:36:43 2014
@@ -35,6 +35,7 @@
 #include "svn_private_config.h"
 #include "svn_dso.h"
 #include "svn_version.h"
+#include "private/svn_auth_private.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_subr_private.h"
 
@@ -540,6 +541,11 @@ svn_auth_get_platform_specific_provider(
         {
           svn_auth_get_windows_ssl_server_trust_provider(provider, pool);
         }
+      else if (strcmp(provider_name, "windows") == 0 &&
+          strcmp(provider_type, "ssl_server_authority") == 0)
+        {
+          svn_auth__get_windows_ssl_server_authority_provider(provider, pool);
+        }
 #endif
     }
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-membuffer.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-membuffer.c Tue Apr 29 23:36:43 2014
@@ -422,7 +422,7 @@ struct svn_membuffer_t
    */
   apr_uint64_t current_data;
 
-  /* Total number of data buffer bytes in use. This is for statistics only.
+  /* Total number of data buffer bytes in use.
    */
   apr_uint64_t data_used;
 
@@ -1374,7 +1374,11 @@ membuffer_cache_set_internal(svn_membuff
    * the old spot, just re-use that space. */
   if (entry && ALIGN_VALUE(entry->size) >= size && buffer)
     {
-      cache->data_used += size - entry->size;
+      /* Careful! We need to cast SIZE to the full width of CACHE->DATA_USED
+       * lest we run into trouble with 32 bit underflow *not* treated as a
+       * negative value.
+       */
+      cache->data_used += (apr_uint64_t)size - entry->size;
       entry->size = size;
 
 #ifdef SVN_DEBUG_CACHE_MEMBUFFER

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-memcache.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cache-memcache.c Tue Apr 29 23:36:43 2014
@@ -203,9 +203,10 @@ memcache_get(void **value_p,
         }
       else
         {
-          svn_string_t *value = apr_pcalloc(result_pool, sizeof(*value));
+          svn_stringbuf_t *value = svn_stringbuf_create_empty(result_pool);
           value->data = data;
-          value->len = data_len;
+          value->blocksize = data_len;
+          value->len = data_len - 1; /* account for trailing NUL */
           *value_p = value;
         }
     }
@@ -263,7 +264,7 @@ memcache_set(void *cache_void,
     {
       svn_stringbuf_t *value_str = value;
       data = value_str->data;
-      data_len = value_str->len;
+      data_len = value_str->len + 1; /* copy trailing NUL */
     }
 
   err = memcache_internal_set(cache_void, key, data, data_len, subpool);

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cmdline.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/cmdline.c Tue Apr 29 23:36:43 2014
@@ -505,7 +505,7 @@ svn_cmdline_create_auth_baton(svn_auth_b
   svn_auth_get_username_provider(&provider, pool);
   APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
 
-  /* The server-cert, client-cert, and client-cert-password providers. */
+  /* The windows ssl server certificate CRYPTOAPI provider. */
   SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
                                                   "windows",
                                                   "ssl_server_trust",
@@ -514,6 +514,15 @@ svn_cmdline_create_auth_baton(svn_auth_b
   if (provider)
     APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
 
+  /* The windows ssl authority certificate CRYPTOAPI provider. */
+  SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
+                                                  "windows",
+                                                  "ssl_server_authority",
+                                                  pool));
+
+  if (provider)
+    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
+
   svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
   APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
   svn_auth_get_ssl_client_cert_file_provider(&provider, pool);

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/config_file.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/config_file.c Tue Apr 29 23:36:43 2014
@@ -69,7 +69,7 @@ typedef struct parse_context_t
 
   /* Parser buffer for getc() to avoid call overhead into several libraries
      for every character */
-  char parser_buffer[SVN_STREAM_CHUNK_SIZE]; /* Larger than most config files */
+  char parser_buffer[SVN__STREAM_CHUNK_SIZE]; /* Larger than most config files */
   size_t buffer_pos; /* Current position within parser_buffer */
   size_t buffer_size; /* parser_buffer contains this many bytes */
 } parse_context_t;

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/io.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/io.c Tue Apr 29 23:36:43 2014
@@ -1243,32 +1243,44 @@ svn_io_sleep_for_timestamps(const char *
         {
           /* Very simplistic but safe approach:
               If the filesystem has < sec mtime we can be reasonably sure
-              that the filesystem has <= millisecond precision.
+              that the filesystem has some sub-second resolution.  On Windows
+              it is likely to be sub-millisecond; on Linux systems it depends
+              on the filesystem, ext4 is typically 1ms, 4ms or 10ms resolution.
 
              ## Perhaps find a better algorithm here. This will fail once
-                in every 1000 cases on a millisecond precision filesystem.
+                in every 1000 cases on a millisecond precision filesystem
+                if the mtime happens to be an exact second.
 
                 But better to fail once in every thousand cases than every
                 time, like we did before.
-                (All tested filesystems I know have at least microsecond precision.)
 
              Note for further research on algorithm:
-               FAT32 has < 1 sec precision on ctime, but 2 sec on mtime */
+               FAT32 has < 1 sec precision on ctime, but 2 sec on mtime.
 
-          /* Sleep for at least 1 millisecond.
-             (t < 1000 will be round to 0 in apr) */
-          apr_sleep(1000);
+               Linux/ext4 with CONFIG_HZ=250 has high resolution
+               apr_time_now and although the filesystem timestamps
+               have similar high precision they are only updated with
+               a coarser 4ms resolution. */
 
-          return;
+          /* 10 milliseconds after now. */
+#ifndef SVN_HI_RES_SLEEP_MS
+#define SVN_HI_RES_SLEEP_MS 10
+#endif
+          then = now + apr_time_from_msec(SVN_HI_RES_SLEEP_MS);
         }
 
-      now = apr_time_now(); /* Extract the time used for the path stat */
-
-      if (now >= then)
-        return; /* Passing negative values may suspend indefinitely (Windows) */
+      /* Remove time taken to do stat() from sleep. */
+      now = apr_time_now();
     }
 
-  apr_sleep(then - now);
+  if (now >= then)
+    return; /* Passing negative values may suspend indefinitely (Windows) */
+
+  /* (t < 1000 will be round to 0 in apr) */
+  if (then - now < 1000)
+    apr_sleep(1000);
+  else
+    apr_sleep(then - now);
 }
 
 
@@ -1533,14 +1545,9 @@ io_set_file_perms(const char *path,
     {
       if (enable_write) /* Make read-write. */
         {
-          apr_file_t *fd;
-
-          /* Get the perms for the original file so we'll have any other bits
-           * that were already set (like the execute bits, for example). */
-          SVN_ERR(svn_io_file_open(&fd, path, APR_READ,
-                                   APR_OS_DEFAULT, pool));
-          SVN_ERR(merge_default_file_perms(fd, &perms_to_set, pool));
-          SVN_ERR(svn_io_file_close(fd, pool));
+          /* Tweak the owner bits only. The group/other bits aren't safe to
+           * touch because we may end up setting them in undesired ways. */
+          perms_to_set |= (APR_UREAD|APR_UWRITE);
         }
       else
         {
@@ -4289,7 +4296,7 @@ contents_three_identical_p(svn_boolean_t
 
       /* As long as a file is not at the end yet, and it is still
        * potentially identical to another file, we read the next chunk.*/
-      if (!eof1 && (identical_p12 || identical_p13))
+      if (!eof1 && (*identical_p12 || *identical_p13))
         {
           err = svn_io_file_read_full2(file1_h, buf1,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read1,
@@ -4299,7 +4306,7 @@ contents_three_identical_p(svn_boolean_t
           read_1 = TRUE;
         }
 
-      if (!eof2 && (identical_p12 || identical_p23))
+      if (!eof2 && (*identical_p12 || *identical_p23))
         {
           err = svn_io_file_read_full2(file2_h, buf2,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read2,
@@ -4309,7 +4316,7 @@ contents_three_identical_p(svn_boolean_t
           read_2 = TRUE;
         }
 
-      if (!eof3 && (identical_p13 || identical_p23))
+      if (!eof3 && (*identical_p13 || *identical_p23))
         {
           err = svn_io_file_read_full2(file3_h, buf3,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read3,

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/prompt.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/prompt.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/prompt.c Tue Apr 29 23:36:43 2014
@@ -177,7 +177,7 @@ terminal_open(terminal_handle_t **termin
      and stderr for prompting. */
   apr_file_t *tmpfd;
   status = apr_file_open(&tmpfd, "/dev/tty",
-                         APR_FOPEN_READ | APR_FOPEN_WRITE,
+                         APR_READ | APR_WRITE,
                          APR_OS_DEFAULT, pool);
   *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
   if (!status)

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite.c Tue Apr 29 23:36:43 2014
@@ -778,6 +778,21 @@ internal_open(sqlite3 **db3, const char 
        somebody initialized SQLite before us it is needed anyway.  */
     flags |= SQLITE_OPEN_NOMUTEX;
 
+#if !defined(WIN32) && !defined(SVN_SQLITE_INLINE)
+    if (mode == svn_sqlite__mode_rwcreate)
+      {
+        svn_node_kind_t kind;
+
+        /* Create the file before SQLite to avoid any permissions
+           problems with an SQLite build that uses the default
+           SQLITE_DEFAULT_FILE_PERMISSIONS of 644 modified by umask.
+           We simply want umask permissions. */
+        SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+        if (kind == svn_node_none)
+          SVN_ERR(svn_io_file_create(path, "", scratch_pool));
+      }
+#endif
+
     /* Open the database. Note that a handle is returned, even when an error
        occurs (except for out-of-memory); thus, we can safely use it to
        extract an error message and construct an svn_error_t. */
@@ -887,6 +902,18 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
 
   SVN_ERR(internal_open(&(*db)->db3, path, mode, scratch_pool));
 
+#if SQLITE_VERSION_NUMBER >= 3008000 && SQLITE_VERSION_NUMBER < 3009000
+  /* disable SQLITE_ENABLE_STAT3/4 from 3.8.1 - 3.8.3 (but not 3.8.3.1+)
+   * to prevent using it when it's buggy.
+   * See: https://www.sqlite.org/src/info/4c86b126f2 */
+  if (sqlite3_libversion_number() > 3008000 &&
+      sqlite3_libversion_number() < 3008004 &&
+      strcmp(sqlite3_sourceid(),"2014-02-11")<0)
+    {
+      sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, (*db)->db3, 0x800);
+    }
+#endif
+
 #ifdef SQLITE3_DEBUG
   sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
 #endif
@@ -918,7 +945,13 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
               /* Enable recursive triggers so that a user trigger will fire
                  in the deletion phase of an INSERT OR REPLACE statement.
                  Requires SQLite >= 3.6.18  */
-              "PRAGMA recursive_triggers=ON;"));
+              "PRAGMA recursive_triggers=ON;"
+              /* Enforce current Sqlite default behavior. Some distributions
+                 might change the Sqlite defaults without realizing how this
+                 affects application(read: Subversion) performance/behavior. */
+              "PRAGMA foreign_keys=OFF;"      /* SQLITE_DEFAULT_FOREIGN_KEYS*/
+              "PRAGMA locking_mode = NORMAL;" /* SQLITE_DEFAULT_LOCKING_MODE */
+              ));
 
 #if defined(SVN_DEBUG)
   /* When running in debug mode, enable the checking of foreign key
@@ -927,6 +960,14 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
   SVN_ERR(exec_sql(*db, "PRAGMA foreign_keys=ON;"));
 #endif
 
+#ifdef SVN_SQLITE_REVERSE_UNORDERED_SELECTS
+  /* When enabled, this PRAGMA causes SELECT statements without an ORDER BY
+     clause to emit their results in the reverse order of what they normally
+     would.  This can help detecting invalid assumptions about the result
+     order.*/
+  SVN_ERR(exec_sql(*db, "PRAGMA reverse_unordered_selects=ON;"));
+#endif
+
   /* Store temporary tables in RAM instead of in temporary files, but don't
      fail on this if this option is disabled in the sqlite compilation by
      setting SQLITE_TEMP_STORE to 0 (always to disk) */

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite3wrapper.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite3wrapper.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite3wrapper.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sqlite3wrapper.c Tue Apr 29 23:36:43 2014
@@ -50,6 +50,7 @@
 #      undef inline
 #    endif
 #  endif
+#  define SQLITE_DEFAULT_FILE_PERMISSIONS 0666
 #  include <sqlite3.c>
 #  if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))
 #    pragma GCC diagnostic pop

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/subst.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/subst.c Tue Apr 29 23:36:43 2014
@@ -1702,9 +1702,19 @@ create_special_file_from_stream(svn_stre
      ### this only writes the first line!
   */
   if (create_using_internal_representation)
-    SVN_ERR(svn_io_write_unique(&dst_tmp, svn_dirent_dirname(dst, pool),
-                                contents->data, contents->len,
-                                svn_io_file_del_none, pool));
+    {
+      apr_file_t *new_file;
+      SVN_ERR(svn_io_open_unique_file3(&new_file, &dst_tmp,
+                                       svn_dirent_dirname(dst, pool),
+                                       svn_io_file_del_none,
+                                       pool, pool));
+
+      SVN_ERR(svn_io_file_write_full(new_file,
+                                     contents->data, contents->len, NULL,
+                                     pool));
+
+      SVN_ERR(svn_io_file_close(new_file, pool));
+    }
 
   /* Do the atomic rename from our temporary location. */
   return svn_io_file_rename(dst_tmp, dst, pool);

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sysinfo.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/sysinfo.c Tue Apr 29 23:36:43 2014
@@ -290,11 +290,21 @@ stringbuf_split_key(svn_stringbuf_t *buf
     return NULL;
 
   svn_stringbuf_strip_whitespace(buffer);
+
+  /* Now we split the currently allocated buffer in two parts:
+      - a const char * HEAD
+      - the remaining stringbuf_t. */
+
+  /* Create HEAD as '\0' terminated const char * */
   key = buffer->data;
   end = strchr(key, delim);
   *end = '\0';
-  buffer->len = 1 + end - key;
+
+  /* And update the TAIL to be a smaller, but still valid stringbuf */
   buffer->data = end + 1;
+  buffer->len -= 1 + end - key;
+  buffer->blocksize -= 1 + end - key;
+
   svn_stringbuf_strip_whitespace(buffer);
 
   return key;
@@ -1012,6 +1022,7 @@ release_name_from_version(const char *os
     case 6: return "Snow Leopard";
     case 7: return "Lion";
     case 8: return "Mountain Lion";
+    case 9: return "Mavericks";
     }
 
   return NULL;

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/version.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/version.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/version.c Tue Apr 29 23:36:43 2014
@@ -136,7 +136,7 @@ svn_version_extended(svn_boolean_t verbo
   info->build_time = __TIME__;
   info->build_host = SVN_BUILD_HOST;
   info->copyright = apr_pstrdup
-    (pool, _("Copyright (C) 2013 The Apache Software Foundation.\n"
+    (pool, _("Copyright (C) 2014 The Apache Software Foundation.\n"
              "This software consists of contributions made by many people;\n"
              "see the NOTICE file for more information.\n"
              "Subversion is open source software, see "

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/win32_crypto.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_subr/win32_crypto.c Tue Apr 29 23:36:43 2014
@@ -436,8 +436,9 @@ windows_ssl_server_trust_first_credentia
                                            const char *realmstring,
                                            apr_pool_t *pool)
 {
-  apr_uint32_t *failures = svn_hash_gets(parameters,
-                                         SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
+  apr_uint32_t *failure_ptr = svn_hash_gets(parameters,
+                                            SVN_AUTH_PARAM_SSL_SERVER_FAILURES);
+  apr_uint32_t failures = *failure_ptr;
   const svn_auth_ssl_server_cert_info_t *cert_info =
     svn_hash_gets(parameters, SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO);
 
@@ -445,7 +446,7 @@ windows_ssl_server_trust_first_credentia
   *iter_baton = NULL;
 
   /* We can accept only unknown certificate authority. */
-  if (*failures & SVN_AUTH_SSL_UNKNOWNCA)
+  if (failures & SVN_AUTH_SSL_UNKNOWNCA)
     {
       svn_boolean_t ok;
 
@@ -455,15 +456,16 @@ windows_ssl_server_trust_first_credentia
       if (ok)
         {
           /* Clear failure flag. */
-          *failures &= ~SVN_AUTH_SSL_UNKNOWNCA;
+          failures &= ~SVN_AUTH_SSL_UNKNOWNCA;
         }
     }
 
   /* If all failures are cleared now, we return the creds */
-  if (! *failures)
+  if (! failures)
     {
       svn_auth_cred_ssl_server_trust_t *creds =
         apr_pcalloc(pool, sizeof(*creds));
+      creds->accepted_failures = *failure_ptr & ~failures;
       creds->may_save = FALSE; /* No need to save it. */
       *credentials = creds;
     }
@@ -489,4 +491,24 @@ svn_auth_get_windows_ssl_server_trust_pr
   *provider = po;
 }
 
+static const svn_auth_provider_t windows_server_authority_provider = {
+    SVN_AUTH_CRED_SSL_SERVER_AUTHORITY,
+    windows_ssl_server_trust_first_credentials,
+    NULL,
+    NULL,
+};
+
+/* Public API */
+void
+svn_auth__get_windows_ssl_server_authority_provider(
+                            svn_auth_provider_object_t **provider,
+                            apr_pool_t *pool)
+{
+    svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
+
+    po->vtable = &windows_server_authority_provider;
+    *provider = po;
+}
+
+
 #endif /* WIN32 */

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/conflicts.h?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/conflicts.h Tue Apr 29 23:36:43 2014
@@ -401,14 +401,18 @@ svn_wc__conflict_create_markers(svn_skel
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool);
 
-/* Call the interactive conflict resolver RESOLVER_FUNC with RESOLVER_BATON to
-   allow resolving the conflicts on LOCAL_ABSPATH.
+/* Call the conflict resolver RESOLVER_FUNC with RESOLVER_BATON for each
+   of the conflicts on LOCAL_ABSPATH.  Depending on the results that
+   the callback returns, perhaps resolve the conflicts, and perhaps mark
+   them as resolved in the WC DB.
 
    Call RESOLVER_FUNC once for each property conflict, and again for any
    text conflict, and again for any tree conflict on the node.
 
    CONFLICT_SKEL contains the details of the conflicts on LOCAL_ABSPATH.
 
+   Use MERGE_OPTIONS when the resolver requests a merge.
+
    Resolver actions are directly applied to the in-db state of LOCAL_ABSPATH,
    so the conflict and the state in CONFLICT_SKEL must already be installed in
    wc.db. */

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff.h?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff.h (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff.h Tue Apr 29 23:36:43 2014
@@ -38,7 +38,9 @@
 extern "C" {
 #endif /* __cplusplus */
 
-/* Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
+/* A function to diff locally added and locally copied files.
+  
+   Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
    PROCESSOR with as parent baton PROCESSOR_PARENT_BATON.
 
    The node is expected to have status svn_wc__db_status_normal, or
@@ -61,7 +63,9 @@ svn_wc__diff_local_only_file(svn_wc__db_
                              void *cancel_baton,
                              apr_pool_t *scratch_pool);
 
-/* Reports the directory LOCAL_ABSPATH and everything below it (limited by
+/* A function to diff locally added and locally copied directories.
+  
+   Reports the directory LOCAL_ABSPATH and everything below it (limited by
    DEPTH) as added with relpath RELPATH to PROCESSOR with as parent baton
    PROCESSOR_PARENT_BATON.
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff_local.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/diff_local.c Tue Apr 29 23:36:43 2014
@@ -116,13 +116,20 @@ ensure_state(struct diff_baton *eb,
   apr_pool_t *ns_pool;
   if (!eb->cur)
     {
-      if (!svn_dirent_is_ancestor(eb->anchor_abspath, local_abspath))
+      const char *relpath;
+
+      relpath = svn_dirent_skip_ancestor(eb->anchor_abspath, local_abspath);
+      if (! relpath)
         return SVN_NO_ERROR;
 
-      SVN_ERR(ensure_state(eb,
-                           svn_dirent_dirname(local_abspath,scratch_pool),
-                           FALSE,
-                           scratch_pool));
+      /* Don't recurse on the anchor, as that might loop infinately because
+            svn_dirent_dirname("/",...)   -> "/"
+            svn_dirent_dirname("C:/",...) -> "C:/" (Windows) */
+      if (*relpath)
+        SVN_ERR(ensure_state(eb,
+                             svn_dirent_dirname(local_abspath,scratch_pool),
+                             FALSE,
+                             scratch_pool));
     }
   else if (svn_dirent_is_child(eb->cur->local_abspath, local_abspath, NULL))
     SVN_ERR(ensure_state(eb, svn_dirent_dirname(local_abspath,scratch_pool),
@@ -391,7 +398,7 @@ diff_status_callback(void *baton,
           }
       }
 
-    if (local_only)
+    if (local_only && (db_status != svn_wc__db_status_deleted))
       {
         if (db_kind == svn_node_file)
           SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/status.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/status.c Tue Apr 29 23:36:43 2014
@@ -421,13 +421,42 @@ get_repos_root_url_relpath(const char **
                                        db, local_abspath,
                                        result_pool, scratch_pool));
     }
-  else if (info->have_base)
+  else if (info->status == svn_wc__db_status_deleted
+           && !info->have_more_work
+           && info->have_base)
     {
       SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, repos_root_url,
                                          repos_uuid,
                                          db, local_abspath,
                                          result_pool, scratch_pool));
     }
+  else if (info->status == svn_wc__db_status_deleted)
+    {
+      const char *work_del_abspath;
+      const char *add_abspath;
+
+      /* Handles working DELETE and the special case where there is just
+         svn_wc__db_status_not_present in WORKING */
+
+      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+
+      /* The parent of what has been deleted must be added */
+      add_abspath = svn_dirent_dirname(work_del_abspath, scratch_pool);
+
+      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath,
+                                       repos_root_url, repos_uuid, NULL,
+                                       NULL, NULL, NULL,
+                                       db, add_abspath,
+                                       result_pool, scratch_pool));
+
+      *repos_relpath = svn_relpath_join(*repos_relpath,
+                                        svn_dirent_skip_ancestor(
+                                              add_abspath,
+                                              local_abspath),
+                                        result_pool);
+    }
   else
     {
       *repos_relpath = NULL;

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/upgrade.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/upgrade.c Tue Apr 29 23:36:43 2014
@@ -1958,6 +1958,10 @@ svn_wc__upgrade_sdb(int *result_format,
       case SVN_WC__VERSION:
         /* already upgraded */
         *result_format = SVN_WC__VERSION;
+
+        SVN_SQLITE__WITH_LOCK(
+            svn_wc__db_install_schema_statistics(sdb, scratch_pool),
+            sdb);
     }
 
 #ifdef SVN_DEBUG

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-metadata.sql?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-metadata.sql Tue Apr 29 23:36:43 2014
@@ -573,6 +573,57 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED 
                                                       local_relpath);
 
 /* ------------------------------------------------------------------------- */
+/* This statement provides SQLite with the necessary information about our
+   indexes to make better decisions in the query planner.
+
+   For every interesting index this contains a number of rows where the
+   statistics ar calculated for and then for every column in the index the
+   average number of rows with the same value in all columns left of this
+   column including the column itself.
+
+   See http://www.sqlite.org/fileformat2.html#stat1tab for more details.
+
+   The important thing here is that this tells Sqlite that the wc_id column
+   of the NODES and ACTUAL_NODE table is usually a single value, so queries
+   should use more than one column for index usage.
+
+   The current hints describe NODES+ACTUAL_NODE as a working copy with
+   8000 nodes in 1 a single working copy(=wc_id), 10 nodes per directory
+   and an average of 2 op-depth layers per node.
+
+   The number of integers must be number of index columns + 1, which is
+   verified via the test_schema_statistics() test.
+ */
+-- STMT_INSTALL_SCHEMA_STATISTICS
+ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */
+
+DELETE FROM sqlite_stat1
+WHERE tbl in ('NODES', 'ACTUAL_NODE', 'LOCK', 'WC_LOCK');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('NODES', 'sqlite_autoindex_NODES_1',               '8000 8000 2 1');
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('NODES', 'I_NODES_PARENT',                         '8000 8000 10 2 1');
+/* Tell a lie: We ignore that 99.9% of all moved_to values are NULL */
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('NODES', 'I_NODES_MOVED',                          '8000 8000 1 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('ACTUAL_NODE', 'sqlite_autoindex_ACTUAL_NODE_1',   '8000 8000 1');
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('ACTUAL_NODE', 'I_ACTUAL_PARENT',                  '8000 8000 10 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('LOCK', 'sqlite_autoindex_LOCK_1',                 '100 100 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+    ('WC_LOCK', 'sqlite_autoindex_WC_LOCK_1',           '100 100 1');
+
+/* sqlite_autoindex_WORK_QUEUE_1 doesn't exist because WORK_QUEUE is
+   a INTEGER PRIMARY KEY AUTOINCREMENT table */
+
+ANALYZE sqlite_master; /* Loads sqlite_stat1 data for query optimizer */
+/* ------------------------------------------------------------------------- */
 
 /* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-queries.sql?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc-queries.sql Tue Apr 29 23:36:43 2014
@@ -1503,7 +1503,6 @@ WHERE wc_id = ?1
   AND presence=MAP_NORMAL
   AND file_external IS NULL
 
-/* ### FIXME: op-depth?  What about multiple moves? */
 -- STMT_SELECT_MOVED_FROM_RELPATH
 SELECT local_relpath, op_depth FROM nodes
 WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0
@@ -1530,14 +1529,31 @@ SELECT moved_to, local_relpath FROM node
 WHERE wc_id = ?1 AND op_depth > 0
   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
 
+/* If the node is moved here (r.moved_here = 1) we are really interested in
+   where the node was moved from. To obtain that we need the op_depth, but
+   this form of select only allows a single return value */
 -- STMT_SELECT_MOVED_FOR_DELETE
-SELECT local_relpath, moved_to, op_depth FROM nodes
+SELECT local_relpath, moved_to, op_depth,
+       (SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
+        WHERE r.wc_id = ?1
+          AND r.local_relpath = n.local_relpath
+          AND r.op_depth < n.op_depth
+        ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
+ FROM nodes n
 WHERE wc_id = ?1
   AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND moved_to IS NOT NULL
-  AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
-                    WHERE o.wc_id = ?1
-                      AND o.local_relpath = ?2)
+  AND op_depth >= ?3
+
+-- STMT_SELECT_MOVED_FROM_FOR_DELETE
+SELECT local_relpath, op_depth,
+       (SELECT CASE WHEN r.moved_here THEN r.op_depth END FROM nodes r
+        WHERE r.wc_id = ?1
+          AND r.local_relpath = n.local_relpath
+          AND r.op_depth < n.op_depth
+        ORDER BY r.op_depth DESC LIMIT 1) AS moved_here_op_depth
+ FROM nodes n
+WHERE wc_id = ?1 AND moved_to = ?2 AND op_depth > 0
 
 -- STMT_UPDATE_MOVED_TO_DESCENDANTS
 UPDATE nodes SET moved_to = RELPATH_SKIP_JOIN(?2, ?3, moved_to)
@@ -1565,10 +1581,15 @@ WHERE wc_id = ?1
 
 -- STMT_SELECT_MOVED_PAIR3
 SELECT local_relpath, moved_to, op_depth, kind FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
+  AND moved_to IS NOT NULL
+UNION ALL
+SELECT local_relpath, moved_to, op_depth, kind FROM nodes
 WHERE wc_id = ?1
-  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND op_depth > ?3
   AND moved_to IS NOT NULL
+ORDER BY local_relpath, op_depth
 
 -- STMT_SELECT_MOVED_OUTSIDE
 SELECT local_relpath, moved_to, op_depth FROM nodes

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc.h?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc.h Tue Apr 29 23:36:43 2014
@@ -157,6 +157,8 @@ extern "C" {
  * The bump to 31 added the inherited_props column in the NODES table.
  * Bumped in r1395109.
  *
+ * == 1.8.x shipped with format 31
+ * 
  * Please document any further format changes here.
  */
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.c Tue Apr 29 23:36:43 2014
@@ -1390,6 +1390,15 @@ does_node_exist(svn_boolean_t *exists,
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
+svn_error_t *
+svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb,
+                                     apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_INSTALL_SCHEMA_STATISTICS));
+
+  return SVN_NO_ERROR;
+}
+
 /* Helper for create_db(). Initializes our wc.db schema.
  */
 static svn_error_t *
@@ -1417,6 +1426,8 @@ init_db(/* output values */
   SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid,
                           db, scratch_pool));
 
+  SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
+
   /* Insert the wcroot. */
   /* ### Right now, this just assumes wc metadata is being stored locally. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
@@ -4065,8 +4076,9 @@ get_info_for_copy(apr_int64_t *copyfrom_
                   svn_wc__db_status_t *status,
                   svn_node_kind_t *kind,
                   svn_boolean_t *op_root,
-                  svn_wc__db_wcroot_t *wcroot,
+                  svn_wc__db_wcroot_t *src_wcroot,
                   const char *local_relpath,
+                  svn_wc__db_wcroot_t *dst_wcroot,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
@@ -4083,7 +4095,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                     NULL /* have_base */,
                     NULL /* have_more_work */,
                     NULL /* have_work */,
-                    wcroot, local_relpath, result_pool, scratch_pool));
+                    src_wcroot, local_relpath, result_pool, scratch_pool));
 
   if (op_root)
     *op_root = is_op_root;
@@ -4098,7 +4110,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                        scratch_pool);
       SVN_ERR(get_info_for_copy(copyfrom_id, copyfrom_relpath, copyfrom_rev,
                                 NULL, NULL, NULL,
-                                wcroot, parent_relpath,
+                                src_wcroot, parent_relpath, dst_wcroot,
                                 scratch_pool, scratch_pool));
       if (*copyfrom_relpath)
         *copyfrom_relpath = svn_relpath_join(*copyfrom_relpath, base_name,
@@ -4107,7 +4119,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
   else if (node_status == svn_wc__db_status_added)
     {
       SVN_ERR(scan_addition(&node_status, NULL, NULL, NULL, NULL, NULL, NULL,
-                            NULL, NULL, NULL, wcroot, local_relpath,
+                            NULL, NULL, NULL, src_wcroot, local_relpath,
                             scratch_pool, scratch_pool));
     }
   else if (node_status == svn_wc__db_status_deleted && is_op_root)
@@ -4116,7 +4128,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
 
       SVN_ERR(scan_deletion_txn(&base_del_relpath, NULL,
                                 &work_del_relpath,
-                                NULL, wcroot, local_relpath,
+                                NULL, src_wcroot, local_relpath,
                                 scratch_pool, scratch_pool));
       if (work_del_relpath)
         {
@@ -4129,7 +4141,8 @@ get_info_for_copy(apr_int64_t *copyfrom_
           SVN_ERR(scan_addition(NULL, &op_root_relpath,
                                 NULL, NULL, /* repos_* */
                                 copyfrom_relpath, copyfrom_id, copyfrom_rev,
-                                NULL, NULL, NULL, wcroot, parent_del_relpath,
+                                NULL, NULL, NULL,
+                                src_wcroot, parent_del_relpath,
                                 scratch_pool, scratch_pool));
           *copyfrom_relpath
             = svn_relpath_join(*copyfrom_relpath,
@@ -4144,7 +4157,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                                                     copyfrom_id, NULL, NULL,
                                                     NULL, NULL, NULL, NULL,
                                                     NULL, NULL, NULL, NULL,
-                                                    wcroot, local_relpath,
+                                                    src_wcroot, local_relpath,
                                                     result_pool,
                                                     scratch_pool));
         }
@@ -4166,6 +4179,24 @@ get_info_for_copy(apr_int64_t *copyfrom_
   if (status)
     *status = node_status;
 
+  if (src_wcroot != dst_wcroot && *copyfrom_relpath)
+    {
+      const char *repos_root_url;
+      const char *repos_uuid;
+
+      /* Pass the right repos-id for the destination db. We can't just use
+         the id of the source database, as this value can change after
+         relocation (and perhaps also when we start storing multiple
+         working copies in a single db)! */
+
+      SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
+                                          src_wcroot->sdb, *copyfrom_id,
+                                          scratch_pool));
+
+      SVN_ERR(create_repos_id(copyfrom_id, repos_root_url, repos_uuid,
+                              dst_wcroot->sdb, scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -4325,8 +4356,9 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
   const apr_array_header_t *children;
 
   SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
-                            &status, &kind, &op_root, src_wcroot,
-                            src_relpath, scratch_pool, scratch_pool));
+                            &status, &kind, &op_root,
+                            src_wcroot, src_relpath, dst_wcroot,
+                            scratch_pool, scratch_pool));
 
   SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth,
                             &dst_parent_op_depth,
@@ -7461,8 +7493,86 @@ struct moved_node_t {
 
   /* The op-depth of the deleted node at the source of the move. */
   int op_depth;
+
+  /* When >= 1 the op_depth at which local_relpath was moved to its
+     location. Used to find its original location outside the delete */
+  int moved_from_depth;
 };
 
+/* Helper function to resolve the original location of local_relpath at OP_DEPTH
+   before it was moved into the tree rooted at ROOT_RELPATH. */
+static svn_error_t *
+resolve_moved_from(const char **moved_from_relpath,
+                   int *moved_from_op_depth,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *root_relpath,
+                   const char *local_relpath,
+                   int op_depth,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  const char *suffix = "";
+  svn_sqlite__stmt_t *stmt;
+  const char *m_from_relpath;
+  int m_from_op_depth;
+  int m_move_from_depth;
+  svn_boolean_t have_row;
+
+  while (relpath_depth(local_relpath) > op_depth)
+    {
+      const char *name;
+      svn_relpath_split(&local_relpath, &name, local_relpath, scratch_pool);
+      suffix = svn_relpath_join(suffix, name, scratch_pool);
+    }
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_MOVED_FROM_FOR_DELETE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                            wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (!have_row)
+    {
+      /* assert(have_row); */
+      *moved_from_relpath = NULL;
+      *moved_from_op_depth = -1;
+
+      SVN_ERR(svn_sqlite__reset(stmt));
+
+      return SVN_NO_ERROR;
+    }
+
+  m_from_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
+  m_from_op_depth = svn_sqlite__column_int(stmt, 1);
+  m_move_from_depth = svn_sqlite__column_int(stmt, 2);
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  if (! svn_relpath_skip_ancestor(root_relpath, m_from_relpath))
+    {
+      *moved_from_relpath = svn_relpath_join(m_from_relpath, suffix,
+                                             result_pool);
+      *moved_from_op_depth = m_from_op_depth; /* ### Ok? */
+      return SVN_NO_ERROR;
+    }
+  else if (!m_move_from_depth)
+    {
+      *moved_from_relpath = NULL;
+      *moved_from_op_depth = -1;
+      return SVN_NO_ERROR;
+    }
+
+  return svn_error_trace(
+        resolve_moved_from(moved_from_relpath,
+                           moved_from_op_depth,
+                           wcroot,
+                           root_relpath,
+                           svn_relpath_join(m_from_relpath, suffix,
+                                            scratch_pool),
+                           m_move_from_depth,
+                           result_pool, scratch_pool));
+}
+
 static svn_error_t *
 delete_node(void *baton,
             svn_wc__db_wcroot_t *wcroot,
@@ -7474,19 +7584,70 @@ delete_node(void *baton,
   svn_boolean_t have_row, op_root;
   svn_boolean_t add_work = FALSE;
   svn_sqlite__stmt_t *stmt;
-  int select_depth; /* Depth of what is to be deleted */
-  svn_boolean_t refetch_depth = FALSE;
+  int working_op_depth; /* Depth of what is to be deleted */
+  int keep_op_depth = 0; /* Depth of what is below what is deleted */
   svn_node_kind_t kind;
   apr_array_header_t *moved_nodes = NULL;
-  int delete_depth = relpath_depth(local_relpath);
+  int delete_op_depth = relpath_depth(local_relpath);
 
-  SVN_ERR(read_info(&status,
-                    &kind, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                    &op_root, NULL, NULL,
-                    NULL, NULL, NULL,
-                    wcroot, local_relpath,
-                    scratch_pool, scratch_pool));
+  assert(*local_relpath); /* Can't delete wcroot */
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_NODE_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  if (!have_row)
+    {
+      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND,
+                               svn_sqlite__reset(stmt),
+                               _("The node '%s' was not found."),
+                               path_for_error_message(wcroot,
+                                                      local_relpath,
+                                                      scratch_pool));
+    }
+
+  working_op_depth = svn_sqlite__column_int(stmt, 0);
+  status = svn_sqlite__column_token(stmt, 3, presence_map);
+  kind = svn_sqlite__column_token(stmt, 4, kind_map);
+
+  if (working_op_depth < delete_op_depth)
+    {
+      op_root = FALSE;
+      add_work = TRUE;
+      keep_op_depth = working_op_depth;
+    }
+  else
+    {
+      op_root = TRUE;
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+      if (have_row)
+        {
+          svn_wc__db_status_t below_status;
+          int below_op_depth;
+
+          below_op_depth = svn_sqlite__column_int(stmt, 0);
+          below_status = svn_sqlite__column_token(stmt, 3, presence_map);
+
+          if (below_status != svn_wc__db_status_not_present
+              && below_status != svn_wc__db_status_base_deleted)
+            {
+              add_work = TRUE;
+              keep_op_depth = below_op_depth;
+            }
+          else
+            keep_op_depth = 0;
+        }
+      else
+        keep_op_depth = -1;
+    }
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  if (working_op_depth != 0) /* WORKING */
+    SVN_ERR(convert_to_working_status(&status, status));
 
   if (status == svn_wc__db_status_deleted
       || status == svn_wc__db_status_not_present)
@@ -7565,6 +7726,7 @@ delete_node(void *baton,
                                                          part, scratch_pool);
           moved_node->op_depth = move_op_depth;
           moved_node->moved_to_relpath = b->moved_to_relpath;
+          moved_node->moved_from_depth = -1;
 
           APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
         }
@@ -7576,8 +7738,9 @@ delete_node(void *baton,
            * possibly because of a nested move operation. */
           moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
           moved_node->local_relpath = local_relpath;
-          moved_node->op_depth = delete_depth;
+          moved_node->op_depth = delete_op_depth;
           moved_node->moved_to_relpath = b->moved_to_relpath;
+          moved_node->moved_from_depth = -1;
 
           APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
         }
@@ -7592,24 +7755,18 @@ delete_node(void *baton,
                                              b->moved_to_relpath));
       SVN_ERR(svn_sqlite__update(NULL, stmt));
     }
-  else
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_MOVED_TO_DESCENDANTS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
-                                            local_relpath));
-      SVN_ERR(svn_sqlite__update(NULL, stmt));
-    }
 
   /* Find children that were moved out of the subtree rooted at this node.
    * We'll need to update their op-depth columns because their deletion
    * is now implied by the deletion of their parent (i.e. this node). */
     {
       apr_pool_t *iterpool;
+      int i;
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_SELECT_MOVED_FOR_DELETE));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+                                delete_op_depth));
 
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
       iterpool = svn_pool_create(scratch_pool);
@@ -7619,52 +7776,85 @@ delete_node(void *baton,
           const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
           const char *mv_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
           int child_op_depth = svn_sqlite__column_int(stmt, 2);
+          int moved_from_depth = -1;
           svn_boolean_t fixup = FALSE;
 
-          if (!b->moved_to_relpath
+          if (! b->moved_to_relpath
               && ! svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
             {
-              /* Update the op-depth of an moved node below this tree */
-              fixup = TRUE;
-              child_op_depth = delete_depth;
-            }
-          else if (b->moved_to_relpath
-                   && delete_depth == child_op_depth)
-            {
-              /* Update the op-depth of a tree shadowed by this tree */
-              fixup = TRUE;
-              child_op_depth = delete_depth;
-            }
-          else if (b->moved_to_relpath
-                   && child_op_depth >= delete_depth
-                   && !svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
-            {
-              /* Update the move destination of something that is now moved
-                 away further */
+              /* a NULL moved_here_depth will be reported as 0 */
+              int moved_here_depth = svn_sqlite__column_int(stmt, 3);
 
-              child_relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath);
+              /* Plain delete. Fixup move information of descendants that were
+                 moved here, or that were moved out */
 
-              if (child_relpath)
+              if (moved_here_depth >= delete_op_depth)
                 {
-                  child_relpath = svn_relpath_join(b->moved_to_relpath, child_relpath, scratch_pool);
+                  /* The move we recorded here must be moved to the location
+                     this node had before it was moved here.
 
-                  if (child_op_depth > delete_depth
-                      && svn_relpath_skip_ancestor(local_relpath, child_relpath))
-                    child_op_depth = delete_depth;
-                  else
-                    child_op_depth = relpath_depth(child_relpath);
+                     This might contain multiple steps when the node was moved
+                     in several places within the to be deleted tree */
 
+                  /* ### TODO: Add logic */
                   fixup = TRUE;
+                  moved_from_depth = moved_here_depth;
+                }
+              else
+                {
+                  /* Update the op-depth of an moved away node that was
+                     registered as moved by the records that we are about
+                     to delete */
+                  fixup = TRUE;
+                  child_op_depth = delete_op_depth;
+                }
+            }
+          else if (b->moved_to_relpath)
+            {
+              /* The node is moved to a new location */
+
+              if (delete_op_depth == child_op_depth)
+                {
+                  /* Update the op-depth of a tree shadowed by this tree */
+                  fixup = TRUE;
+                  /*child_op_depth = delete_depth;*/
+                }
+              else if (child_op_depth >= delete_op_depth
+                       && !svn_relpath_skip_ancestor(local_relpath,
+                                                     mv_to_relpath))
+                {
+                  /* Update the move destination of something that is now moved
+                     away further */
+
+                  child_relpath = svn_relpath_skip_ancestor(local_relpath,
+                                                            child_relpath);
+
+                  if (child_relpath)
+                    {
+                      child_relpath = svn_relpath_join(b->moved_to_relpath,
+                                                       child_relpath,
+                                                       scratch_pool);
+
+                      if (child_op_depth > delete_op_depth
+                           && svn_relpath_skip_ancestor(local_relpath,
+                                                        child_relpath))
+                        child_op_depth = delete_op_depth;
+                      else
+                        child_op_depth = relpath_depth(child_relpath);
+
+                      fixup = TRUE;
+                    }
                 }
             }
 
           if (fixup)
             {
-              mn = apr_pcalloc(scratch_pool, sizeof(struct moved_node_t));
+              mn = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
 
               mn->local_relpath = apr_pstrdup(scratch_pool, child_relpath);
               mn->moved_to_relpath = apr_pstrdup(scratch_pool, mv_to_relpath);
               mn->op_depth = child_op_depth;
+              mn->moved_from_depth = moved_from_depth;
 
               if (!moved_nodes)
                 moved_nodes = apr_array_make(scratch_pool, 1,
@@ -7674,58 +7864,67 @@ delete_node(void *baton,
 
           SVN_ERR(svn_sqlite__step(&have_row, stmt));
         }
-      svn_pool_destroy(iterpool);
       SVN_ERR(svn_sqlite__reset(stmt));
-    }
 
-  if (op_root)
-    {
-      svn_boolean_t below_base;
-      svn_boolean_t below_work;
-      svn_wc__db_status_t below_status;
-
-      /* Use STMT_SELECT_NODE_INFO directly instead of read_info plus
-         info_below_working */
-      SVN_ERR(info_below_working(&below_base, &below_work, &below_status,
-                                 wcroot, local_relpath, -1, scratch_pool));
-      if ((below_base || below_work)
-          && below_status != svn_wc__db_status_not_present
-          && below_status != svn_wc__db_status_deleted)
+      for (i = 0; moved_nodes && (i < moved_nodes->nelts); i++)
         {
-          add_work = TRUE;
-          refetch_depth = TRUE;
+          struct moved_node_t *mn = APR_ARRAY_IDX(moved_nodes, i,
+                                                  struct moved_node_t *);
+
+          if (mn->moved_from_depth > 0)
+            {
+              svn_pool_clear(iterpool);
+
+              SVN_ERR(resolve_moved_from(&mn->local_relpath, &mn->op_depth,
+                                         wcroot, local_relpath,
+                                         mn->local_relpath,
+                                         mn->moved_from_depth,
+                                         scratch_pool, iterpool));
+
+              if (!mn->local_relpath)
+                svn_sort__array_delete(moved_nodes, i--, 1);
+            }
         }
 
-      select_depth = relpath_depth(local_relpath);
+      svn_pool_destroy(iterpool);
     }
-  else
+
+  if (!b->moved_to_relpath)
     {
-      add_work = TRUE;
-      if (status != svn_wc__db_status_normal)
-        SVN_ERR(op_depth_of(&select_depth, wcroot, local_relpath));
-      else
-        select_depth = 0; /* Deleting BASE node */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_MOVED_TO_DESCENDANTS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
+                                local_relpath));
+      SVN_ERR(svn_sqlite__update(NULL, stmt));
+
+      if (op_root)
+        {
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_CLEAR_MOVED_TO_FROM_DEST));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
+                                    local_relpath));
+
+          SVN_ERR(svn_sqlite__update(NULL, stmt));
+        }
     }
 
+
   /* ### Put actual-only nodes into the list? */
   if (b->notify)
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                         STMT_INSERT_DELETE_LIST));
       SVN_ERR(svn_sqlite__bindf(stmt, "isd",
-                                wcroot->wc_id, local_relpath, select_depth));
+                                wcroot->wc_id, local_relpath, working_op_depth));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE));
   SVN_ERR(svn_sqlite__bindf(stmt, "isd",
-                            wcroot->wc_id, local_relpath, delete_depth));
+                            wcroot->wc_id, local_relpath, delete_op_depth));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
-  if (refetch_depth)
-    SVN_ERR(op_depth_of(&select_depth, wcroot, local_relpath));
-
   /* Delete ACTUAL_NODE rows, but leave those that have changelist
      and a NODES row. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -7755,7 +7954,7 @@ delete_node(void *baton,
                                  STMT_INSERT_DELETE_FROM_NODE_RECURSIVE));
       SVN_ERR(svn_sqlite__bindf(stmt, "isdd",
                                 wcroot->wc_id, local_relpath,
-                                select_depth, delete_depth));
+                                keep_op_depth, delete_op_depth));
       SVN_ERR(svn_sqlite__step_done(stmt));
     }
 

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.h?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db.h Tue Apr 29 23:36:43 2014
@@ -2831,6 +2831,16 @@ svn_wc__db_scan_deletion(const char **ba
    @{
 */
 
+/* Installs or updates Sqlite schema statistics for the current (aka latest)
+   working copy schema.
+
+   This function should be called once on initializing the database and after
+   an schema update completes */
+svn_error_t *
+svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb,
+                                     apr_pool_t *scratch_pool);
+
+
 /* Create a new wc.db file for LOCAL_DIR_ABSPATH, which is going to be a
    working copy for the repository REPOS_ROOT_URL with uuid REPOS_UUID.
    Return the raw sqlite handle, repository id and working copy id

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_util.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_util.c Tue Apr 29 23:36:43 2014
@@ -136,22 +136,6 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
                                  svn_dirent_local_style(sdb_abspath,
                                                         scratch_pool));
     }
-#ifndef WIN32
-  else
-    {
-      apr_file_t *f;
-
-      /* A standard SQLite build creates a DB with mode 644 ^ !umask
-         which means the file doesn't have group/world write access
-         even when umask allows it. By ensuring the file exists before
-         SQLite gets involved we give it the permissions allowed by
-         umask. */
-      SVN_ERR(svn_io_file_open(&f, sdb_abspath,
-                               (APR_READ | APR_WRITE | APR_CREATE),
-                               APR_OS_DEFAULT, scratch_pool));
-      SVN_ERR(svn_io_file_close(f, scratch_pool));
-    }
-#endif
 
   SVN_ERR(svn_sqlite__open(sdb, sdb_abspath, smode,
                            my_statements ? my_statements : statements,

Modified: subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_wcroot.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/libsvn_wc/wc_db_wcroot.c Tue Apr 29 23:36:43 2014
@@ -690,8 +690,12 @@ try_symlink_as_dir:
           svn_error_clear(err);
           *wcroot = NULL;
         }
-      else
-        SVN_ERR(err);
+      else if (err)
+        {
+          /* Close handle if we are not going to use it to support
+             upgrading with exclusive wc locking. */
+          return svn_error_compose_create(err, svn_sqlite__close(sdb));
+        }
     }
   else
     {

Modified: subversion/branches/1.8.x-r1536931/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/mod_authz_svn/mod_authz_svn.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/mod_authz_svn/mod_authz_svn.c Tue Apr 29 23:36:43 2014
@@ -91,7 +91,8 @@ create_authz_svn_dir_config(apr_pool_t *
 /* canonicalize ACCESS_FILE based on the type of argument.
  * If SERVER_RELATIVE is true, ACCESS_FILE is a relative
  * path then ACCESS_FILE is converted to an absolute
- * path rooted at the server root. */
+ * path rooted at the server root.
+ * Returns NULL if path is not valid.*/
 static const char *
 canonicalize_access_file(const char *access_file,
                          svn_boolean_t server_relative,
@@ -104,7 +105,11 @@ canonicalize_access_file(const char *acc
   else if (!svn_path_is_repos_relative_url(access_file))
     {
       if (server_relative)
-        access_file = ap_server_root_relative(pool, access_file);
+        {
+          access_file = ap_server_root_relative(pool, access_file);
+          if (access_file == NULL)
+            return NULL;
+        }
 
       access_file = svn_dirent_internal_style(access_file, pool);
     }
@@ -126,6 +131,8 @@ AuthzSVNAccessFile_cmd(cmd_parms *cmd, v
            "directives are mutually exclusive.";
 
   conf->access_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
+  if (!conf->access_file)
+    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, NULL);
 
   return NULL;
 }
@@ -145,6 +152,9 @@ AuthzSVNReposRelativeAccessFile_cmd(cmd_
   conf->repo_relative_access_file = canonicalize_access_file(arg1, FALSE,
                                                              cmd->pool);
 
+  if (!conf->repo_relative_access_file)
+    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, NULL);
+
   return NULL;
 }
 
@@ -155,6 +165,9 @@ AuthzSVNGroupsFile_cmd(cmd_parms *cmd, v
 
   conf->groups_file = canonicalize_access_file(arg1, TRUE, cmd->pool);
 
+  if (!conf->groups_file)
+    return apr_pstrcat(cmd->pool, "Invalid file path ", arg1, NULL);
+
   return NULL;
 }
 

Modified: subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/dav_svn.h?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/dav_svn.h Tue Apr 29 23:36:43 2014
@@ -52,8 +52,11 @@ extern "C" {
 /* a pool-key for the shared dav_svn_root used by autoversioning  */
 #define DAV_SVN__AUTOVERSIONING_ACTIVITY "svn-autoversioning-activity"
 
-/* Option values for SVNAllowBulkUpdates */
+/* Option values for SVNAllowBulkUpdates.  Note that
+   it's important that CONF_BULKUPD_DEFAULT is 0 to make
+   dav_svn_merge_dir_config do the right thing. */
 typedef enum dav_svn__bulk_upd_conf {
+    CONF_BULKUPD_DEFAULT,
     CONF_BULKUPD_ON,
     CONF_BULKUPD_OFF,
     CONF_BULKUPD_PREFER
@@ -900,6 +903,12 @@ dav_svn__simple_parse_uri(dav_svn__uri_i
                           const char *uri,
                           apr_pool_t *pool);
 
+/* Test the request R to determine if we should return the list of
+ * repositories at the parent path.  Only true if SVNListParentPath directive
+ * is 'on' and the request is for our configured root path. */
+svn_boolean_t
+dav_svn__is_parentpath_list(request_rec *r);
+
 
 int dav_svn__find_ns(const apr_array_header_t *namespaces, const char *uri);
 

Modified: subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/lock.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/lock.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/lock.c Tue Apr 29 23:36:43 2014
@@ -453,7 +453,8 @@ get_locks(dav_lockdb *lockdb,
      lock.  For the --force case, this is required and for the non-force case,
      we allow the filesystem to produce a better error for svn clients.
   */
-  if (info->r->method_number == M_LOCK)
+  if (info->r->method_number == M_LOCK
+      && resource->info->repos->is_svn_client)
     {
       *locks = NULL;
       return 0;
@@ -594,7 +595,8 @@ has_locks(dav_lockdb *lockdb, const dav_
      lock.  For the --force case, this is required and for the non-force case,
      we allow the filesystem to produce a better error for svn clients.
   */
-  if (info->r->method_number == M_LOCK)
+  if (info->r->method_number == M_LOCK
+      && resource->info->repos->is_svn_client)
     {
       *locks_present = 0;
       return 0;

Modified: subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/mod_dav_svn.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/mod_dav_svn.c Tue Apr 29 23:36:43 2014
@@ -214,7 +214,7 @@ create_dir_config(apr_pool_t *p, char *d
      <Location /blah> directive. So we treat it as a urlpath. */
   if (dir)
     conf->root_dir = svn_urlpath__canonicalize(dir, p);
-  conf->bulk_updates = CONF_BULKUPD_ON;
+  conf->bulk_updates = CONF_BULKUPD_DEFAULT;
   conf->v2_protocol = CONF_FLAG_ON;
   conf->hooks_env = NULL;
 
@@ -812,7 +812,12 @@ dav_svn__get_bulk_updates_flag(request_r
   dir_conf_t *conf;
 
   conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
-  return conf->bulk_updates;
+
+  /* SVNAllowBulkUpdates is 'on' by default. */
+  if (conf->bulk_updates == CONF_BULKUPD_DEFAULT)
+    return CONF_BULKUPD_ON;
+  else
+    return conf->bulk_updates;
 }
 
 
@@ -1096,30 +1101,84 @@ static int dav_svn__handler(request_rec 
 
 #define NO_MAP_TO_STORAGE_NOTE "dav_svn-no-map-to-storage"
 
-/* Prevent filename on the request from being set since we aren't serving a
- * file off the disk.  This means that <Directory> blocks will not match and
- * that * %f in logging formats will show as "-". */
+/* Fill the filename on the request with a bogus path since we aren't serving
+ * a file off the disk.  This means that <Directory> blocks will not match and
+ * that %f in logging formats will show as "svn:/path/to/repo/path/in/repo". */
 static int dav_svn__translate_name(request_rec *r)
 {
+  const char *fs_path, *repos_basename, *repos_path, *slash;
+  const char *ignore_cleaned_uri, *ignore_relative_path;
+  int ignore_had_slash;
   dir_conf_t *conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
 
   /* module is not configured, bail out early */
   if (!conf->fs_path && !conf->fs_parent_path)
     return DECLINED;
 
-  /* Be paranoid and set it to NULL just in case some other module set it
-   * before we got called. */ 
-  r->filename = NULL;
+  if (dav_svn__is_parentpath_list(r))
+    {
+      /* SVNListParentPath is on and the request is for the conf->root_dir,
+       * so just set the repos_basename to an empty string and the repos_path
+       * to NULL so we end up just reporting our parent path as the bogus
+       * path. */
+      repos_basename = "";
+      repos_path = NULL;
+    }
+  else
+    {
+      /* Retrieve path to repo and within repo for the request */
+      dav_error *err = dav_svn_split_uri(r, r->uri, conf->root_dir,
+                                         &ignore_cleaned_uri,
+                                         &ignore_had_slash, &repos_basename,
+                                         &ignore_relative_path, &repos_path);
+      if (err)
+        {
+          dav_svn__log_err(r, err, APLOG_ERR);
+          return err->status;
+        }
+    }
+
+  if (conf->fs_parent_path)
+    {
+      fs_path = svn_dirent_join(conf->fs_parent_path, repos_basename,
+                                r->pool);
+    }
+  else
+    {
+      fs_path = conf->fs_path;
+    }
+
+  /* Avoid a trailing slash on the bogus path when repos_path is just "/" and
+   * ensure that there is always a slash between fs_path and repos_path as
+   * long as the repos_path is not an empty path. */
+  slash = "";
+  if (repos_path)
+    {
+      if ('/' == repos_path[0] && '\0' == repos_path[1])
+        repos_path = NULL;
+      else if ('/' != repos_path[0] && '\0' != repos_path[0])
+        slash = "/";
+    }
+
+  /* Combine 'svn:', fs_path and repos_path to produce the bogus path we're
+   * placing in r->filename.  We can't use our standard join helpers such
+   * as svn_dirent_join.  fs_path is a dirent and repos_path is a fspath
+   * (that can be trivially converted to a relpath by skipping the leading
+   * slash).  In general it is safe to join these, but when a path in a
+   * repository is 'trunk/c:hi' this results in a non canonical dirent on
+   * Windows. Instead we just cat them together. */
+  r->filename = apr_pstrcat(r->pool,
+                            "svn:", fs_path, slash, repos_path, NULL);
 
-  /* Leave a note to ourselves so that we know not to decline in the 
+  /* Leave a note to ourselves so that we know not to decline in the
    * map_to_storage hook. */
-  apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1); 
+  apr_table_setn(r->notes, NO_MAP_TO_STORAGE_NOTE, (const char*)1);
   return OK;
 }
 
 /* Prevent core_map_to_storage from running if we prevented the r->filename
  * from being set since core_map_to_storage doesn't like r->filename being
- * NULL. */
+ * bogus. */
 static int dav_svn__map_to_storage(request_rec *r)
 {
   /* Check a note we left in translate_name since map_to_storage doesn't

Modified: subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/reports/update.c?rev=1591144&r1=1591143&r2=1591144&view=diff
==============================================================================
--- subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/1.8.x-r1536931/subversion/mod_dav_svn/reports/update.c Tue Apr 29 23:36:43 2014
@@ -694,8 +694,8 @@ upd_change_xxx_prop(void *baton,
 
           /* That said, beginning in Subversion 1.8, clients might
              request even in skelta mode that we transmit properties
-             on newly added files explicitly. */
-          if ((! b->copyfrom) && value && b->uc->include_props)
+             on added files and directories explicitly. */
+          if (value && b->uc->include_props)
             {
               SVN_ERR(send_propchange(b, name, value, pool));
             }