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

svn commit: r1300532 [4/9] - in /subversion/branches/multi-layer-moves: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ notes/ notes/directory-index/ subversion/bindings/javahl/ subversion/bindings/javahl/native/ sub...

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_repos/rev_hunt.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_repos/rev_hunt.c Wed Mar 14 13:07:02 2012
@@ -154,6 +154,8 @@ svn_repos_get_committed_info(svn_revnum_
                              const char *path,
                              apr_pool_t *pool)
 {
+  apr_hash_t *revprops;
+  
   svn_fs_t *fs = svn_fs_root_fs(root);
 
   /* ### It might be simpler just to declare that revision
@@ -164,13 +166,16 @@ svn_repos_get_committed_info(svn_revnum_
   /* Get the CR field out of the node's skel. */
   SVN_ERR(svn_fs_node_created_rev(committed_rev, root, path, pool));
 
-  /* Get the date property of this revision. */
-  SVN_ERR(svn_fs_revision_prop(&committed_date_s, fs, *committed_rev,
-                               SVN_PROP_REVISION_DATE, pool));
-
-  /* Get the author property of this revision. */
-  SVN_ERR(svn_fs_revision_prop(&last_author_s, fs, *committed_rev,
-                               SVN_PROP_REVISION_AUTHOR, pool));
+  /* Get the revision properties of this revision. */
+  SVN_ERR(svn_fs_revision_proplist(&revprops, fs, *committed_rev, pool));
+
+  /* Extract date and author from these revprops. */
+  committed_date_s = apr_hash_get(revprops,
+                                  SVN_PROP_REVISION_DATE,
+                                  sizeof(SVN_PROP_REVISION_DATE)-1);
+  last_author_s = apr_hash_get(revprops,
+                               SVN_PROP_REVISION_AUTHOR,
+                               sizeof(SVN_PROP_REVISION_AUTHOR)-1);
 
   *committed_date = committed_date_s ? committed_date_s->data : NULL;
   *last_author = last_author_s ? last_author_s->data : NULL;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/auth.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/auth.c Wed Mar 14 13:07:02 2012
@@ -35,13 +35,20 @@
 #include "svn_dso.h"
 #include "svn_version.h"
 
-/* The good way to think of this machinery is as a set of tables.
+/* AN OVERVIEW
+   ===========
 
-   - Each type of credentials selects a single table.
+   A good way to think of this machinery is as a set of tables.
 
-   - In a given table, each row is a 'provider' capable of returning
-     the same type of credentials.  Each column represents a
-     provider's repeated attempts to provide credentials.
+     - Each type of credentials selects a single table.
+
+     - In a given table, each row is a 'provider' capable of returning
+       the same type of credentials.  Each column represents a
+       provider's repeated attempts to provide credentials.
+
+
+   Fetching Credentials from Providers
+   -----------------------------------
 
    When the caller asks for a particular type of credentials, the
    machinery in this file walks over the appropriate table.  It starts
@@ -55,6 +62,23 @@
 
    Note that the caller cannot see the table traversal, and thus has
    no idea when we switch providers.
+
+
+   Storing Credentials with Providers
+   ----------------------------------
+
+   When the server has validated a set of credentials, and when
+   credential caching is enabled, we have the chance to store those
+   credentials for later use.  The provider which provided the working
+   credentials is the first one given the opportunity to (re)cache
+   those credentials.  Its save_credentials() function is invoked with
+   the working credentials.  If that provider reports that it
+   successfully stored the credentials, we're done.  Otherwise, we
+   walk the providers (rows) for that type of credentials in order
+   from the top of the table, allowing each in turn the opportunity to
+   store the credentials.  When one reports that it has done so
+   successfully -- or when we run out of providers (rows) to try --
+   the table walk ends.
 */
 
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-inprocess.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-inprocess.c Wed Mar 14 13:07:02 2012
@@ -201,7 +201,7 @@ inprocess_cache_get_internal(char **buff
 
       *size = entry->size;
     }
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -223,7 +223,7 @@ inprocess_cache_get(void **value_p,
                                                       cache,
                                                       key,
                                                       result_pool));
-    
+
   /* deserialize the buffer content. Usually, this will directly
      modify the buffer content directly.
    */
@@ -445,7 +445,7 @@ inprocess_cache_iter(svn_boolean_t *comp
   b.user_baton = user_baton;
 
   SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       svn_iter_apr_hash(completed, cache->hash, 
+                       svn_iter_apr_hash(completed, cache->hash,
                                          iter_cb, &b, scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-membuffer.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-membuffer.c Wed Mar 14 13:07:02 2012
@@ -136,6 +136,13 @@
  */
 #define NO_OFFSET APR_UINT64_MAX
 
+/* To save space in our group structure, we only use 32 bit size values
+ * and, therefore, limit the size of each entry to just below 4GB.
+ * Supporting larger items is not a good idea as the data transfer
+ * to and from the cache would block other threads for a very long time.
+ */
+#define MAX_ITEM_SIZE ((apr_uint32_t)(0 - ITEM_ALIGNMENT))
+
 /* Debugging / corruption detection support.
  * If you define this macro, the getter functions will performed expensive
  * checks on the item data, requested keys and entry types. If there is
@@ -395,6 +402,11 @@ struct svn_membuffer_t
    */
   apr_uint64_t data_used;
 
+  /* Largest entry size that we would accept.  For total cache sizes
+   * less than 4TB (sic!), this is determined by the total cache size.
+   */
+  apr_uint64_t max_entry_size;
+
 
   /* Number of used dictionary entries, i.e. number of cached items.
    * In conjunction with hit_count, this is used calculate the average
@@ -591,7 +603,7 @@ get_group_index(svn_membuffer_t **cache,
 
   if (key == NULL)
     return NO_INDEX;
-  
+
   err = svn_checksum(&checksum, svn_checksum_md5, key, len, pool);
   if (err != NULL)
   {
@@ -949,6 +961,7 @@ svn_cache__membuffer_cache_create(svn_me
   apr_uint32_t group_count;
   apr_uint32_t group_init_size;
   apr_uint64_t data_size;
+  apr_uint64_t max_entry_size;
 
   /* Determine a reasonable number of cache segments. Segmentation is
    * only useful for multi-threaded / multi-core servers as it reduces
@@ -992,8 +1005,19 @@ svn_cache__membuffer_cache_create(svn_me
    */
   data_size = total_size - directory_size;
 
+  /* For cache sizes > 4TB, individual cache segments will be larger
+   * than 16GB allowing for >4GB entries.  But caching chunks larger
+   * than 4GB is simply not supported.
+   */
+  max_entry_size = data_size / 4 > MAX_ITEM_SIZE
+                 ? MAX_ITEM_SIZE
+                 : data_size / 4;
+  
   /* to keep the entries small, we use 32 bit indices only
-   * -> we need to ensure that no more then 4G entries exist
+   * -> we need to ensure that no more then 4G entries exist.
+   * 
+   * Note, that this limit could only be exceeded in a very
+   * theoretical setup with about 1EB of cache.
    */
   group_count = directory_size / sizeof(entry_group_t);
   if (group_count >= (APR_UINT32_MAX / GROUP_SIZE))
@@ -1024,6 +1048,7 @@ svn_cache__membuffer_cache_create(svn_me
       c[seg].data = secure_aligned_alloc(pool, (apr_size_t)data_size, FALSE);
       c[seg].current_data = 0;
       c[seg].data_used = 0;
+      c[seg].max_entry_size = max_entry_size;
 
       c[seg].used_entries = 0;
       c[seg].hit_count = 0;
@@ -1055,14 +1080,14 @@ svn_cache__membuffer_cache_create(svn_me
 
 
 /* Try to insert the serialized item given in BUFFER with SIZE into
- * the group GROUP_INDEX of CACHE and uniquely identify it by hash 
- * value TO_FIND. 
- * 
+ * the group GROUP_INDEX of CACHE and uniquely identify it by hash
+ * value TO_FIND.
+ *
  * However, there is no guarantee that it will actually be put into
  * the cache. If there is already some data associated with TO_FIND,
  * it will be removed from the cache even if the new data cannot
  * be inserted.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1078,7 +1103,7 @@ membuffer_cache_set_internal(svn_membuff
   /* if necessary, enlarge the insertion window.
    */
   if (   buffer != NULL
-      && cache->data_size / 4 > size
+      && cache->max_entry_size >= size
       && ensure_data_insertable(cache, size))
     {
       /* Remove old data for this key, if that exists.
@@ -1165,11 +1190,11 @@ membuffer_cache_set(svn_membuffer_t *cac
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
- * by the hash value TO_FIND. If no item has been stored for KEY, 
+ * by the hash value TO_FIND. If no item has been stored for KEY,
  * *BUFFER will be NULL. Otherwise, return a copy of the serialized
- * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will 
+ * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will
  * be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1195,10 +1220,10 @@ membuffer_cache_get_internal(svn_membuff
        */
       *buffer = NULL;
       *item_size = 0;
-  
+
       return SVN_NO_ERROR;
     }
-    
+
   size = ALIGN_VALUE(entry->size);
   *buffer = ALIGN_POINTER(apr_palloc(result_pool, size + ITEM_ALIGNMENT-1));
   memcpy(*buffer, (const char*)cache->data + entry->offset, size);
@@ -1225,7 +1250,7 @@ membuffer_cache_get_internal(svn_membuff
   cache->total_hits++;
 
   *item_size = entry->size;
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1275,18 +1300,18 @@ membuffer_cache_get(svn_membuffer_t *cac
       *item = NULL;
       return SVN_NO_ERROR;
     }
-    
+
   return deserializer(item, buffer, size, result_pool);
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. FOUND indicates whether that entry exists.
  * If not found, *ITEM will be NULL.
- * 
- * Otherwise, the DESERIALIZER is called with that entry and the BATON 
+ *
+ * Otherwise, the DESERIALIZER is called with that entry and the BATON
  * provided and will extract the desired information. The result is set
  * in *ITEM. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1307,7 +1332,7 @@ membuffer_cache_get_partial_internal(svn
     {
       *item = NULL;
       *found = FALSE;
-      
+
       return SVN_NO_ERROR;
     }
   else
@@ -1379,10 +1404,10 @@ membuffer_cache_get_partial(svn_membuffe
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. If no entry has been found, the function
  * returns without modifying the cache.
- * 
+ *
  * Otherwise, FUNC is called with that entry and the BATON provided
  * and may modify the cache entry. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_set_partial instead.
  */
@@ -1452,7 +1477,7 @@ membuffer_cache_set_partial_internal(svn
               /* Remove the old entry and try to make space for the new one.
                */
               drop_entry(cache, entry);
-              if (   (cache->data_size / 4 > size)
+              if (   (cache->max_entry_size >= size)
                   && ensure_data_insertable(cache, size))
                 {
                   /* Write the new entry.
@@ -1823,8 +1848,7 @@ svn_membuffer_cache_is_cachable(void *ca
    * must be small enough to be stored in a 32 bit value.
    */
   svn_membuffer_cache_t *cache = cache_void;
-  return (size < cache->membuffer->data_size / 4)
-      && (size < APR_UINT32_MAX - ITEM_ALIGNMENT);
+  return size <= cache->membuffer->max_entry_size;
 }
 
 /* Add statistics of SEGMENT to INFO.
@@ -1872,7 +1896,7 @@ svn_membuffer_cache_get_info(void *cache
   for (i = 0; i < cache->membuffer->segment_count; ++i)
     {
       svn_membuffer_t *segment = cache->membuffer + i;
-      SVN_MUTEX__WITH_LOCK(segment->mutex, 
+      SVN_MUTEX__WITH_LOCK(segment->mutex,
                            svn_membuffer_get_segment_info(segment, info));
     }
 
@@ -1902,13 +1926,13 @@ svn_membuffer_cache_get_synced(void **va
                                apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get(value_p,
                                                found,
                                                cache_void,
                                                key,
                                                result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1921,12 +1945,12 @@ svn_membuffer_cache_set_synced(void *cac
                                apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set(cache_void,
                                                key,
                                                value,
                                                scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1942,7 +1966,7 @@ svn_membuffer_cache_get_partial_synced(v
                                        apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get_partial(value_p,
                                                        found,
                                                        cache_void,
@@ -1950,7 +1974,7 @@ svn_membuffer_cache_get_partial_synced(v
                                                        func,
                                                        baton,
                                                        result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1964,13 +1988,13 @@ svn_membuffer_cache_set_partial_synced(v
                                        apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set_partial(cache_void,
                                                        key,
                                                        func,
                                                        baton,
                                                        scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -2057,7 +2081,7 @@ svn_cache__create_membuffer_cache(svn_ca
   cache->alloc_counter = 0;
 
   SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, pool));
-  
+
   /* for performance reasons, we don't actually store the full prefix but a
    * hash value of it
    */
@@ -2078,7 +2102,7 @@ svn_cache__create_membuffer_cache(svn_ca
 
   /* initialize the generic cache wrapper
    */
-  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable 
+  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable
                                 : &membuffer_cache_vtable;
   wrapper->cache_internal = cache;
   wrapper->error_handler = 0;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-memcache.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/cache-memcache.c Wed Mar 14 13:07:02 2012
@@ -148,7 +148,7 @@ memcache_internal_get(char **data,
       *found = FALSE;
       return SVN_NO_ERROR;
     }
-  
+
   subpool = svn_pool_create(pool);
   SVN_ERR(build_key(&mc_key, cache, key, subpool));
 
@@ -253,7 +253,7 @@ memcache_set(void *cache_void,
 
   if (key == NULL)
     return SVN_NO_ERROR;
-  
+
   if (cache->serialize_func)
     {
       SVN_ERR((cache->serialize_func)(&data, &data_len, value, subpool));

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/gpg_agent.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/gpg_agent.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/gpg_agent.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/gpg_agent.c Wed Mar 14 13:07:02 2012
@@ -169,7 +169,7 @@ password_get_gpg_agent(svn_boolean_t *do
   const char *p = NULL;
   char *ep = NULL;
   char *buffer;
-  
+
   apr_array_header_t *socket_details;
   const char *request = NULL;
   const char *cache_id = NULL;
@@ -204,7 +204,7 @@ password_get_gpg_agent(svn_boolean_t *do
       sd = socket(AF_UNIX, SOCK_STREAM, 0);
       if (sd == -1)
         return SVN_NO_ERROR;
-    
+
       if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
         {
           close(sd);
@@ -363,7 +363,7 @@ password_get_gpg_agent(svn_boolean_t *do
 
   if (strncmp(buffer, "ERR", 3) == 0)
     return SVN_NO_ERROR;
-  
+
   p = NULL;
   if (strncmp(buffer, "D", 1) == 0)
     p = &buffer[2];

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/mergeinfo.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/mergeinfo.c Wed Mar 14 13:07:02 2012
@@ -1112,12 +1112,12 @@ svn_rangelist_merge2(apr_array_header_t 
                           j++;
                         }
                     }
-                  else 
+                  else
                     {
                       /* CHANGE and RANGE share the same start rev, but
                          CHANGE is considered older because its end rev
                          is older.
-                         
+
                          Insert the intersection of RANGE and CHANGE into
                          RANGELIST and then set RANGE to the non-intersecting
                          portion of RANGE. */
@@ -2111,7 +2111,6 @@ svn_mergeinfo__remove_prefix_from_catalo
                                           apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
-  apr_ssize_t prefix_len = strlen(prefix_path);
 
   SVN_ERR_ASSERT(prefix_path[0] == '/');
 
@@ -2120,23 +2119,13 @@ svn_mergeinfo__remove_prefix_from_catalo
   for (hi = apr_hash_first(pool, in_catalog); hi; hi = apr_hash_next(hi))
     {
       const char *original_path = svn__apr_hash_index_key(hi);
-      apr_ssize_t klen = svn__apr_hash_index_klen(hi);
       svn_mergeinfo_t value = svn__apr_hash_index_val(hi);
-      apr_ssize_t padding = 0;
-
-      SVN_ERR_ASSERT(klen >= prefix_len);
-      SVN_ERR_ASSERT(svn_fspath__skip_ancestor(prefix_path, original_path));
+      const char *new_path;
 
-      /* If the ORIGINAL_PATH doesn't match the PREFIX_PATH exactly
-         and we're not simply removing a single leading slash (such as
-         when PREFIX_PATH is "/"), we advance our string offset by an
-         extra character (to get past the directory separator that
-         follows the prefix).  */
-      if ((strcmp(original_path, prefix_path) != 0) && (prefix_len != 1))
-        padding = 1;
+      new_path = svn_fspath__skip_ancestor(prefix_path, original_path);
+      SVN_ERR_ASSERT(new_path);
 
-      apr_hash_set(*out_catalog, original_path + prefix_len + padding,
-                   klen - prefix_len - padding, value);
+      apr_hash_set(*out_catalog, new_path, APR_HASH_KEY_STRING, value);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/skel.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/skel.c Wed Mar 14 13:07:02 2012
@@ -138,7 +138,7 @@ getsize(const char *data, apr_size_t len
 /* Store the ASCII decimal representation of VALUE at DATA.  Return
    the length of the representation if all goes well; return zero if
    the result doesn't fit in LEN bytes.  */
-static int
+static apr_size_t
 putsize(char *data, apr_size_t len, apr_size_t value)
 {
   apr_size_t i = 0;
@@ -157,7 +157,7 @@ putsize(char *data, apr_size_t len, apr_
 
   /* Put the digits in most-significant-first order.  */
   {
-    int left, right;
+    apr_size_t left, right;
 
     for (left = 0, right = i-1; left < right; left++, right--)
       {
@@ -492,7 +492,7 @@ unparse(const svn_skel_t *skel, svn_stri
         {
           /* Append the length to STR.  */
           char buf[200];
-          int length_len;
+          apr_size_t length_len;
 
           length_len = putsize(buf, sizeof(buf), skel->len);
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/sqlite.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/sqlite.c Wed Mar 14 13:07:02 2012
@@ -120,16 +120,17 @@ struct svn_sqlite__value_t
 {                                                                \
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
-    return svn_error_create(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                            NULL, sqlite3_errmsg((db)->db3));    \
+    return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
+                             NULL, "sqlite: %s",                 \
+                             sqlite3_errmsg((db)->db3));         \
 } while (0)
 
 #define SQLITE_ERR_MSG(x, msg) do                                \
 {                                                                \
   int sqlite_err__temp = (x);                                    \
   if (sqlite_err__temp != SQLITE_OK)                             \
-    return svn_error_create(SQLITE_ERROR_CODE(sqlite_err__temp), \
-                            NULL, msg);                          \
+    return svn_error_createf(SQLITE_ERROR_CODE(sqlite_err__temp), \
+                             NULL, "sqlite: %s", (msg));         \
 } while (0)
 
 
@@ -245,8 +246,8 @@ svn_sqlite__step(svn_boolean_t *got_row,
     {
       svn_error_t *err1, *err2;
 
-      err1 = svn_error_create(SQLITE_ERROR_CODE(sqlite_result), NULL,
-                              sqlite3_errmsg(stmt->db->db3));
+      err1 = svn_error_createf(SQLITE_ERROR_CODE(sqlite_result), NULL,
+                               "sqlite: %s", sqlite3_errmsg(stmt->db->db3));
       err2 = svn_sqlite__reset(stmt);
       return svn_error_compose_create(err1, err2);
     }
@@ -678,14 +679,15 @@ internal_open(sqlite3 **db3, const char 
       int err_code = sqlite3_open_v2(path, db3, flags, NULL);
       if (err_code != SQLITE_OK)
         {
+          /* Save the error message before closing the SQLite handle. */
           char *msg = apr_pstrdup(scratch_pool, sqlite3_errmsg(*db3));
 
           /* We don't catch the error here, since we care more about the open
              error than the close error at this point. */
           sqlite3_close(*db3);
 
-          msg = apr_pstrcat(scratch_pool, msg, ": '", path, "'", (char *)NULL);
-          return svn_error_create(SQLITE_ERROR_CODE(err_code), NULL, msg);
+          return svn_error_createf(SQLITE_ERROR_CODE(err_code), NULL,
+                                   "sqlite: %s: '%s'", msg, path);
         }
     }
   }

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/stream.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/stream.c Wed Mar 14 13:07:02 2012
@@ -1008,7 +1008,7 @@ read_handler_gz(void *baton, char *buffe
     }
 
   btn->in->next_out = (Bytef *) buffer;
-  btn->in->avail_out = *len;
+  btn->in->avail_out = (uInt) *len;
 
   while (btn->in->avail_out > 0)
     {
@@ -1067,12 +1067,12 @@ write_handler_gz(void *baton, const char
   write_buf = apr_palloc(subpool, buf_size);
 
   btn->out->next_in = (Bytef *) buffer;  /* Casting away const! */
-  btn->out->avail_in = *len;
+  btn->out->avail_in = (uInt) *len;
 
   while (btn->out->avail_in > 0)
     {
       btn->out->next_out = write_buf;
-      btn->out->avail_out = buf_size;
+      btn->out->avail_out = (uInt) buf_size;
 
       zerr = deflate(btn->out, Z_NO_FLUSH);
       SVN_ERR(svn_error__wrap_zlib(zerr, "deflate", btn->out->msg));

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_mutex.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_mutex.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_mutex.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_mutex.c Wed Mar 14 13:07:02 2012
@@ -25,8 +25,8 @@
 #include "private/svn_mutex.h"
 
 svn_error_t *
-svn_mutex__init(svn_mutex__t **mutex_p, 
-                svn_boolean_t mutex_required, 
+svn_mutex__init(svn_mutex__t **mutex_p,
+                svn_boolean_t mutex_required,
                 apr_pool_t *result_pool)
 {
   /* always initialize the mutex pointer, even though it is not
@@ -47,7 +47,7 @@ svn_mutex__init(svn_mutex__t **mutex_p, 
       *mutex_p = apr_mutex;
     }
 #endif
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -67,7 +67,7 @@ svn_mutex__lock(svn_mutex__t *mutex)
 }
 
 svn_error_t *
-svn_mutex__unlock(svn_mutex__t *mutex, 
+svn_mutex__unlock(svn_mutex__t *mutex,
                   svn_error_t *err)
 {
 #if APR_HAS_THREADS

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_string.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_string.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/svn_string.c Wed Mar 14 13:07:02 2012
@@ -133,7 +133,7 @@ create_string(const char *data, apr_size
 }
 
 static char empty_buffer[1] = {0};
-  
+
 svn_string_t *
 svn_string_create_empty(apr_pool_t *pool)
 {
@@ -302,7 +302,7 @@ svn_stringbuf_create_empty(apr_pool_t *p
 {
   /* All instances share the same zero-length buffer.
    * Some algorithms, however, assume that they may write
-   * the terminating zero. So, empty_buffer must be writable 
+   * the terminating zero. So, empty_buffer must be writable
    * (a simple (char *)"" will cause SEGFAULTs). */
 
   return create_stringbuf(empty_buffer, 0, 0, pool);
@@ -717,7 +717,7 @@ svn_cstring_match_list(const char *str, 
   return FALSE;
 }
 
-char * 
+char *
 svn_cstring_tokenize(const char *sep, char **str)
 {
     char *token;
@@ -742,7 +742,7 @@ svn_cstring_tokenize(const char *sep, ch
         return NULL;
 
     /* skip valid token characters to terminate token and
-     * prepare for the next call (will terminate at '\0) 
+     * prepare for the next call (will terminate at '\0)
      */
     next = strchr(token, csep);
     if (next == NULL)

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_subr/utf.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_subr/utf.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_subr/utf.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_subr/utf.c Wed Mar 14 13:07:02 2012
@@ -200,8 +200,8 @@ atomic_swap(void * volatile * mem, void 
 #endif
 }
 
-/* Set *RET to a newly created handle node for converting from FROMPAGE 
-   to TOPAGE, If apr_xlate_open() returns APR_EINVAL or APR_ENOTIMPL, set 
+/* Set *RET to a newly created handle node for converting from FROMPAGE
+   to TOPAGE, If apr_xlate_open() returns APR_EINVAL or APR_ENOTIMPL, set
    (*RET)->handle to NULL.  If fail for any other reason, return the error.
    Allocate *RET and its xlate handle in POOL. */
 static svn_error_t *
@@ -274,11 +274,11 @@ xlate_alloc_handle(xlate_handle_node_t *
 
 /* Extend xlate_alloc_handle by using USERDATA_KEY as a key in our
    global hash map, if available.
-   
+
    Allocate *RET and its xlate handle in POOL if svn_utf_initialize()
    hasn't been called or USERDATA_KEY is NULL.  Else, allocate them
    in the pool of xlate_handle_hash.
-   
+
    Note: this function is not thread-safe. Call get_xlate_handle_node
    instead. */
 static svn_error_t *
@@ -292,7 +292,7 @@ get_xlate_handle_node_internal(xlate_han
       xlate_handle_node_t *old_node = NULL;
 
       /* 2nd level: hash lookup */
-      xlate_handle_node_t **old_node_p = apr_hash_get(xlate_handle_hash, 
+      xlate_handle_node_t **old_node_p = apr_hash_get(xlate_handle_hash,
                                                       userdata_key,
                                                       APR_HASH_KEY_STRING);
       if (old_node_p)
@@ -381,7 +381,7 @@ get_xlate_handle_node(xlate_handle_node_
 }
 
 /* Put back NODE into the xlate handle cache for use by other calls.
-   
+
    Note: this function is not thread-safe. Call put_xlate_handle_node
    instead. */
 static svn_error_t *
@@ -403,7 +403,7 @@ put_xlate_handle_node_internal(xlate_han
     }
   node->next = *node_p;
   *node_p = node;
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -431,7 +431,7 @@ put_xlate_handle_node(xlate_handle_node_
         return SVN_NO_ERROR;
 
       SVN_MUTEX__WITH_LOCK(xlate_handle_mutex,
-                           put_xlate_handle_node_internal(node, 
+                           put_xlate_handle_node_internal(node,
                                                           userdata_key));
     }
   else
@@ -439,7 +439,7 @@ put_xlate_handle_node(xlate_handle_node_
       /* Store it in the per-pool cache. */
       apr_pool_userdata_set(node, userdata_key, apr_pool_cleanup_null, pool);
     }
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -748,7 +748,7 @@ svn_utf_stringbuf_to_utf8(svn_stringbuf_
 
   return svn_error_compose_create(err,
                                   put_xlate_handle_node
-                                     (node, 
+                                     (node,
                                       SVN_UTF_NTOU_XLATE_HANDLE,
                                       pool));
 }
@@ -782,7 +782,7 @@ svn_utf_string_to_utf8(const svn_string_
 
   return svn_error_compose_create(err,
                                   put_xlate_handle_node
-                                     (node, 
+                                     (node,
                                       SVN_UTF_NTOU_XLATE_HANDLE,
                                       pool));
 }
@@ -827,7 +827,7 @@ svn_utf_cstring_to_utf8(const char **des
   err = convert_cstring(dest, src, node, pool);
   SVN_ERR(svn_error_compose_create(err,
                                    put_xlate_handle_node
-                                      (node, 
+                                      (node,
                                        SVN_UTF_NTOU_XLATE_HANDLE,
                                        pool)));
   return check_cstring_utf8(*dest, pool);
@@ -850,7 +850,7 @@ svn_utf_cstring_to_utf8_ex2(const char *
   err = convert_cstring(dest, src, node, pool);
   SVN_ERR(svn_error_compose_create(err,
                                    put_xlate_handle_node
-                                      (node, 
+                                      (node,
                                        SVN_UTF_NTOU_XLATE_HANDLE,
                                        pool)));
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_crawler.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_crawler.c Wed Mar 14 13:07:02 2012
@@ -494,10 +494,14 @@ report_revisions_and_depths(svn_wc__db_t
         {
           svn_boolean_t is_incomplete;
           svn_boolean_t start_empty;
+          svn_depth_t report_depth = ths->depth;
 
           is_incomplete = (ths->status == svn_wc__db_status_incomplete);
           start_empty = is_incomplete;
 
+          if (!SVN_DEPTH_IS_RECURSIVE(depth))
+            report_depth = svn_depth_empty;
+
           /* When a <= 1.6 working copy is upgraded without some of its
              subdirectories we miss some information in the database. If we
              report the revision as -1, the update editor will receive an
@@ -525,7 +529,7 @@ report_revisions_and_depths(svn_wc__db_t
                                                 dir_repos_root,
                                                 ths->repos_relpath, iterpool),
                                             ths->revnum,
-                                            ths->depth,
+                                            report_depth,
                                             start_empty,
                                             ths->lock ? ths->lock->token
                                                       : NULL,
@@ -534,7 +538,7 @@ report_revisions_and_depths(svn_wc__db_t
                 SVN_ERR(reporter->set_path(report_baton,
                                            this_report_relpath,
                                            ths->revnum,
-                                           ths->depth,
+                                           report_depth,
                                            start_empty,
                                            ths->lock ? ths->lock->token : NULL,
                                            iterpool));
@@ -548,7 +552,7 @@ report_revisions_and_depths(svn_wc__db_t
                                               dir_repos_root,
                                               ths->repos_relpath, iterpool),
                                           ths->revnum,
-                                          ths->depth,
+                                          report_depth,
                                           start_empty,
                                           ths->lock ? ths->lock->token : NULL,
                                           iterpool));
@@ -572,7 +576,7 @@ report_revisions_and_depths(svn_wc__db_t
               SVN_ERR(reporter->set_path(report_baton,
                                          this_report_relpath,
                                          ths->revnum,
-                                         ths->depth,
+                                         report_depth,
                                          start_empty,
                                          ths->lock ? ths->lock->token : NULL,
                                          iterpool));

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_ops.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/adm_ops.c Wed Mar 14 13:07:02 2012
@@ -610,8 +610,7 @@ svn_wc__delete_many(svn_wc_context_t *wc
   svn_error_t *err;
   svn_wc__db_status_t status;
   svn_kind_t kind;
-  svn_boolean_t conflicted;
-  const apr_array_header_t *conflicts;
+  const apr_array_header_t *conflicts = NULL;
   apr_array_header_t *versioned_targets;
   const char *local_abspath;
   int i;
@@ -622,6 +621,8 @@ svn_wc__delete_many(svn_wc_context_t *wc
                                      sizeof(const char *));
   for (i = 0; i < targets->nelts; i++)
     {
+      svn_boolean_t conflicted = FALSE;
+
       svn_pool_clear(iterpool);
 
       local_abspath = APR_ARRAY_IDX(targets, i, const char *);
@@ -699,7 +700,7 @@ svn_wc__delete_many(svn_wc_context_t *wc
                                     cancel_func, cancel_baton,
                                     notify_func, notify_baton, scratch_pool));
 
-  if (!keep_local && conflicted && conflicts != NULL)
+  if (!keep_local && conflicts != NULL)
     {
       svn_pool_clear(iterpool);
 
@@ -1711,7 +1712,7 @@ revert_restore(svn_wc__db_t *db,
           svn_boolean_t removed;
 
           SVN_ERR(revert_restore_handle_copied_dirs(&removed, db,
-                                                    local_abspath, TRUE, 
+                                                    local_abspath, TRUE,
                                                     cancel_func, cancel_baton,
                                                     scratch_pool));
           if (removed)
@@ -1736,8 +1737,15 @@ revert_restore(svn_wc__db_t *db,
         }
       else if (on_disk == svn_node_file && kind != svn_kind_file)
         {
-          SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool));
-          on_disk = svn_node_none;
+#ifdef HAVE_SYMLINK
+          /* Preserve symlinks pointing at directories. Changes on the
+           * directory node have been reverted. The symlink should remain. */
+          if (!(special && kind == svn_kind_dir))
+#endif
+            {
+              SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool));
+              on_disk = svn_node_none;
+            }
         }
       else if (on_disk == svn_node_file)
         {

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/entries.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/entries.c Wed Mar 14 13:07:02 2012
@@ -1897,7 +1897,7 @@ write_entry(struct write_baton **entry_n
         }
       else if (entry->absent)
         {
-          SVN_ERR_ASSERT(base_node->presence 
+          SVN_ERR_ASSERT(base_node->presence
                                 == svn_wc__db_status_server_excluded);
           /* ### should be svn_node_unknown, but let's store what we have. */
           base_node->kind = entry->kind;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/externals.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/externals.c Wed Mar 14 13:07:02 2012
@@ -1181,7 +1181,7 @@ svn_wc__committable_externals_below(apr_
                                                  local_abspath,
                                                  depth != svn_depth_infinity,
                                                  result_pool, scratch_pool));
-  
+
   if (orig_externals == NULL)
     return SVN_NO_ERROR;
 
@@ -1363,6 +1363,16 @@ svn_wc__externals_gather_definitions(apr
     }
 }
 
+svn_error_t *
+svn_wc__close_db(const char *external_abspath,
+                 svn_wc_context_t *wc_ctx,
+                 apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__db_drop_root(wc_ctx->db, external_abspath,
+                               scratch_pool));
+  return SVN_NO_ERROR;
+}
+
 /* Return the scheme of @a uri in @a scheme allocated from @a pool.
    If @a uri does not appear to be a valid URI, then @a scheme will
    not be updated.  */

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/props.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/props.c Wed Mar 14 13:07:02 2012
@@ -2546,7 +2546,8 @@ svn_wc_canonicalize_svn_prop(const svn_s
            || strcmp(propname, SVN_PROP_EXTERNALS) == 0)
     {
       /* Make sure that the last line ends in a newline */
-      if (propval->data[propval->len - 1] != '\n')
+      if (propval->len == 0
+          || propval->data[propval->len - 1] != '\n')
         {
           new_value = svn_stringbuf_create_from_string(propval, pool);
           svn_stringbuf_appendbyte(new_value, '\n');

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/status.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/status.c Wed Mar 14 13:07:02 2012
@@ -294,7 +294,7 @@ read_info(const struct svn_wc__db_info_t
         {
           const char *moved_to_abspath;
           const char *moved_to_op_root_abspath;
-          
+
           /* NOTE: we can't use op-root-ness as a condition here since a base
            * node can be the root of a move and still not be an explicit
            * op-root (having a working node with op_depth == pathelements).
@@ -303,7 +303,7 @@ read_info(const struct svn_wc__db_info_t
            *   svn mv a/b bb
            *   svn del a
            * and
-           *   svn mv a aa  
+           *   svn mv a aa
            *   svn mv aa/b bb
            * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
            * node at all, as its parent 'a' is locally deleted. */
@@ -526,9 +526,17 @@ assemble_status(svn_wc_status3_t **statu
           if (!info->have_base)
             copied = TRUE;
           else
-            SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
-                                                       db, local_abspath,
-                                                       scratch_pool));
+            {
+              const char *work_del_abspath;
+
+              /* Find out details of our deletion.  */
+              SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
+                                               &work_del_abspath, NULL,
+                                               db, local_abspath,
+                                               scratch_pool, scratch_pool));
+              if (work_del_abspath)
+                copied = TRUE; /* Working deletion */
+            }
         }
       else if (!dirent || dirent->kind != svn_node_dir)
         {
@@ -544,11 +552,17 @@ assemble_status(svn_wc_status3_t **statu
     {
       if (info->status == svn_wc__db_status_deleted)
         {
+          const char *work_del_abspath;
+
           node_status = svn_wc_status_deleted;
 
-          SVN_ERR(svn_wc__internal_node_get_schedule(NULL, &copied,
-                                                     db, local_abspath,
-                                                     scratch_pool));
+          /* Find out details of our deletion.  */
+          SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
+                                           &work_del_abspath, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+          if (work_del_abspath)
+            copied = TRUE; /* Working deletion */
         }
       else if (!dirent || dirent->kind != svn_node_file)
         {
@@ -1203,7 +1217,7 @@ one_child_status(const struct walk_statu
   /* The node exists on disk but there is no versioned information about it,
    * or it doesn't exist but is a tree conflicted path or should be
    * reported not-present. */
-   
+
   /* Why pass ignore patterns on a tree conflicted node, even if it should
    * always show up in clients' status reports anyway? Because the calling
    * client decides whether to ignore, and thus this flag needs to be
@@ -1318,13 +1332,37 @@ get_dir_status(const struct walk_status_
 
   /* Handle "this-dir" first. */
   if (! skip_this_dir)
-    SVN_ERR(send_status_structure(wb, local_abspath,
-                                  parent_repos_root_url,
-                                  parent_repos_relpath,
-                                  parent_repos_uuid,
-                                  dir_info, dirent, get_all,
-                                  status_func, status_baton,
-                                  iterpool));
+    {
+#ifdef HAVE_SYMLINK
+      if (dirent->special)
+        {
+          svn_io_dirent2_t *this_dirent = svn_io_dirent2_dup(dirent, iterpool);
+
+          /* We're being pointed to "this-dir" via a symlink.
+           * Get the real node kind and pretend the path is not a symlink.
+           * This prevents send_status_structure() from treating this-dir
+           * as a directory obstructed by a file. */
+          SVN_ERR(svn_io_check_resolved_path(local_abspath,
+                                             &this_dirent->kind, iterpool));
+          this_dirent->special = FALSE;
+          SVN_ERR(send_status_structure(wb, local_abspath,
+                                        parent_repos_root_url,
+                                        parent_repos_relpath,
+                                        parent_repos_uuid,
+                                        dir_info, this_dirent, get_all,
+                                        status_func, status_baton,
+                                        iterpool));
+        }
+     else
+#endif
+        SVN_ERR(send_status_structure(wb, local_abspath,
+                                      parent_repos_root_url,
+                                      parent_repos_relpath,
+                                      parent_repos_uuid,
+                                      dir_info, dirent, get_all,
+                                      status_func, status_baton,
+                                      iterpool));
+    }
 
   /* If the requested depth is empty, we only need status on this-dir. */
   if (depth == svn_depth_empty)
@@ -1594,9 +1632,9 @@ tweak_statushash(void *baton,
           else
             statstruct->repos_relpath = apr_pstrdup(pool, b->repos_relpath);
 
-          statstruct->repos_root_url = 
+          statstruct->repos_root_url =
                               b->edit_baton->anchor_status->repos_root_url;
-          statstruct->repos_uuid = 
+          statstruct->repos_uuid =
                               b->edit_baton->anchor_status->repos_uuid;
         }
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/update_editor.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/update_editor.c Wed Mar 14 13:07:02 2012
@@ -4581,7 +4581,7 @@ close_file(void *file_baton,
 
       /* If the file was moved-away, notify for the moved-away node.
        * The original location only had its BASE info changed and
-       * we don't usually notify about such changes. */ 
+       * we don't usually notify about such changes. */
       notify = svn_wc_create_notify(working_abspath, action, scratch_pool);
       notify->kind = svn_node_file;
       notify->content_state = content_state;

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/util.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/util.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/util.c Wed Mar 14 13:07:02 2012
@@ -548,7 +548,7 @@ svn_wc__fetch_kind_func(svn_kind_t *kind
 
   SVN_ERR(svn_wc__db_read_kind(kind, sfb->db, local_abspath, FALSE,
                                scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.c Wed Mar 14 13:07:02 2012
@@ -3703,7 +3703,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
                   dst_wcroot->wc_id,
                   dst_relpath,
                   copyfrom_id,
-                  copyfrom_relpath, 
+                  copyfrom_relpath,
                   copyfrom_rev,
                   children,
                   dst_op_depth,
@@ -6678,7 +6678,7 @@ op_delete_many_txn(void *baton,
       const char *target_relpath = APR_ARRAY_IDX(odmb->rel_targets, i,
                                                  const char *);
       struct op_delete_baton_t odb;
-      
+
       svn_pool_clear(iterpool);
       odb.delete_depth = relpath_depth(target_relpath);
       odb.moved_to_relpath = NULL;
@@ -6764,7 +6764,7 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
                                                 db, local_abspath,
                                                 scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
-  
+
   if (moved_to_abspath)
     {
       SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&moved_to_wcroot,
@@ -6852,7 +6852,7 @@ svn_wc__db_op_delete_many(svn_wc__db_t *
 
     }
   svn_pool_destroy(iterpool);
-  
+
   /* Perform the deletion operation (transactionally), perform any
      notifications necessary, and then clean out our temporary tables.  */
   return svn_error_trace(with_finalization(wcroot, wcroot->abspath,
@@ -7198,7 +7198,7 @@ read_info(svn_wc__db_status_t *status,
     err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
 
   if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-    err = svn_error_quick_wrap(err, 
+    err = svn_error_quick_wrap(err,
                                apr_psprintf(scratch_pool,
                                             "Error reading node '%s'",
                                             local_relpath));
@@ -7210,6 +7210,49 @@ read_info(svn_wc__db_status_t *status,
 
 
 svn_error_t *
+svn_wc__db_read_info_internal(svn_wc__db_status_t *status,
+                              svn_kind_t *kind,
+                              svn_revnum_t *revision,
+                              const char **repos_relpath,
+                              apr_int64_t *repos_id,
+                              svn_revnum_t *changed_rev,
+                              apr_time_t *changed_date,
+                              const char **changed_author,
+                              svn_depth_t *depth,
+                              const svn_checksum_t **checksum,
+                              const char **target,
+                              const char **original_repos_relpath,
+                              apr_int64_t *original_repos_id,
+                              svn_revnum_t *original_revision,
+                              svn_wc__db_lock_t **lock,
+                              svn_filesize_t *recorded_size,
+                              apr_time_t *recorded_mod_time,
+                              const char **changelist,
+                              svn_boolean_t *conflicted,
+                              svn_boolean_t *op_root,
+                              svn_boolean_t *had_props,
+                              svn_boolean_t *props_mod,
+                              svn_boolean_t *have_base,
+                              svn_boolean_t *have_more_work,
+                              svn_boolean_t *have_work,
+                              svn_wc__db_wcroot_t *wcroot,
+                              const char *local_relpath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+           read_info(status, kind, revision, repos_relpath, repos_id,
+                     changed_rev, changed_date, changed_author,
+                     depth, checksum, target, original_repos_relpath,
+                     original_repos_id, original_revision, lock,
+                     recorded_size, recorded_mod_time, changelist, conflicted,
+                     op_root, had_props, props_mod,
+                     have_base, have_more_work, have_work,
+                     wcroot, local_relpath, result_pool, scratch_pool));
+}
+
+
+svn_error_t *
 svn_wc__db_read_info(svn_wc__db_status_t *status,
                      svn_kind_t *kind,
                      svn_revnum_t *revision,
@@ -7506,7 +7549,6 @@ read_children_info(void *baton,
       struct svn_wc__db_info_t *child;
       const char *child_relpath = svn_sqlite__column_text(stmt, 7, NULL);
       const char *name = svn_relpath_basename(child_relpath, NULL);
-      svn_error_t *err;
 
       child_item = apr_hash_get(nodes, name, APR_HASH_KEY_STRING);
       if (!child_item)
@@ -7523,6 +7565,7 @@ read_children_info(void *baton,
 #ifdef HAVE_SYMLINK
       if (child->props_mod)
         {
+          svn_error_t *err;
           apr_hash_t *properties;
 
           err = svn_sqlite__column_properties(&properties, stmt, 6,
@@ -10284,9 +10327,9 @@ scan_deletion_txn(void *baton,
               moved_to_relpath = svn_relpath_join(moved_to_op_root_relpath,
                                                   moved_child_relpath,
                                                   scratch_pool);
-              
+
               if (sd_baton->moved_to_relpath)
-                *sd_baton->moved_to_relpath = moved_to_relpath ? 
+                *sd_baton->moved_to_relpath = moved_to_relpath ?
                   apr_pstrdup(sd_baton->result_pool, moved_to_relpath) : NULL;
             }
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.h?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db.h Wed Mar 14 13:07:02 2012
@@ -1535,7 +1535,7 @@ svn_wc__db_op_revert(svn_wc__db_t *db,
  * path was reverted.  Set *CONFLICT_OLD, *CONFLICT_NEW,
  * *CONFLICT_WORKING and *PROP_REJECT to the names of the conflict
  * files, or NULL if the names are not stored.
- * 
+ *
  * Set *COPIED_HERE if the reverted node was copied here and is the
  * operation root of the copy.
  * Set *KIND to the node kind of the reverted node.

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_private.h?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_private.h Wed Mar 14 13:07:02 2012
@@ -54,7 +54,7 @@ struct svn_wc__db_t {
   struct
   {
     svn_stringbuf_t *abspath;
-    svn_node_kind_t kind;
+    svn_kind_t kind;
   } parse_cache;
 
   /* As we grow the state of this DB, allocate that state here. */
@@ -174,6 +174,39 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 
+/* Like svn_wc__db_read_info(), but taking WCROOT+LOCAL_RELPATH instead of
+   DB+LOCAL_ABSPATH, and outputting repos ids instead of URL+UUID. */
+svn_error_t *
+svn_wc__db_read_info_internal(svn_wc__db_status_t *status,
+                              svn_kind_t *kind,
+                              svn_revnum_t *revision,
+                              const char **repos_relpath,
+                              apr_int64_t *repos_id,
+                              svn_revnum_t *changed_rev,
+                              apr_time_t *changed_date,
+                              const char **changed_author,
+                              svn_depth_t *depth,
+                              const svn_checksum_t **checksum,
+                              const char **target,
+                              const char **original_repos_relpath,
+                              apr_int64_t *original_repos_id,
+                              svn_revnum_t *original_revision,
+                              svn_wc__db_lock_t **lock,
+                              svn_filesize_t *recorded_size,
+                              apr_time_t *recorded_mod_time,
+                              const char **changelist,
+                              svn_boolean_t *conflicted,
+                              svn_boolean_t *op_root,
+                              svn_boolean_t *had_props,
+                              svn_boolean_t *props_mod,
+                              svn_boolean_t *have_base,
+                              svn_boolean_t *have_more_work,
+                              svn_boolean_t *have_work,
+                              svn_wc__db_wcroot_t *wcroot,
+                              const char *local_relpath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
+
 
 /* Transaction handling */
 

Modified: subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_wcroot.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/multi-layer-moves/subversion/libsvn_wc/wc_db_wcroot.c Wed Mar 14 13:07:02 2012
@@ -100,16 +100,15 @@ get_old_version(int *version,
    of LOCAL_ABSPATH, using DB and SCRATCH_POOL as needed.
 
    This function may do strange things, but at long as it comes up with the
-   Right Answer, we should be happy.
-
-   Sets *KIND to svn_node_dir for symlinks. */
+   Right Answer, we should be happy. */
 static svn_error_t *
-get_path_kind(svn_node_kind_t *kind,
+get_path_kind(svn_kind_t *kind,
               svn_wc__db_t *db,
               const char *local_abspath,
               apr_pool_t *scratch_pool)
 {
   svn_boolean_t special;
+  svn_node_kind_t node_kind;
 
   /* This implements a *really* simple LRU cache, where "simple" is defined
      as "only one element".  In other words, we remember the most recently
@@ -133,12 +132,10 @@ get_path_kind(svn_node_kind_t *kind,
       svn_stringbuf_set(db->parse_cache.abspath, local_abspath);
     }
 
-  SVN_ERR(svn_io_check_special_path(local_abspath, &db->parse_cache.kind,
+  SVN_ERR(svn_io_check_special_path(local_abspath, &node_kind,
                                     &special, scratch_pool));
 
-  /* The wcroot could be a symlink to a directory. (Issue #2557, #3987) */
-  if (special)
-    db->parse_cache.kind = svn_node_dir;
+  db->parse_cache.kind = svn__kind_from_node_kind(node_kind, special);
   *kind = db->parse_cache.kind;
 
   return SVN_NO_ERROR;
@@ -366,7 +363,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
 {
   const char *local_dir_abspath;
   const char *original_abspath = local_abspath;
-  svn_node_kind_t kind;
+  svn_kind_t kind;
   const char *build_relpath;
   svn_wc__db_wcroot_t *probe_wcroot;
   svn_wc__db_wcroot_t *found_wcroot = NULL;
@@ -402,7 +399,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
      ### into wc_db which references a file. calls for directories could
      ### get an early-exit in the hash lookup just above.  */
   SVN_ERR(get_path_kind(&kind, db, local_abspath, scratch_pool));
-  if (kind != svn_node_dir)
+  if (kind != svn_kind_dir)
     {
       /* If the node specified by the path is NOT present, then it cannot
          possibly be a directory containing ".svn/wc.db".
@@ -437,7 +434,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
          many ancestors need to be scanned until we start hitting content
          on the disk. Set ALWAYS_CHECK to keep looking for .svn/entries
          rather than bailing out after the first check.  */
-      if (kind == svn_node_none)
+      if (kind == svn_kind_none)
         always_check = TRUE;
 
       /* Start the scanning at LOCAL_DIR_ABSPATH.  */
@@ -511,6 +508,38 @@ svn_wc__db_wcroot_parse_local_abspath(sv
       if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
         {
           /* Hit the root without finding a wcroot. */
+
+          /* The wcroot could be a symlink to a directory.
+           * (Issue #2557, #3987). If so, try again, this time scanning
+           * for a db within the directory the symlink points to,
+           * rather than within the symlink's parent directory. */
+          if (kind == svn_kind_symlink)
+            {
+              svn_node_kind_t resolved_kind;
+
+              local_abspath = original_abspath;
+
+              SVN_ERR(svn_io_check_resolved_path(local_abspath,
+                                                 &resolved_kind,
+                                                 scratch_pool));
+              if (resolved_kind == svn_node_dir)
+                {
+                  /* Is this directory recorded in our hash?  */
+                  found_wcroot = apr_hash_get(db->dir_data, local_abspath,
+                                              APR_HASH_KEY_STRING);
+                  if (found_wcroot)
+                    break;
+
+try_symlink_as_dir:
+                  kind = svn_kind_dir;
+                  moved_upwards = FALSE;
+                  local_dir_abspath = local_abspath;
+                  build_relpath = "";
+
+                  continue;
+                }
+            }
+
           return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
                                    _("'%s' is not a working copy"),
                                    svn_dirent_local_style(original_abspath,
@@ -584,6 +613,61 @@ svn_wc__db_wcroot_parse_local_abspath(sv
     *local_relpath = svn_relpath_join(dir_relpath, build_relpath, result_pool);
   }
 
+  if (kind == svn_kind_symlink)
+    {
+      svn_boolean_t retry_if_dir = FALSE;
+      svn_wc__db_status_t status;
+      svn_boolean_t conflicted;
+      svn_error_t *err;
+
+      /* Check if the symlink is versioned or obstructs a versioned node
+       * in this DB -- in that case, use this wcroot. Else, if the symlink
+       * points to a directory, try to find a wcroot in that directory
+       * instead. */
+
+      err = svn_wc__db_read_info_internal(&status, NULL, NULL, NULL, NULL,
+                                          NULL, NULL, NULL, NULL, NULL, NULL,
+                                          NULL, NULL, NULL, NULL, NULL, NULL,
+                                          NULL, &conflicted, NULL, NULL, NULL,
+                                          NULL, NULL, NULL,
+                                          *wcroot, *local_relpath,
+                                          scratch_pool, scratch_pool);
+      if (err)
+        {
+          if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
+              && !SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
+            return svn_error_trace(err);
+
+          svn_error_clear(err);
+          retry_if_dir = TRUE; /* The symlink is unversioned. */
+        }
+      else
+        {
+          /* The symlink is versioned, or obstructs a versioned node.
+           * Ignore non-conflicted not-present/excluded nodes.
+           * This allows the symlink to redirect the wcroot query to a
+           * directory, regardless of 'invisible' nodes in this WC. */
+          retry_if_dir = ((status == svn_wc__db_status_not_present ||
+                           status == svn_wc__db_status_excluded ||
+                           status == svn_wc__db_status_server_excluded)
+                          && !conflicted);
+        }
+
+      if (retry_if_dir)
+        {
+          svn_node_kind_t resolved_kind;
+
+          SVN_ERR(svn_io_check_resolved_path(original_abspath,
+                                             &resolved_kind,
+                                             scratch_pool));
+          if (resolved_kind == svn_node_dir)
+            {
+              local_abspath = original_abspath;
+              goto try_symlink_as_dir;
+            }
+        }
+    }
+
   /* We've found the appropriate WCROOT for the requested path. Stash
      it into that path's directory.  */
   apr_hash_set(db->dir_data,

Modified: subversion/branches/multi-layer-moves/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/mod_dav_svn/liveprops.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/multi-layer-moves/subversion/mod_dav_svn/liveprops.c Wed Mar 14 13:07:02 2012
@@ -282,6 +282,9 @@ insert_prop_internal(const dav_resource 
   int global_ns;
   svn_error_t *serr;
 
+  /* ### TODO proper errors */
+  static const char *const error_value = "###error###";
+
   /*
   ** Almost none of the SVN provider properties are defined if the
   ** resource does not exist.  We do need to return the one VCC
@@ -378,14 +381,14 @@ insert_prop_internal(const dav_resource 
                                            scratch_pool);
             if (serr != NULL)
               {
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                               resource->info->r,
                               "Can't get created-rev of '%s': "
                               "%s",
                               resource->info->repos_path,
                               serr->message);
                 svn_error_clear(serr);
-                value = "###error###";
+                value = error_value;
                 break;
               }
           }
@@ -401,14 +404,14 @@ insert_prop_internal(const dav_resource 
                                 scratch_pool);
         if (serr)
           {
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                           resource->info->r,
                           "Can't get author of r%ld: "
                           "%s",
                           committed_rev,
                           serr->message);
             svn_error_clear(serr);
-            value = "###error###";
+            value = error_value;
             break;
           }
 
@@ -436,8 +439,14 @@ insert_prop_internal(const dav_resource 
                                   resource->info->repos_path, scratch_pool);
         if (serr != NULL)
           {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
+                          resource->info->r,
+                          "Can't get filesize of '%s': "
+                          "%s",
+                          resource->info->repos_path,
+                          serr->message);
             svn_error_clear(serr);
-            value = "0";  /* ### what to do? */
+            value = error_value;
             break;
           }
 
@@ -494,7 +503,7 @@ insert_prop_internal(const dav_resource 
                    there's no point even checking.  No matter what the
                    error is, we can't claim to have a mime type for
                    this resource. */
-                ap_log_rerror(APLOG_MARK, APLOG_WARNING, serr->apr_err, 
+                ap_log_rerror(APLOG_MARK, APLOG_WARNING, serr->apr_err,
                               resource->info->r, "%s", serr->message);
                 svn_error_clear(serr);
                 return DAV_PROP_INSERT_NOTDEF;
@@ -549,7 +558,7 @@ insert_prop_internal(const dav_resource 
                                      scratch_pool);
           if (serr != NULL)
             {
-              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
                             "Can't get youngest revision in '%s': "
                             "%s",
@@ -557,7 +566,7 @@ insert_prop_internal(const dav_resource 
                                         scratch_pool),
                             serr->message);
               svn_error_clear(serr);
-              value = "###error###";
+              value = error_value;
               break;
             }
           s = dav_svn__build_uri(resource->info->repos,
@@ -629,14 +638,14 @@ insert_prop_internal(const dav_resource 
                                          scratch_pool);
           if (serr != NULL)
             {
-              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
                             "Can't get created-rev of '%s': "
                             "%s",
                             resource->info->repos_path,
                             serr->message);
               svn_error_clear(serr);
-              value = "###error###";
+              value = error_value;
               break;
             }
 
@@ -677,14 +686,14 @@ insert_prop_internal(const dav_resource 
                                         scratch_pool);
           if (serr != NULL)
             {
-              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                             resource->info->r,
                             "Can't fetch or compute MD5 checksum of '%s': "
                             "%s",
                             resource->info->repos_path,
                             serr->message);
               svn_error_clear(serr);
-              value = "###error###";
+              value = error_value;
               break;
             }
 
@@ -705,14 +714,14 @@ insert_prop_internal(const dav_resource 
       serr = svn_fs_get_uuid(resource->info->repos->fs, &value, scratch_pool);
       if (serr != NULL)
         {
-          ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                         resource->info->r,
                         "Can't fetch UUID of '%s': "
                         "%s",
                         svn_fs_path(resource->info->repos->fs, scratch_pool),
                         serr->message);
           svn_error_clear(serr);
-          value = "###error###";
+          value = error_value;
           break;
         }
       break;
@@ -730,14 +739,14 @@ insert_prop_internal(const dav_resource 
                                     resource->info->repos_path, scratch_pool);
         if (serr != NULL)
           {
-            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
                           resource->info->r,
                           "Can't fetch proplist of '%s': "
                           "%s",
                           resource->info->repos_path,
                           serr->message);
             svn_error_clear(serr);
-            value = "###error###";
+            value = error_value;
             break;
           }
 

Modified: subversion/branches/multi-layer-moves/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/mod_dav_svn/mod_dav_svn.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/multi-layer-moves/subversion/mod_dav_svn/mod_dav_svn.c Wed Mar 14 13:07:02 2012
@@ -559,7 +559,7 @@ SVNHooksEnv_cmd(cmd_parms *cmd, void *co
             {
               svn_stringbuf_appendbyte(buf, '=');
               svn_stringbuf_appendcstr(buf, APR_ARRAY_IDX(var, i, const char *));
-            } 
+            }
 
           val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env), buf->data);
         }

Modified: subversion/branches/multi-layer-moves/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/mod_dav_svn/repos.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/multi-layer-moves/subversion/mod_dav_svn/repos.c Wed Mar 14 13:07:02 2012
@@ -3264,7 +3264,7 @@ deliver(const dav_resource *resource, ap
               if (dirent->kind == svn_node_file && dirent->special)
                 {
                   svn_node_kind_t resolved_kind;
-                  const char *link_path = 
+                  const char *link_path =
                     svn_dirent_join(fs_parent_path, key, resource->pool);
 
                   serr = svn_io_check_resolved_path(link_path, &resolved_kind,
@@ -3277,7 +3277,7 @@ deliver(const dav_resource *resource, ap
                                                 resource->pool);
                   if (resolved_kind != svn_node_dir)
                     continue;
-                  
+
                   dirent->kind = svn_node_dir;
                 }
               else if (dirent->kind != svn_node_dir)

Modified: subversion/branches/multi-layer-moves/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/multi-layer-moves/subversion/mod_dav_svn/version.c?rev=1300532&r1=1300531&r2=1300532&view=diff
==============================================================================
--- subversion/branches/multi-layer-moves/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/multi-layer-moves/subversion/mod_dav_svn/version.c Wed Mar 14 13:07:02 2012
@@ -1382,6 +1382,15 @@ merge(dav_resource *target,
                                     SVN_DAV_ERROR_NAMESPACE,
                                     SVN_DAV_ERROR_TAG);
     }
+  if (! source->exists)
+    {
+      return dav_svn__new_error_tag(pool, HTTP_METHOD_NOT_ALLOWED,
+                                    SVN_ERR_INCORRECT_PARAMS,
+                                    "MERGE activity or transaction resource "
+                                    "does not exist.",
+                                    SVN_DAV_ERROR_NAMESPACE,
+                                    SVN_DAV_ERROR_TAG);
+    }
 
   /* Before attempting the final commit, we need to push any incoming
      lock-tokens into the filesystem's access_t.   Normally they come