You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2011/10/11 21:52:46 UTC

svn commit: r1182053 [17/30] - in /subversion/branches/svn_mutex: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/ contrib/hook-scripts/enforcer/ contrib/server-side/ notes/ notes/merge-t...

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/entries.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/entries.c Tue Oct 11 19:52:34 2011
@@ -61,7 +61,7 @@ typedef struct db_node_t {
   const char *parent_relpath;
   svn_wc__db_status_t presence;
   svn_revnum_t revision;
-  svn_node_kind_t kind;  /* ### should switch to svn_wc__db_kind_t */
+  svn_node_kind_t kind;  /* ### should switch to svn_kind_t */
   svn_checksum_t *checksum;
   svn_filesize_t translated_size;
   svn_revnum_t changed_rev;
@@ -148,7 +148,7 @@ check_file_external(svn_wc_entry_t *entr
                     apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const char *repos_relpath;
   svn_revnum_t peg_revision;
   svn_revnum_t revision;
@@ -169,7 +169,7 @@ check_file_external(svn_wc_entry_t *entr
     }
 
   if (status == svn_wc__db_status_normal
-      && kind == svn_wc__db_kind_file)
+      && kind == svn_kind_file)
     {
       entry->file_external_path = repos_relpath;
       if (SVN_IS_VALID_REVNUM(peg_revision))
@@ -204,7 +204,7 @@ check_file_external(svn_wc_entry_t *entr
 */
 static svn_error_t *
 get_info_for_deleted(svn_wc_entry_t *entry,
-                     svn_wc__db_kind_t *kind,
+                     svn_kind_t *kind,
                      const char **repos_relpath,
                      const svn_checksum_t **checksum,
                      svn_wc__db_t *db,
@@ -272,7 +272,7 @@ get_info_for_deleted(svn_wc_entry_t *ent
 
      SVN_ERR(svn_wc__db_scan_deletion(NULL,
                                       NULL,
-                                      &work_del_abspath,
+                                      &work_del_abspath, NULL,
                                       db, entry_abspath,
                                       scratch_pool, scratch_pool));
 
@@ -285,7 +285,7 @@ get_info_for_deleted(svn_wc_entry_t *ent
                                        &parent_repos_relpath,
                                        &entry->repos,
                                        &entry->uuid,
-                                       NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
                                        db, parent_abspath,
                                        result_pool, scratch_pool));
 
@@ -384,7 +384,7 @@ read_one_entry(const svn_wc_entry_t **ne
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
 {
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_wc__db_status_t status;
   svn_wc__db_lock_t *lock;
   const char *repos_relpath;
@@ -525,7 +525,7 @@ read_one_entry(const svn_wc_entry_t **ne
         {
           const char *work_del_abspath;
           SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                           &work_del_abspath,
+                                           &work_del_abspath, NULL,
                                            db, entry_abspath,
                                            scratch_pool, scratch_pool));
 
@@ -615,6 +615,7 @@ read_one_entry(const svn_wc_entry_t **ne
                                            &scanned_original_relpath,
                                            NULL, NULL, /* original_root|uuid */
                                            &original_revision,
+                                           NULL, NULL,
                                            db,
                                            entry_abspath,
                                            result_pool, scratch_pool));
@@ -637,7 +638,10 @@ read_one_entry(const svn_wc_entry_t **ne
           /* ### scan_addition may need to be updated to avoid returning
              ### status_copied in this case.  */
         }
-      else if (work_status == svn_wc__db_status_copied)
+      /* For backwards-compatiblity purposes we treat moves just like
+       * regular copies. */
+      else if (work_status == svn_wc__db_status_copied ||
+               work_status == svn_wc__db_status_moved_here)
         {
           entry->copied = TRUE;
 
@@ -662,7 +666,8 @@ read_one_entry(const svn_wc_entry_t **ne
           svn_boolean_t is_copied_child;
           svn_boolean_t is_mixed_rev = FALSE;
 
-          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied);
+          SVN_ERR_ASSERT(work_status == svn_wc__db_status_copied ||
+                         work_status == svn_wc__db_status_moved_here);
 
           /* If this node inherits copyfrom information from an
              ancestor node, then it must be a copied child.  */
@@ -712,9 +717,8 @@ read_one_entry(const svn_wc_entry_t **ne
                                              NULL, NULL, NULL,
                                              &parent_repos_relpath,
                                              &parent_root_url,
-                                             NULL, NULL,
-                                             db,
-                                             parent_abspath,
+                                             NULL, NULL, NULL, NULL,
+                                             db, parent_abspath,
                                              scratch_pool,
                                              scratch_pool);
               if (err)
@@ -836,11 +840,11 @@ read_one_entry(const svn_wc_entry_t **ne
   if (entry->depth == svn_depth_unknown)
     entry->depth = svn_depth_infinity;
 
-  if (kind == svn_wc__db_kind_dir)
+  if (kind == svn_kind_dir)
     entry->kind = svn_node_dir;
-  else if (kind == svn_wc__db_kind_file)
+  else if (kind == svn_kind_file)
     entry->kind = svn_node_file;
-  else if (kind == svn_wc__db_kind_symlink)
+  else if (kind == svn_kind_symlink)
     entry->kind = svn_node_file;  /* ### no symlink kind */
   else
     entry->kind = svn_node_unknown;
@@ -892,12 +896,15 @@ read_one_entry(const svn_wc_entry_t **ne
           switch (cd->kind)
             {
             case svn_wc_conflict_kind_text:
-              entry->conflict_old = svn_dirent_basename(cd->base_abspath,
-                                                        result_pool);
-              entry->conflict_new = svn_dirent_basename(cd->their_abspath,
-                                                        result_pool);
-              entry->conflict_wrk = svn_dirent_basename(cd->my_abspath,
-                                                        result_pool);
+              if (cd->base_abspath)
+                entry->conflict_old = svn_dirent_basename(cd->base_abspath,
+                                                          result_pool);
+              if (cd->their_abspath)
+                entry->conflict_new = svn_dirent_basename(cd->their_abspath,
+                                                          result_pool);
+              if (cd->my_abspath)
+                entry->conflict_wrk = svn_dirent_basename(cd->my_abspath,
+                                                          result_pool);
               break;
             case svn_wc_conflict_kind_property:
               entry->prejfile = svn_dirent_basename(cd->their_abspath,
@@ -919,7 +926,7 @@ read_one_entry(const svn_wc_entry_t **ne
 
   /* Let's check for a file external.  ugh.  */
   if (status == svn_wc__db_status_normal
-      && kind == svn_wc__db_kind_file)
+      && kind == svn_kind_file)
     SVN_ERR(check_file_external(entry, db, entry_abspath, dir_abspath,
                                 result_pool, scratch_pool));
 
@@ -1972,6 +1979,9 @@ write_entry(struct write_baton **entry_n
       base_node->changed_date = entry->cmt_date;
       base_node->changed_author = entry->cmt_author;
 
+      if (entry->file_external_path)
+        base_node->file_external = TRUE;
+
       SVN_ERR(insert_node(sdb, base_node, scratch_pool));
 
       /* We have to insert the lock after the base node, because the node
@@ -1989,12 +1999,6 @@ write_entry(struct write_baton **entry_n
           SVN_ERR(svn_wc__db_lock_add(db, tmp_entry_abspath, &lock,
                                       scratch_pool));
         }
-
-      /* Now, update the file external information. */
-      if (entry->file_external_path)
-        {
-          base_node->file_external = TRUE;
-        }
     }
 
   if (below_working_node)
@@ -2496,7 +2500,7 @@ svn_wc_walk_entries3(const char *path,
   const char *local_abspath;
   svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
   svn_error_t *err;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_depth_t depth;
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
@@ -2520,7 +2524,7 @@ svn_wc_walk_entries3(const char *path,
         walk_baton, pool);
     }
 
-  if (kind == svn_wc__db_kind_file || depth == svn_depth_exclude)
+  if (kind == svn_kind_file || depth == svn_depth_exclude)
     {
       const svn_wc_entry_t *entry;
 
@@ -2562,7 +2566,7 @@ svn_wc_walk_entries3(const char *path,
       return SVN_NO_ERROR;
     }
 
-  if (kind == svn_wc__db_kind_dir)
+  if (kind == svn_kind_dir)
     return walker_helper(path, adm_access, walk_callbacks, walk_baton,
                          walk_depth, show_hidden, cancel_func, cancel_baton,
                          pool);

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/externals.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/externals.c Tue Oct 11 19:52:34 2011
@@ -30,6 +30,7 @@
 #include <apr_hash.h>
 #include <apr_tables.h>
 #include <apr_general.h>
+#include <apr_uri.h>
 
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
@@ -441,7 +442,7 @@ open_file(const char *path,
           void **file_baton)
 {
   struct edit_baton *eb = parent_baton;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   if (strcmp(path, eb->name))
       return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                                _("This editor can only update '%s'"),
@@ -457,7 +458,7 @@ open_file(const char *path,
                                    eb->db, eb->local_abspath,
                                    eb->pool, file_pool));
 
-  if (kind != svn_wc__db_kind_file)
+  if (kind != svn_kind_file)
     return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                                _("Node '%s' is no existing file external"),
                                svn_dirent_local_style(eb->local_abspath,
@@ -669,7 +670,7 @@ close_file(void *file_baton,
                                       &new_pristine_props,
                                       &new_actual_props,
                                       eb->db, eb->local_abspath,
-                                      svn_wc__db_kind_file,
+                                      svn_kind_file,
                                       NULL, NULL,
                                       NULL /* server_baseprops*/,
                                       base_props,
@@ -955,7 +956,7 @@ svn_wc__crawl_file_external(svn_wc_conte
 {
   svn_wc__db_t *db = wc_ctx->db;
   svn_error_t *err;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_wc__db_lock_t *lock;
   svn_revnum_t revision;
   const char *repos_root_url;
@@ -970,7 +971,7 @@ svn_wc__crawl_file_external(svn_wc_conte
                                  scratch_pool, scratch_pool);
 
   if (err
-      || kind == svn_wc__db_kind_dir
+      || kind == svn_kind_dir
       || !update_root)
     {
       if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
@@ -1054,7 +1055,7 @@ svn_wc__read_external_info(svn_node_kind
 {
   const char *repos_root_url;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_error_t *err;
 
   err = svn_wc__db_external_read(&status, &kind, defining_abspath,
@@ -1096,11 +1097,11 @@ svn_wc__read_external_info(svn_node_kind
       else
         switch(kind)
           {
-            case svn_wc__db_kind_file:
-            case svn_wc__db_kind_symlink:
+            case svn_kind_file:
+            case svn_kind_symlink:
               *external_kind = svn_node_file;
               break;
-            case svn_wc__db_kind_dir:
+            case svn_kind_dir:
               *external_kind = svn_node_dir;
               break;
             default:
@@ -1163,7 +1164,7 @@ svn_wc__external_remove(svn_wc_context_t
                         apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
 
   SVN_ERR(svn_wc__db_external_read(&status, &kind, NULL, NULL, NULL, NULL,
                                    NULL, NULL,
@@ -1173,7 +1174,7 @@ svn_wc__external_remove(svn_wc_context_t
   SVN_ERR(svn_wc__db_external_remove(wc_ctx->db, local_abspath, wri_abspath,
                                      NULL, scratch_pool));
 
-  if (kind == svn_wc__db_kind_dir)
+  if (kind == svn_kind_dir)
     SVN_ERR(svn_wc_remove_from_revision_control2(wc_ctx, local_abspath,
                                                  TRUE, FALSE,
                                                  cancel_func, cancel_baton,
@@ -1248,3 +1249,195 @@ svn_wc__externals_gather_definitions(apr
       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.  */
+static svn_error_t *
+uri_scheme(const char **scheme, const char *uri, apr_pool_t *pool)
+{
+  apr_size_t i;
+
+  for (i = 0; uri[i] && uri[i] != ':'; ++i)
+    if (uri[i] == '/')
+      goto error;
+
+  if (i > 0 && uri[i] == ':' && uri[i+1] == '/' && uri[i+2] == '/')
+    {
+      *scheme = apr_pstrmemdup(pool, uri, i);
+      return SVN_NO_ERROR;
+    }
+
+error:
+  return svn_error_createf(SVN_ERR_BAD_URL, 0,
+                           _("URL '%s' does not begin with a scheme"),
+                           uri);
+}
+
+svn_error_t *
+svn_wc__resolve_relative_external_url(const char **resolved_url,
+                                      const svn_wc_external_item2_t *item,
+                                      const char *repos_root_url,
+                                      const char *parent_dir_url,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool)
+{
+  const char *url = item->url;
+  apr_uri_t parent_dir_uri;
+  apr_status_t status;
+
+  *resolved_url = item->url;
+
+  /* If the URL is already absolute, there is nothing to do. */
+  if (svn_path_is_url(url))
+    {
+      /* "http://server/path" */
+      *resolved_url = svn_uri_canonicalize(url, result_pool);
+      return SVN_NO_ERROR;
+    }
+
+  if (url[0] == '/')
+    {
+      /* "/path", "//path", and "///path" */
+      int num_leading_slashes = 1;
+      if (url[1] == '/')
+        {
+          num_leading_slashes++;
+          if (url[2] == '/')
+            num_leading_slashes++;
+        }
+
+      /* "//schema-relative" and in some cases "///schema-relative".
+         This last format is supported on file:// schema relative. */
+      url = apr_pstrcat(scratch_pool,
+                        apr_pstrndup(scratch_pool, url, num_leading_slashes),
+                        svn_relpath_canonicalize(url + num_leading_slashes,
+                                                 scratch_pool),
+                        (char*)NULL);
+    }
+  else
+    {
+      /* "^/path" and "../path" */
+      url = svn_relpath_canonicalize(url, scratch_pool);
+    }
+
+  /* Parse the parent directory URL into its parts. */
+  status = apr_uri_parse(scratch_pool, parent_dir_url, &parent_dir_uri);
+  if (status)
+    return svn_error_createf(SVN_ERR_BAD_URL, 0,
+                             _("Illegal parent directory URL '%s'"),
+                             parent_dir_url);
+
+  /* If the parent directory URL is at the server root, then the URL
+     may have no / after the hostname so apr_uri_parse() will leave
+     the URL's path as NULL. */
+  if (! parent_dir_uri.path)
+    parent_dir_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
+  parent_dir_uri.query = NULL;
+  parent_dir_uri.fragment = NULL;
+
+  /* Handle URLs relative to the current directory or to the
+     repository root.  The backpaths may only remove path elements,
+     not the hostname.  This allows an external to refer to another
+     repository in the same server relative to the location of this
+     repository, say using SVNParentPath. */
+  if ((0 == strncmp("../", url, 3)) ||
+      (0 == strncmp("^/", url, 2)))
+    {
+      apr_array_header_t *base_components;
+      apr_array_header_t *relative_components;
+      int i;
+
+      /* Decompose either the parent directory's URL path or the
+         repository root's URL path into components.  */
+      if (0 == strncmp("../", url, 3))
+        {
+          base_components = svn_path_decompose(parent_dir_uri.path,
+                                               scratch_pool);
+          relative_components = svn_path_decompose(url, scratch_pool);
+        }
+      else
+        {
+          apr_uri_t repos_root_uri;
+
+          status = apr_uri_parse(scratch_pool, repos_root_url,
+                                 &repos_root_uri);
+          if (status)
+            return svn_error_createf(SVN_ERR_BAD_URL, 0,
+                                     _("Illegal repository root URL '%s'"),
+                                     repos_root_url);
+
+          /* If the repository root URL is at the server root, then
+             the URL may have no / after the hostname so
+             apr_uri_parse() will leave the URL's path as NULL. */
+          if (! repos_root_uri.path)
+            repos_root_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
+
+          base_components = svn_path_decompose(repos_root_uri.path,
+                                               scratch_pool);
+          relative_components = svn_path_decompose(url + 2, scratch_pool);
+        }
+
+      for (i = 0; i < relative_components->nelts; ++i)
+        {
+          const char *component = APR_ARRAY_IDX(relative_components,
+                                                i,
+                                                const char *);
+          if (0 == strcmp("..", component))
+            {
+              /* Constructing the final absolute URL together with
+                 apr_uri_unparse() requires that the path be absolute,
+                 so only pop a component if the component being popped
+                 is not the component for the root directory. */
+              if (base_components->nelts > 1)
+                apr_array_pop(base_components);
+            }
+          else
+            APR_ARRAY_PUSH(base_components, const char *) = component;
+        }
+
+      parent_dir_uri.path = (char *)svn_path_compose(base_components,
+                                                     scratch_pool);
+      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
+                                                           &parent_dir_uri, 0),
+                                       result_pool);
+      return SVN_NO_ERROR;
+    }
+
+  /* The remaining URLs are relative to either the scheme or server root
+     and can only refer to locations inside that scope, so backpaths are
+     not allowed. */
+  if (svn_path_is_backpath_present(url + 2))
+    return svn_error_createf(SVN_ERR_BAD_URL, 0,
+                             _("The external relative URL '%s' cannot have "
+                               "backpaths, i.e. '..'"),
+                             item->url);
+
+  /* Relative to the scheme: Build a new URL from the parts we know. */
+  if (0 == strncmp("//", url, 2))
+    {
+      const char *scheme;
+
+      SVN_ERR(uri_scheme(&scheme, repos_root_url, scratch_pool));
+      *resolved_url = svn_uri_canonicalize(apr_pstrcat(scratch_pool, scheme,
+                                                       ":", url, (char *)NULL),
+                                           result_pool);
+      return SVN_NO_ERROR;
+    }
+
+  /* Relative to the server root: Just replace the path portion of the
+     parent's URL. */
+  if (url[0] == '/')
+    {
+      parent_dir_uri.path = (char *)url;
+      *resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
+                                                           &parent_dir_uri, 0),
+                                           result_pool);
+      return SVN_NO_ERROR;
+    }
+
+  return svn_error_createf(SVN_ERR_BAD_URL, 0,
+                           _("Unrecognized format for the relative external "
+                             "URL '%s'"),
+                           item->url);
+}

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/info.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/info.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/info.c Tue Oct 11 19:52:34 2011
@@ -63,6 +63,11 @@ svn_wc_info_dup(const svn_wc_info_t *inf
     new_info->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
   if (info->wcroot_abspath)
     new_info->wcroot_abspath = apr_pstrdup(pool, info->wcroot_abspath);
+  if (info->moved_from_abspath)
+    new_info->moved_from_abspath = apr_pstrdup(pool, info->moved_from_abspath);
+  if (info->moved_to_abspath)
+    new_info->moved_to_abspath = apr_pstrdup(pool, info->moved_to_abspath);
+
   return new_info;
 }
 
@@ -71,7 +76,7 @@ svn_wc_info_dup(const svn_wc_info_t *inf
    metadata of LOCAL_ABSPATH.  Pointer fields are copied by reference, not
    dup'd. */
 static svn_error_t *
-build_info_for_entry(svn_wc__info2_t **info,
+build_info_for_node(svn_wc__info2_t **info,
                      svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_node_kind_t kind,
@@ -81,7 +86,7 @@ build_info_for_entry(svn_wc__info2_t **i
   svn_wc__info2_t *tmpinfo;
   const char *repos_relpath;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t db_kind;
+  svn_kind_t db_kind;
   const char *original_repos_relpath;
   const char *original_repos_root_url;
   const char *original_uuid;
@@ -146,6 +151,12 @@ build_info_for_entry(svn_wc__info2_t **i
 
               wc_info->copyfrom_rev = original_revision;
             }
+
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL,
+                                           &wc_info->moved_from_abspath, NULL,
+                                           db, local_abspath,
+                                           result_pool, scratch_pool));
         }
       else if (op_root)
         {
@@ -153,7 +164,7 @@ build_info_for_entry(svn_wc__info2_t **i
           SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
                                            &tmpinfo->repos_root_URL,
                                            &tmpinfo->repos_UUID,
-                                           NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL,
                                            db, local_abspath,
                                            result_pool, scratch_pool));
 
@@ -186,6 +197,8 @@ build_info_for_entry(svn_wc__info2_t **i
     }
   else if (status == svn_wc__db_status_deleted)
     {
+      const char *work_del_abspath;
+
       SVN_ERR(svn_wc__db_read_pristine_info(NULL, NULL,
                                             &tmpinfo->last_changed_rev,
                                             &tmpinfo->last_changed_date,
@@ -196,51 +209,57 @@ build_info_for_entry(svn_wc__info2_t **i
                                             db, local_abspath,
                                             result_pool, scratch_pool));
 
-      SVN_ERR(svn_wc__internal_get_repos_info(&tmpinfo->repos_root_URL,
-                                              &tmpinfo->repos_UUID,
-                                              db, local_abspath,
-                                              result_pool, scratch_pool));
+      /* And now fetch the url and revision of what will be deleted */
+      SVN_ERR(svn_wc__db_scan_deletion(NULL, &wc_info->moved_to_abspath,
+                                       &work_del_abspath, NULL,
+                                       db, local_abspath,
+                                       scratch_pool, scratch_pool));
+      if (work_del_abspath != NULL)
+        {
+          /* This is a deletion within a copied subtree. Get the copied-from
+           * revision. */
+          const char *added_abspath = svn_dirent_dirname(work_del_abspath,
+                                                         scratch_pool);
 
-      SVN_ERR(svn_wc__db_read_url(&tmpinfo->URL, db, local_abspath,
-                                result_pool, scratch_pool));
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+                                           &tmpinfo->repos_root_URL,
+                                           &tmpinfo->repos_UUID,
+                                           NULL, NULL, NULL,
+                                           &tmpinfo->rev, NULL, NULL,
+                                           db, added_abspath,
+                                           result_pool, scratch_pool));
 
-      /* And now fetch the revision of what will be deleted */
-      {
-        const char *work_del_abspath;
-
-        SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                         &work_del_abspath,
-                                         db, local_abspath,
-                                         scratch_pool, scratch_pool));
-        if (work_del_abspath != NULL)
-          {
-            /* This is a deletion within a copied subtree. Get the copied-from
-             * revision. */
-            SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
-                                             NULL, NULL, NULL,
-                                             &tmpinfo->rev,
-                                             db,
-                                             svn_dirent_dirname(
-                                                  work_del_abspath,
-                                                  scratch_pool),
-                                             result_pool, scratch_pool));
-          }
-        else
+          tmpinfo->URL = svn_path_url_add_component2(
+                              tmpinfo->repos_root_URL,
+                              svn_relpath_join(repos_relpath,
+                                    svn_dirent_skip_ancestor(added_abspath,
+                                                             local_abspath),
+                                    scratch_pool),
+                              result_pool);
+        }
+      else
+        {
           SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, &tmpinfo->rev,
-                                           NULL, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, NULL, NULL, NULL, NULL, NULL,
+                                           &repos_relpath,
+                                           &tmpinfo->repos_root_URL,
+                                           &tmpinfo->repos_UUID, NULL, NULL,
+                                           NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL,
                                            db, local_abspath,
                                            result_pool, scratch_pool));
-      }
+
+          tmpinfo->URL = svn_path_url_add_component2(tmpinfo->repos_root_URL,
+                                                     repos_relpath,
+                                                     result_pool);
+        }
+
       wc_info->schedule = svn_wc_schedule_delete;
     }
   else if (status == svn_wc__db_status_not_present
            || status == svn_wc__db_status_server_excluded)
     {
-      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
-                               _("The node '%s' was not found."),
-                               svn_dirent_local_style(local_abspath,
-                                                      scratch_pool));
+      *info = NULL;
+      return SVN_NO_ERROR;
     }
   else
     {
@@ -277,8 +296,6 @@ build_info_for_entry(svn_wc__info2_t **i
       tmpinfo->lock->creation_date = lock->date;
     }
 
-  /* ### Temporary hacks to keep our test suite happy: */
-
   *info = tmpinfo;
   return SVN_NO_ERROR;
 }
@@ -293,18 +310,24 @@ build_info_for_unversioned(svn_wc__info2
                            apr_pool_t *pool)
 {
   svn_wc__info2_t *tmpinfo = apr_pcalloc(pool, sizeof(*tmpinfo));
-  tmpinfo->wc_info = apr_pcalloc(pool, sizeof (*tmpinfo->wc_info));
+  svn_wc_info_t *wc_info = apr_pcalloc(pool, sizeof (*wc_info));
 
   tmpinfo->URL                  = NULL;
-  tmpinfo->rev                  = SVN_INVALID_REVNUM;
-  tmpinfo->kind                 = svn_node_none;
   tmpinfo->repos_UUID           = NULL;
   tmpinfo->repos_root_URL       = NULL;
+  tmpinfo->rev                  = SVN_INVALID_REVNUM;
+  tmpinfo->kind                 = svn_node_none;
+  tmpinfo->size                 = SVN_INVALID_FILESIZE;
   tmpinfo->last_changed_rev     = SVN_INVALID_REVNUM;
   tmpinfo->last_changed_date    = 0;
   tmpinfo->last_changed_author  = NULL;
   tmpinfo->lock                 = NULL;
-  tmpinfo->size                 = SVN_INVALID_FILESIZE;
+
+  tmpinfo->wc_info = wc_info;
+
+  wc_info->copyfrom_rev = SVN_INVALID_REVNUM;
+  wc_info->depth = svn_depth_unknown;
+  wc_info->recorded_size = SVN_INVALID_FILESIZE;
 
   *info = tmpinfo;
   return SVN_NO_ERROR;
@@ -316,9 +339,12 @@ struct found_entry_baton
   svn_wc__info_receiver2_t receiver;
   void *receiver_baton;
   svn_wc__db_t *db;
+  svn_boolean_t actual_only;
+  svn_boolean_t first;
   /* The set of tree conflicts that have been found but not (yet) visited by
    * the tree walker.  Map of abspath -> svn_wc_conflict_description2_t. */
   apr_hash_t *tree_conflicts;
+  apr_pool_t *pool;
 };
 
 /* Call WALK_BATON->receiver with WALK_BATON->receiver_baton, passing to it
@@ -328,37 +354,52 @@ static svn_error_t *
 info_found_node_callback(const char *local_abspath,
                          svn_node_kind_t kind,
                          void *walk_baton,
-                         apr_pool_t *pool)
+                         apr_pool_t *scratch_pool)
 {
   struct found_entry_baton *fe_baton = walk_baton;
   svn_wc__info2_t *info;
 
-  SVN_ERR(build_info_for_entry(&info, fe_baton->db, local_abspath,
-                               kind, pool, pool));
+  SVN_ERR(build_info_for_node(&info, fe_baton->db, local_abspath,
+                               kind, scratch_pool, scratch_pool));
+
+  if (info == NULL)
+    {
+      if (!fe_baton->first)
+        return SVN_NO_ERROR; /* not present or server excluded descendant */
+
+      /* If the info root is not found, that is an error */
+      return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                               _("The node '%s' was not found."),
+                               svn_dirent_local_style(local_abspath,
+                                                      scratch_pool));
+    }
+
+  fe_baton->first = FALSE;
 
-  SVN_ERR_ASSERT(info != NULL && info->wc_info != NULL);
+  SVN_ERR_ASSERT(info->wc_info != NULL);
   SVN_ERR(fe_baton->receiver(fe_baton->receiver_baton, local_abspath,
-                             info, pool));
+                             info, scratch_pool));
 
   /* If this node is a versioned directory, make a note of any tree conflicts
    * on all immediate children.  Some of these may be visited later in this
    * walk, at which point they will be removed from the list, while any that
    * are not visited will remain in the list. */
-  if (kind == svn_node_dir)
+  if (fe_baton->actual_only && kind == svn_node_dir)
     {
       apr_hash_t *conflicts;
       apr_hash_index_t *hi;
 
       SVN_ERR(svn_wc__db_op_read_all_tree_conflicts(
                 &conflicts, fe_baton->db, local_abspath,
-                apr_hash_pool_get(fe_baton->tree_conflicts), pool));
-      for (hi = apr_hash_first(pool, conflicts); hi;
+                fe_baton->pool, scratch_pool));
+      for (hi = apr_hash_first(scratch_pool, conflicts); hi;
            hi = apr_hash_next(hi))
         {
           const char *this_basename = svn__apr_hash_index_key(hi);
 
           apr_hash_set(fe_baton->tree_conflicts,
-                       svn_dirent_join(local_abspath, this_basename, pool),
+                       svn_dirent_join(local_abspath, this_basename,
+                                       fe_baton->pool),
                        APR_HASH_KEY_STRING, svn__apr_hash_index_val(hi));
         }
     }
@@ -396,52 +437,68 @@ svn_error_t *
 svn_wc__get_info(svn_wc_context_t *wc_ctx,
                  const char *local_abspath,
                  svn_depth_t depth,
+                 svn_boolean_t fetch_excluded,
+                 svn_boolean_t fetch_actual_only,
+                 const apr_array_header_t *changelist_filter,
                  svn_wc__info_receiver2_t receiver,
                  void *receiver_baton,
-                 const apr_array_header_t *changelist_filter,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *scratch_pool)
 {
   struct found_entry_baton fe_baton;
-  const svn_wc_conflict_description2_t *root_tree_conflict;
   svn_error_t *err;
-  apr_pool_t *iterpool;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_hash_index_t *hi;
 
   fe_baton.receiver = receiver;
   fe_baton.receiver_baton = receiver_baton;
   fe_baton.db = wc_ctx->db;
+  fe_baton.actual_only = fetch_actual_only;
+  fe_baton.first = TRUE;
   fe_baton.tree_conflicts = apr_hash_make(scratch_pool);
-
-  SVN_ERR(svn_wc__db_op_read_tree_conflict(&root_tree_conflict,
-                                           wc_ctx->db, local_abspath,
-                                           scratch_pool, scratch_pool));
-  if (root_tree_conflict)
-    {
-      apr_hash_set(fe_baton.tree_conflicts, local_abspath, APR_HASH_KEY_STRING,
-                   root_tree_conflict);
-    }
+  fe_baton.pool = scratch_pool;
 
   err = svn_wc__internal_walk_children(wc_ctx->db, local_abspath,
-                                       FALSE /* show_hidden */,
+                                       fetch_excluded,
                                        changelist_filter,
                                        info_found_node_callback,
                                        &fe_baton, depth,
                                        cancel_func, cancel_baton,
-                                       scratch_pool);
+                                       iterpool);
 
   /* If the target root node is not present, svn_wc__internal_walk_children()
      returns a PATH_NOT_FOUND error and doesn't call the callback.  If there
      is a tree conflict on this node, that is not an error. */
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND && root_tree_conflict)
-    svn_error_clear(err);
-  else if (err)
-    return svn_error_trace(err);
+  if (fe_baton.first /* not visited by walk_children */
+      && fetch_actual_only
+      && err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+    {
+      const svn_wc_conflict_description2_t *root_tree_conflict;
+      svn_error_t *err2;
+
+      err2 = svn_wc__db_op_read_tree_conflict(&root_tree_conflict,
+                                              wc_ctx->db, local_abspath,
+                                              scratch_pool, iterpool);
+
+      if ((err2 && err2->apr_err == SVN_ERR_WC_PATH_NOT_FOUND))
+        {
+          svn_error_clear(err2);
+          return svn_error_trace(err);
+        }
+      else if (err2 || !root_tree_conflict)
+        return svn_error_compose_create(err, err2);
+
+      svn_error_clear(err);
+
+      apr_hash_set(fe_baton.tree_conflicts, local_abspath,
+                   APR_HASH_KEY_STRING, root_tree_conflict);
+    }
+  else
+    SVN_ERR(err);
 
   /* If there are any tree conflicts that we have found but have not reported,
    * send a minimal info struct for each one now. */
-  iterpool = svn_pool_create(scratch_pool);
   for (hi = apr_hash_first(scratch_pool, fe_baton.tree_conflicts); hi;
        hi = apr_hash_next(hi))
     {
@@ -452,7 +509,7 @@ svn_wc__get_info(svn_wc_context_t *wc_ct
       svn_pool_clear(iterpool);
 
       if (depth_includes(local_abspath, depth, tree_conflict->local_abspath,
-                         tree_conflict->kind, iterpool))
+                         tree_conflict->node_kind, iterpool))
         {
           apr_array_header_t *conflicts = apr_array_make(iterpool,
             1, sizeof(const svn_wc_conflict_description2_t *));

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/lock.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/lock.c Tue Oct 11 19:52:34 2011
@@ -125,7 +125,7 @@ svn_wc__internal_check_wc(int *wc_format
     if (*wc_format >= SVN_WC__WC_NG_VERSION)
       {
         svn_wc__db_status_t db_status;
-        svn_wc__db_kind_t db_kind;
+        svn_kind_t db_kind;
 
         if (check_path)
           {
@@ -159,7 +159,7 @@ svn_wc__internal_check_wc(int *wc_format
         else
           SVN_ERR(err);
 
-        if (db_kind != svn_wc__db_kind_dir)
+        if (db_kind != svn_kind_dir)
           {
             /* The WC thinks there must be a file, so this is not
                a wc-directory */
@@ -593,7 +593,7 @@ open_single(svn_wc_adm_access_t **adm_ac
    ### adminstrative area.  */
 static svn_error_t *
 adm_available(svn_boolean_t *available,
-              svn_wc__db_kind_t *kind,
+              svn_kind_t *kind,
               svn_wc__db_t *db,
               const char *local_abspath,
               apr_pool_t *scratch_pool)
@@ -601,7 +601,7 @@ adm_available(svn_boolean_t *available,
   svn_wc__db_status_t status;
 
   if (kind)
-    *kind = svn_wc__db_kind_unknown;
+    *kind = svn_kind_unknown;
 
   SVN_ERR(svn_wc__db_read_info(&status, kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -659,7 +659,7 @@ do_open(svn_wc_adm_access_t **adm_access
       for (i = 0; i < children->nelts; i++)
         {
           const char *node_abspath;
-          svn_wc__db_kind_t kind;
+          svn_kind_t kind;
           svn_boolean_t available;
           const char *name = APR_ARRAY_IDX(children, i, const char *);
 
@@ -677,7 +677,7 @@ do_open(svn_wc_adm_access_t **adm_access
                                 node_abspath,
                                 scratch_pool));
 
-          if (kind != svn_wc__db_kind_dir)
+          if (kind != svn_kind_dir)
             continue;
 
           if (available)
@@ -885,7 +885,7 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t 
                     apr_pool_t *pool)
 {
   const char *local_abspath;
-  svn_wc__db_kind_t kind = svn_wc__db_kind_unknown;
+  svn_kind_t kind = svn_kind_unknown;
   svn_node_kind_t wckind;
   svn_error_t *err;
 
@@ -924,12 +924,12 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t 
 
       if (err)
         {
-          kind = svn_wc__db_kind_unknown;
+          kind = svn_kind_unknown;
           svn_error_clear(err);
         }
     }
 
-  if (kind == svn_wc__db_kind_dir && wckind == svn_node_file)
+  if (kind == svn_kind_dir && wckind == svn_node_file)
     {
       err = svn_error_createf(
                SVN_ERR_WC_NOT_WORKING_COPY, NULL,
@@ -939,7 +939,7 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t 
       return svn_error_create(SVN_ERR_WC_NOT_LOCKED, err, err->message);
     }
 
-  if (kind != svn_wc__db_kind_dir && kind != svn_wc__db_kind_unknown)
+  if (kind != svn_kind_dir && kind != svn_kind_unknown)
     {
       err = svn_error_createf(
                SVN_ERR_WC_NOT_WORKING_COPY, NULL,
@@ -949,7 +949,7 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t 
       return svn_error_create(SVN_ERR_WC_NOT_LOCKED, err, err->message);
     }
 
-  if (kind == svn_wc__db_kind_unknown || wckind == svn_node_none)
+  if (kind == svn_kind_unknown || wckind == svn_node_none)
     {
       err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
                               _("Directory '%s' is missing"),
@@ -974,7 +974,7 @@ svn_wc_adm_probe_retrieve(svn_wc_adm_acc
 {
   const char *dir;
   const char *local_abspath;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_error_t *err;
 
   SVN_ERR_ASSERT(associated != NULL);
@@ -982,9 +982,9 @@ svn_wc_adm_probe_retrieve(svn_wc_adm_acc
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
   SVN_ERR(svn_wc__db_read_kind(&kind, associated->db, local_abspath, TRUE, pool));
 
-  if (kind == svn_wc__db_kind_dir)
+  if (kind == svn_kind_dir)
     dir = path;
-  else if (kind != svn_wc__db_kind_unknown)
+  else if (kind != svn_kind_unknown)
     dir = svn_dirent_dirname(path, pool);
   else
     /* Not a versioned item, probe it */
@@ -1104,7 +1104,7 @@ child_is_disjoint(svn_boolean_t *disjoin
         SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &parent_repos_relpath,
                                          &parent_repos_root,
                                          &parent_repos_uuid,
-                                         NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL,
                                          db, parent_abspath,
                                          scratch_pool, scratch_pool));
       else
@@ -1284,7 +1284,7 @@ open_anchor(svn_wc_adm_access_t **anchor
       if (! t_access)
         {
           svn_boolean_t available;
-          svn_wc__db_kind_t kind;
+          svn_kind_t kind;
 
           err = adm_available(&available, &kind, db, local_abspath, pool);
 
@@ -1511,14 +1511,14 @@ svn_wc__acquire_write_lock(const char **
                            apr_pool_t *scratch_pool)
 {
   svn_wc__db_t *db = wc_ctx->db;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   svn_error_t *err;
 
   SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
                                (lock_root_abspath != NULL),
                                scratch_pool));
 
-  if (!lock_root_abspath && kind != svn_wc__db_kind_dir)
+  if (!lock_root_abspath && kind != svn_kind_dir)
     return svn_error_createf(SVN_ERR_WC_NOT_DIRECTORY, NULL,
                              _("Can't obtain lock on non-directory '%s'."),
                              svn_dirent_local_style(local_abspath,
@@ -1527,7 +1527,7 @@ svn_wc__acquire_write_lock(const char **
   if (lock_anchor)
     {
       const char *parent_abspath;
-      svn_wc__db_kind_t parent_kind;
+      svn_kind_t parent_kind;
 
       SVN_ERR_ASSERT(lock_root_abspath != NULL);
 
@@ -1537,12 +1537,12 @@ svn_wc__acquire_write_lock(const char **
       if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
         {
           svn_error_clear(err);
-          parent_kind = svn_wc__db_kind_unknown;
+          parent_kind = svn_kind_unknown;
         }
       else
         SVN_ERR(err);
 
-      if (kind == svn_wc__db_kind_dir && parent_kind == svn_wc__db_kind_dir)
+      if (kind == svn_kind_dir && parent_kind == svn_kind_dir)
         {
           svn_boolean_t disjoint;
           SVN_ERR(child_is_disjoint(&disjoint, wc_ctx->db, local_abspath,
@@ -1550,25 +1550,25 @@ svn_wc__acquire_write_lock(const char **
           if (!disjoint)
             local_abspath = parent_abspath;
         }
-      else if (parent_kind == svn_wc__db_kind_dir)
+      else if (parent_kind == svn_kind_dir)
         local_abspath = parent_abspath;
-      else if (kind != svn_wc__db_kind_dir)
+      else if (kind != svn_kind_dir)
         return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL,
                                  _("'%s' is not a working copy"),
                                  svn_dirent_local_style(local_abspath,
                                                         scratch_pool));
     }
-  else if (kind != svn_wc__db_kind_dir)
+  else if (kind != svn_kind_dir)
     {
       local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
       /* Can't lock parents that don't exist */
-      if (kind == svn_wc__db_kind_unknown)
+      if (kind == svn_kind_unknown)
         {
           SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE,
                                        scratch_pool));
 
-          if (kind != svn_wc__db_kind_dir)
+          if (kind != svn_kind_dir)
             return svn_error_createf(
                              SVN_ERR_WC_NOT_DIRECTORY, NULL,
                              _("Can't obtain lock on non-directory '%s'."),

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/merge.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/merge.c Tue Oct 11 19:52:34 2011
@@ -161,11 +161,10 @@ detranslate_wc_file(const char **detrans
   const char *eol;
   apr_hash_t *keywords;
   svn_boolean_t special;
-  const svn_string_t *mime_value;
-  mime_value = apr_hash_get(mt->actual_props, SVN_PROP_MIME_TYPE,
-                            APR_HASH_KEY_STRING);
+  const char *mime_value = svn_prop_get_value(mt->actual_props,
+                                              SVN_PROP_MIME_TYPE);
 
-  is_binary = (mime_value && svn_mime_type_is_binary(mime_value->data));
+  is_binary = (mime_value && svn_mime_type_is_binary(mime_value));
 
   /* See if we need to do a straight copy:
      - old and new mime-types are binary, or
@@ -815,7 +814,7 @@ setup_text_conflict_desc(const char *lef
   svn_wc_conflict_description2_t *cdesc;
 
   cdesc = svn_wc_conflict_description_create_text2(target_abspath, pool);
-  cdesc->is_binary = FALSE;
+  cdesc->is_binary = is_binary;
   cdesc->mime_type = (mimeprop && mimeprop->value)
                      ? mimeprop->value->data : NULL,
   cdesc->base_abspath = left_abspath;
@@ -925,6 +924,68 @@ maybe_resolve_conflicts(svn_skel_t **wor
   return SVN_NO_ERROR;
 }
 
+
+/* Attempt a trivial merge of LEFT_ABSPATH and RIGHT_ABSPATH to TARGET_ABSPATH.
+ * The merge is trivial if the file at LEFT_ABSPATH equals TARGET_ABSPATH,
+ * because in this case the content of RIGHT_ABSPATH can be copied to the
+ * target. On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED,
+ * and install work queue items allocated in RESULT_POOL in *WORK_ITEMS.
+ * On failure, set *MERGE_OUTCOME to SVN_WC_MERGE_NO_MERGE. */
+static svn_error_t *
+merge_file_trivial(svn_skel_t **work_items,
+                   enum svn_wc_merge_outcome_t *merge_outcome,
+                   const char *left_abspath,
+                   const char *right_abspath,
+                   const char *target_abspath,
+                   svn_boolean_t dry_run,
+                   svn_wc__db_t *db,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  svn_skel_t *work_item;
+  svn_boolean_t same_contents = FALSE;
+  svn_error_t *err;
+
+  /* If the LEFT side of the merge is equal to WORKING, then we can
+   * copy RIGHT directly. */
+  err = svn_io_files_contents_same_p(&same_contents, left_abspath,
+                                     target_abspath, scratch_pool);
+  if (err)
+    {
+      if (APR_STATUS_IS_ENOENT(err->apr_err))
+        {
+          /* This can happen if TARGET_ABSPATH is a broken symlink.
+           * Let the smart merge code handle this. */
+          svn_error_clear(err);
+          *merge_outcome = svn_wc_merge_no_merge;
+          return SVN_NO_ERROR;
+        }
+      else
+        return svn_error_trace(err);
+    }
+
+  if (same_contents)
+    {
+      if (!dry_run)
+        {
+          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+                                                db, target_abspath,
+                                                right_abspath,
+                                                FALSE /* use_commit_times */,
+                                                FALSE /* record_fileinfo */,
+                                                result_pool, scratch_pool));
+          *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+        }
+
+      *merge_outcome = svn_wc_merge_merged;
+      return SVN_NO_ERROR;
+    }
+
+  *merge_outcome = svn_wc_merge_no_merge;
+  return SVN_NO_ERROR;
+}
+
+
 /* XXX Insane amount of parameters... */
 static svn_error_t*
 merge_text_file(svn_skel_t **work_items,
@@ -1038,7 +1099,7 @@ merge_text_file(svn_skel_t **work_items,
         }
 
       if (*merge_outcome == svn_wc_merge_merged)
-        return SVN_NO_ERROR;
+        goto done;
     }
   else if (contains_conflicts && dry_run)
       *merge_outcome = svn_wc_merge_conflict;
@@ -1075,6 +1136,7 @@ merge_text_file(svn_skel_t **work_items,
       *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
     }
 
+done:
   /* Remove the tempfile after use */
   SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
                                        mt->db, result_target,
@@ -1112,37 +1174,22 @@ merge_binary_file(svn_skel_t **work_item
   const char *merge_dirpath, *merge_filename;
   const char *conflict_wrk;
   svn_skel_t *work_item;
-  svn_boolean_t same_contents = FALSE;
 
   *work_items = NULL;
 
   svn_dirent_split(&merge_dirpath, &merge_filename, mt->local_abspath, pool);
 
-  /* Attempt to merge the binary file. At the moment, we can only
-     handle the special case: if the LEFT side of the merge is equal
-     to WORKING, then we can copy RIGHT directly. */
-  SVN_ERR(svn_io_files_contents_same_p(&same_contents,
-                                      left_abspath,
-                                      mt->local_abspath,
-                                      scratch_pool));
+  SVN_ERR(merge_file_trivial(work_items, merge_outcome,
+                             left_abspath, right_abspath,
+                             mt->local_abspath, dry_run, mt->db,
+                             result_pool, scratch_pool));
+  if (*merge_outcome == svn_wc_merge_merged)
+    return SVN_NO_ERROR;
 
-  if (same_contents)
-    {
-      if (!dry_run)
-        {
-          SVN_ERR(svn_wc__wq_build_file_install(&work_item,
-                                                mt->db, mt->local_abspath,
-                                                right_abspath,
-                                                FALSE /* use_commit_times */,
-                                                FALSE /* record_fileinfo */,
-                                                result_pool, scratch_pool));
-          *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
-        }
+  /* If we get here the binary files differ. Because we don't know how
+   * to merge binary files in a non-trivial way we always flag a conflict. */
 
-      *merge_outcome = svn_wc_merge_merged;
-      return SVN_NO_ERROR;
-    }
-  else if (dry_run)
+  if (dry_run)
     {
       *merge_outcome = svn_wc_merge_conflict;
       return SVN_NO_ERROR;
@@ -1321,7 +1368,6 @@ svn_wc__internal_merge(svn_skel_t **work
                        apr_pool_t *result_pool,
                        apr_pool_t *scratch_pool)
 {
-  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
   const char *detranslated_target_abspath;
   svn_boolean_t is_binary = FALSE;
   const svn_prop_t *mimeprop;
@@ -1349,23 +1395,24 @@ svn_wc__internal_merge(svn_skel_t **work
     is_binary = svn_mime_type_is_binary(mimeprop->value->data);
   else
     {
-      const svn_string_t *value = apr_hash_get(mt.actual_props,
-                                               SVN_PROP_MIME_TYPE,
-                                               APR_HASH_KEY_STRING);
+      const char *value = svn_prop_get_value(mt.actual_props,
+                                             SVN_PROP_MIME_TYPE);
 
-      is_binary = value && svn_mime_type_is_binary(value->data);
+      is_binary = value && svn_mime_type_is_binary(value);
     }
 
   SVN_ERR(detranslate_wc_file(&detranslated_target_abspath, &mt,
                               (! is_binary) && diff3_cmd != NULL,
                               target_abspath,
-                              cancel_func, cancel_baton, pool, pool));
+                              cancel_func, cancel_baton,
+                              scratch_pool, scratch_pool));
 
   /* We cannot depend on the left file to contain the same eols as the
      right file. If the merge target has mods, this will mark the entire
      file as conflicted, so we need to compensate. */
   SVN_ERR(maybe_update_target_eols(&left_abspath, &mt, left_abspath,
-                                   cancel_func, cancel_baton, pool, pool));
+                                   cancel_func, cancel_baton,
+                                   scratch_pool, scratch_pool));
 
   if (is_binary)
     {
@@ -1456,12 +1503,12 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
    * unless the merge target is a copyfrom text, which lives in a
    * temporary file and does not exist in ACTUAL yet. */
   {
-    svn_wc__db_kind_t kind;
+    svn_kind_t kind;
     svn_boolean_t hidden;
     SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, target_abspath, TRUE,
                                  scratch_pool));
 
-    if (kind == svn_wc__db_kind_unknown)
+    if (kind == svn_kind_unknown)
       {
         *merge_outcome = svn_wc_merge_no_merge;
         return SVN_NO_ERROR;

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/node.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/node.c Tue Oct 11 19:52:34 2011
@@ -182,7 +182,7 @@ svn_wc__internal_get_repos_info(const ch
       const char *base_del_abspath, *wrk_del_abspath;
 
       SVN_ERR(svn_wc__db_scan_deletion(&base_del_abspath, NULL,
-                                       &wrk_del_abspath,
+                                       &wrk_del_abspath, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
 
@@ -193,7 +193,7 @@ svn_wc__internal_get_repos_info(const ch
       else if (wrk_del_abspath)
         SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
                                          repos_root_url, repos_uuid,
-                                         NULL, NULL, NULL, NULL,
+                                         NULL, NULL, NULL, NULL, NULL, NULL,
                                          db, svn_dirent_dirname(
                                                    wrk_del_abspath,
                                                    scratch_pool),
@@ -205,7 +205,7 @@ svn_wc__internal_get_repos_info(const ch
          repository location by scanning up the tree.  */
       SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
                                        repos_root_url, repos_uuid,
-                                       NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
                                        db, local_abspath,
                                        result_pool, scratch_pool));
     }
@@ -235,28 +235,28 @@ svn_wc__node_get_repos_info(const char *
  * even if DB_STATUS indicates that the node is hidden.
  * Else, return svn_kind_none for such nodes.
  *
- * ### This is a bit ugly. We should consider promoting svn_wc__db_kind_t
+ * ### This is a bit ugly. We should consider promoting svn_kind_t
  * ### to the de-facto node kind type instead of converting between them
  * ### in non-backwards compat code.
- * ### See also comments at the definition of svn_wc__db_kind_t. */
+ * ### See also comments at the definition of svn_kind_t. */
 static svn_error_t *
 convert_db_kind_to_node_kind(svn_node_kind_t *node_kind,
-                             svn_wc__db_kind_t db_kind,
+                             svn_kind_t db_kind,
                              svn_wc__db_status_t db_status,
                              svn_boolean_t show_hidden)
 {
   switch (db_kind)
     {
-      case svn_wc__db_kind_file:
+      case svn_kind_file:
         *node_kind = svn_node_file;
         break;
-      case svn_wc__db_kind_dir:
+      case svn_kind_dir:
         *node_kind = svn_node_dir;
         break;
-      case svn_wc__db_kind_symlink:
+      case svn_kind_symlink:
         *node_kind = svn_node_file;
         break;
-      case svn_wc__db_kind_unknown:
+      case svn_kind_unknown:
         *node_kind = svn_node_unknown;
         break;
       default:
@@ -287,7 +287,7 @@ svn_wc_read_kind(svn_node_kind_t *kind,
                  apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t db_status;
-  svn_wc__db_kind_t db_kind;
+  svn_kind_t db_kind;
   svn_error_t *err;
 
   err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL, NULL,
@@ -381,7 +381,7 @@ svn_wc__node_get_repos_relpath(const cha
         {
           SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath,
                                            NULL, NULL, NULL, NULL,
-                                           NULL, NULL,
+                                           NULL, NULL, NULL, NULL,
                                            wc_ctx->db, local_abspath,
                                            result_pool, scratch_pool));
         }
@@ -527,8 +527,8 @@ svn_wc__internal_get_copyfrom_info(const
       SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL, NULL,
                                        NULL, &original_repos_relpath,
                                        &original_root_url, NULL,
-                                       &original_revision, db, local_abspath,
-                                       result_pool, scratch_pool));
+                                       &original_revision, NULL, NULL, db,
+                                       local_abspath, result_pool, scratch_pool));
       if (status == svn_wc__db_status_copied ||
           status == svn_wc__db_status_moved_here)
         {
@@ -603,7 +603,7 @@ walker_helper(svn_wc__db_t *db,
     {
       const char *child_name = svn__apr_hash_index_key(hi);
       struct svn_wc__db_walker_info_t *wi = svn__apr_hash_index_val(hi);
-      svn_wc__db_kind_t child_kind = wi->kind;
+      svn_kind_t child_kind = wi->kind;
       svn_wc__db_status_t child_status = wi->status;
       const char *child_abspath;
 
@@ -627,7 +627,7 @@ walker_helper(svn_wc__db_t *db,
           }
 
       /* Return the child, if appropriate. */
-      if ( (child_kind == svn_wc__db_kind_file
+      if ( (child_kind == svn_kind_file
              || depth >= svn_depth_immediates)
            && svn_wc__internal_changelist_match(db, child_abspath,
                                                 changelist_filter,
@@ -646,7 +646,7 @@ walker_helper(svn_wc__db_t *db,
         }
 
       /* Recurse into this directory, if appropriate. */
-      if (child_kind == svn_wc__db_kind_dir
+      if (child_kind == svn_kind_dir
             && depth >= svn_depth_immediates)
         {
           svn_depth_t depth_below_here = depth;
@@ -681,7 +681,7 @@ svn_wc__internal_walk_children(svn_wc__d
                                void *cancel_baton,
                                apr_pool_t *scratch_pool)
 {
-  svn_wc__db_kind_t db_kind;
+  svn_kind_t db_kind;
   svn_node_kind_t kind;
   svn_wc__db_status_t status;
   apr_hash_t *changelist_hash = NULL;
@@ -706,13 +706,13 @@ svn_wc__internal_walk_children(svn_wc__d
                                         changelist_hash, scratch_pool))
     SVN_ERR(walk_callback(local_abspath, kind, walk_baton, scratch_pool));
 
-  if (db_kind == svn_wc__db_kind_file
+  if (db_kind == svn_kind_file
       || status == svn_wc__db_status_not_present
       || status == svn_wc__db_status_excluded
       || status == svn_wc__db_status_server_excluded)
     return SVN_NO_ERROR;
 
-  if (db_kind == svn_wc__db_kind_dir)
+  if (db_kind == svn_kind_dir)
     {
       return svn_error_trace(
         walker_helper(db, local_abspath, show_hidden, changelist_hash,
@@ -748,6 +748,33 @@ svn_wc__node_is_status_deleted(svn_boole
 }
 
 svn_error_t *
+svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath,
+                                  svn_wc_context_t *wc_ctx,
+                                  const char *local_abspath,
+                                  apr_pool_t *result_pool,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_wc__db_status_t status;
+
+  *deleted_ancestor_abspath = NULL;
+
+  SVN_ERR(svn_wc__db_read_info(&status,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(deleted_ancestor_abspath, NULL, NULL,
+                                     NULL, wc_ctx->db, local_abspath,
+                                     result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc__node_is_status_server_excluded(svn_boolean_t *is_server_excluded,
                                        svn_wc_context_t *wc_ctx,
                                        const char *local_abspath,
@@ -977,7 +1004,7 @@ svn_wc__internal_get_commit_base_rev(svn
          revision (not this node's base revision). */
       SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
                                        NULL, NULL, commit_base_revision,
-                                       db, local_abspath,
+                                       NULL, NULL, db, local_abspath,
                                        scratch_pool, scratch_pool));
 
 
@@ -990,7 +1017,7 @@ svn_wc__internal_get_commit_base_rev(svn
       const char *work_del_abspath;
 
       SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                       &work_del_abspath,
+                                       &work_del_abspath, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
       if (work_del_abspath != NULL)
@@ -999,7 +1026,7 @@ svn_wc__internal_get_commit_base_rev(svn
            * revision. */
           SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
                                            NULL, NULL,
-                                           commit_base_revision,
+                                           commit_base_revision, NULL, NULL,
                                            db,
                                            svn_dirent_dirname(work_del_abspath,
                                                               scratch_pool),
@@ -1133,7 +1160,7 @@ svn_wc__internal_node_get_schedule(svn_w
 
               /* Find out details of our deletion.  */
               SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
-                                               &work_del_abspath,
+                                               &work_del_abspath, NULL,
                                                db, local_abspath,
                                                scratch_pool, scratch_pool));
 
@@ -1300,17 +1327,18 @@ svn_wc__node_get_lock_tokens_recursive(a
 }
 
 svn_error_t *
-svn_wc__get_absent_subtrees(apr_hash_t **absent_subtrees,
-                            svn_wc_context_t *wc_ctx,
-                            const char *local_abspath,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
+svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
+                                     svn_wc_context_t *wc_ctx,
+                                     const char *local_abspath,
+                                     apr_pool_t *result_pool,
+                                     apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_wc__db_get_absent_subtrees(absent_subtrees,
-                                                        wc_ctx->db,
-                                                        local_abspath,
-                                                        result_pool,
-                                                        scratch_pool));
+  return svn_error_trace(
+           svn_wc__db_get_server_excluded_subtrees(server_excluded_subtrees,
+                                                   wc_ctx->db,
+                                                   local_abspath,
+                                                   result_pool,
+                                                   scratch_pool));
 }
 
 svn_error_t *
@@ -1393,8 +1421,8 @@ svn_wc__internal_get_origin(svn_boolean_
         SVN_ERR(svn_wc__db_scan_addition(&status, &op_root_abspath, NULL,
                                          NULL, NULL, &original_repos_relpath,
                                          repos_root_url,
-                                         repos_uuid,
-                                         revision, db, local_abspath,
+                                         repos_uuid, revision, NULL, NULL,
+                                         db, local_abspath,
                                          result_pool, scratch_pool));
 
         if (status == svn_wc__db_status_added)
@@ -1406,7 +1434,7 @@ svn_wc__internal_get_origin(svn_boolean_
                                                          local_abspath),
                                 result_pool);
       }
-    else /* Deleted, excluded, not-present, absent, ... */
+    else /* Deleted, excluded, not-present, server-excluded, ... */
       {
         if (is_copy)
           *is_copy = FALSE;
@@ -1465,7 +1493,7 @@ svn_wc__node_get_commit_status(svn_node_
                                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t db_kind;
+  svn_kind_t db_kind;
   svn_wc__db_lock_t *lock;
   svn_boolean_t had_props;
   svn_boolean_t props_mod_tmp;
@@ -1489,9 +1517,9 @@ svn_wc__node_get_commit_status(svn_node_
 
   if (kind)
     {
-      if (db_kind == svn_wc__db_kind_file)
+      if (db_kind == svn_kind_file)
         *kind = svn_node_file;
-      else if (db_kind == svn_wc__db_kind_dir)
+      else if (db_kind == svn_kind_dir)
         *kind = svn_node_dir;
       else
         *kind = svn_node_unknown;
@@ -1524,7 +1552,7 @@ svn_wc__node_get_commit_status(svn_node_
       apr_hash_t *props;
       *symlink = FALSE;
 
-      if (db_kind == svn_wc__db_kind_file
+      if (db_kind == svn_kind_file
           && (had_props || *props_mod))
         {
           SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
@@ -1619,16 +1647,14 @@ svn_wc__check_for_obstructions(svn_wc_no
                                svn_node_kind_t *kind,
                                svn_boolean_t *added,
                                svn_boolean_t *deleted,
-                               svn_boolean_t *conflicted,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,
                                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t db_kind;
+  svn_kind_t db_kind;
   svn_node_kind_t disk_kind;
-  svn_boolean_t conflicted_p;
   svn_error_t *err;
 
   *obstruction_state = svn_wc_notify_state_inapplicable;
@@ -1638,14 +1664,12 @@ svn_wc__check_for_obstructions(svn_wc_no
     *added = FALSE;
   if (deleted)
     *deleted = FALSE;
-  if (conflicted)
-    *conflicted = FALSE;
 
   SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
   err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, &conflicted_p, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              wc_ctx->db, local_abspath,
                              scratch_pool, scratch_pool);
@@ -1679,7 +1703,7 @@ svn_wc__check_for_obstructions(svn_wc_no
       else
         SVN_ERR(err);
 
-      if (db_kind != svn_wc__db_kind_dir
+      if (db_kind != svn_kind_dir
           || (status != svn_wc__db_status_normal
               && status != svn_wc__db_status_added))
         {
@@ -1694,7 +1718,7 @@ svn_wc__check_for_obstructions(svn_wc_no
 
   /* Check for obstructing working copies */
   if (!no_wcroot_check
-      && db_kind == svn_wc__db_kind_dir
+      && db_kind == svn_kind_dir
       && status == svn_wc__db_status_normal)
     {
       svn_boolean_t is_root;
@@ -1751,17 +1775,76 @@ svn_wc__check_for_obstructions(svn_wc_no
         SVN_ERR_MALFUNCTION();
     }
 
-  if (conflicted_p && (conflicted != NULL))
-    {
-      svn_boolean_t text_c, prop_c, tree_c;
+  return SVN_NO_ERROR;
+}
 
-      SVN_ERR(svn_wc__internal_conflicted_p(&text_c, &prop_c, &tree_c,
-                                            wc_ctx->db, local_abspath,
-                                            scratch_pool));
 
-      *conflicted = (text_c || prop_c || tree_c);
-    }
+svn_error_t *
+svn_wc__node_was_moved_away(const char **moved_to_abspath,
+                            const char **op_root_abspath,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  svn_boolean_t is_deleted;
+
+  if (moved_to_abspath)
+    *moved_to_abspath = NULL;
+  if (op_root_abspath)
+    *op_root_abspath = NULL;
+
+  SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted, wc_ctx, local_abspath,
+                                         scratch_pool));
+  if (is_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, moved_to_abspath, NULL,
+                                     op_root_abspath, wc_ctx->db,
+                                     local_abspath,
+                                     result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
+
+svn_error_t *
+svn_wc__node_was_moved_here(const char **moved_from_abspath,
+                            const char **delete_op_root_abspath,
+                            svn_wc_context_t *wc_ctx,
+                            const char *local_abspath,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  svn_boolean_t is_added;
+
+  if (moved_from_abspath)
+    *moved_from_abspath = NULL;
+  if (delete_op_root_abspath)
+    *delete_op_root_abspath = NULL;
+
+  SVN_ERR(svn_wc__node_is_added(&is_added, wc_ctx, local_abspath,
+                                scratch_pool));
+  if (is_added && (moved_from_abspath || delete_op_root_abspath))
+    {
+      svn_wc__db_status_t status;
+      const char *db_moved_from_abspath;
+      const char *db_delete_op_root_abspath;
+
+      SVN_ERR(svn_wc__db_scan_addition(&status, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, &db_moved_from_abspath,
+                                       &db_delete_op_root_abspath,
+                                       wc_ctx->db, local_abspath,
+                                       scratch_pool, scratch_pool));
+      if (status == svn_wc__db_status_moved_here)
+        {
+          if (moved_from_abspath)
+            *moved_from_abspath = apr_pstrdup(result_pool,
+                                              db_moved_from_abspath);
+          if (delete_op_root_abspath)
+            *delete_op_root_abspath = apr_pstrdup(result_pool,
+                                                  db_delete_op_root_abspath);
+        }
+    }
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/props.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/props.c Tue Oct 11 19:52:34 2011
@@ -167,7 +167,8 @@ combine_mergeinfo_props(const svn_string
 
   SVN_ERR(svn_mergeinfo_parse(&mergeinfo1, prop_val1->data, scratch_pool));
   SVN_ERR(svn_mergeinfo_parse(&mergeinfo2, prop_val2->data, scratch_pool));
-  SVN_ERR(svn_mergeinfo_merge(mergeinfo1, mergeinfo2, scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(mergeinfo1, mergeinfo2, scratch_pool,
+                               scratch_pool));
   SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string, mergeinfo1, result_pool));
   *output = mergeinfo_string;
   return SVN_NO_ERROR;
@@ -181,27 +182,33 @@ combine_forked_mergeinfo_props(const svn
                                const svn_string_t *from_prop_val,
                                const svn_string_t *working_prop_val,
                                const svn_string_t *to_prop_val,
-                               apr_pool_t *pool)
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
 {
   svn_mergeinfo_t from_mergeinfo, l_deleted, l_added, r_deleted, r_added;
   svn_string_t *mergeinfo_string;
 
   /* ### OPTIMIZE: Use from_mergeinfo when diff'ing. */
   SVN_ERR(diff_mergeinfo_props(&l_deleted, &l_added, from_prop_val,
-                               working_prop_val, pool));
+                               working_prop_val, scratch_pool));
   SVN_ERR(diff_mergeinfo_props(&r_deleted, &r_added, from_prop_val,
-                               to_prop_val, pool));
-  SVN_ERR(svn_mergeinfo_merge(l_deleted, r_deleted, pool));
-  SVN_ERR(svn_mergeinfo_merge(l_added, r_added, pool));
+                               to_prop_val, scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(l_deleted, r_deleted,
+                               scratch_pool, scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(l_added, r_added,
+                               scratch_pool, scratch_pool));
 
   /* Apply the combined deltas to the base. */
-  SVN_ERR(svn_mergeinfo_parse(&from_mergeinfo, from_prop_val->data, pool));
-  SVN_ERR(svn_mergeinfo_merge(from_mergeinfo, l_added, pool));
+  SVN_ERR(svn_mergeinfo_parse(&from_mergeinfo, from_prop_val->data,
+                              scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(from_mergeinfo, l_added,
+                               scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_mergeinfo_remove2(&from_mergeinfo, l_deleted,
-                                from_mergeinfo, TRUE, pool, pool));
+  SVN_ERR(svn_mergeinfo_remove2(&from_mergeinfo, l_deleted, from_mergeinfo,
+                                TRUE, scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string, from_mergeinfo, pool));
+  SVN_ERR(svn_mergeinfo_to_string(&mergeinfo_string, from_mergeinfo,
+                                  result_pool));
   *output = mergeinfo_string;
   return SVN_NO_ERROR;
 }
@@ -225,7 +232,7 @@ svn_wc__perform_props_merge(svn_wc_notif
 {
   int i;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   apr_hash_t *pristine_props = NULL;
   apr_hash_t *actual_props = NULL;
   apr_hash_t *new_pristine_props;
@@ -315,7 +322,7 @@ svn_wc__perform_props_merge(svn_wc_notif
   {
     const char *dir_abspath;
 
-    if (kind == svn_wc__db_kind_dir)
+    if (kind == svn_kind_dir)
       dir_abspath = local_abspath;
     else
       dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
@@ -803,7 +810,6 @@ maybe_generate_propconflict(svn_boolean_
                             apr_pool_t *scratch_pool)
 {
   svn_wc_conflict_result_t *result = NULL;
-  svn_string_t *mime_propval = NULL;
   apr_pool_t *filepool = svn_pool_create(scratch_pool);
   svn_wc_conflict_description2_t *cdesc;
   const char *dirpath = svn_dirent_dirname(local_abspath, filepool);
@@ -930,12 +936,10 @@ maybe_generate_propconflict(svn_boolean_
     }
 
   /* Build the rest of the description object: */
-  if (!is_dir && working_props)
-    mime_propval = apr_hash_get(working_props, SVN_PROP_MIME_TYPE,
-                                APR_HASH_KEY_STRING);
-  cdesc->mime_type = mime_propval ? mime_propval->data : NULL;
-  cdesc->is_binary = mime_propval ?
-      svn_mime_type_is_binary(mime_propval->data) : FALSE;
+  cdesc->mime_type = (is_dir ? NULL : svn_prop_get_value(working_props,
+                                                         SVN_PROP_MIME_TYPE));
+  cdesc->is_binary = (cdesc->mime_type
+                      && svn_mime_type_is_binary(cdesc->mime_type));
 
   if (!incoming_old_val && incoming_new_val)
     cdesc->action = svn_wc_conflict_action_add;
@@ -1299,7 +1303,8 @@ apply_single_mergeinfo_prop_change(svn_w
                   SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
                                                          working_val,
                                                          new_val,
-                                                         result_pool));
+                                                         result_pool,
+                                                         scratch_pool));
                   apr_hash_set(working_props, propname,
                                APR_HASH_KEY_STRING, new_val);
                   set_prop_merge_state(state, svn_wc_notify_state_merged);
@@ -1351,7 +1356,8 @@ apply_single_mergeinfo_prop_change(svn_w
                  them to base to get the new value. */
               SVN_ERR(combine_forked_mergeinfo_props(&new_val, old_val,
                                                      working_val,
-                                                     new_val, result_pool));
+                                                     new_val, result_pool,
+                                                     scratch_pool));
               apr_hash_set(working_props, propname,
                            APR_HASH_KEY_STRING, new_val);
               set_prop_merge_state(state, svn_wc_notify_state_merged);
@@ -1396,7 +1402,9 @@ apply_single_generic_prop_change(svn_wc_
   if (working_val && new_val
       && svn_string_compare(working_val, new_val))
     {
-       set_prop_merge_state(state, svn_wc_notify_state_merged);
+      /* All values identical is a trivial, non-notifiable merge */
+      if (! old_val || ! svn_string_compare(old_val, new_val))
+        set_prop_merge_state(state, svn_wc_notify_state_merged);
     }
   /* If working_val is the same as old_val... */
   else if (working_val && old_val
@@ -1533,7 +1541,7 @@ svn_wc__merge_props(svn_skel_t **work_it
                     apr_hash_t **new_actual_props,
                     svn_wc__db_t *db,
                     const char *local_abspath,
-                    svn_wc__db_kind_t kind,
+                    svn_kind_t kind,
                     const svn_wc_conflict_version_t *left_version,
                     const svn_wc_conflict_version_t *right_version,
                     apr_hash_t *server_baseprops,
@@ -1562,7 +1570,7 @@ svn_wc__merge_props(svn_skel_t **work_it
   *new_pristine_props = NULL;
   *new_actual_props = NULL;
 
-  is_dir = (kind == svn_wc__db_kind_dir);
+  is_dir = (kind == svn_kind_dir);
 
   if (!server_baseprops)
     server_baseprops = pristine_props;
@@ -1930,7 +1938,7 @@ svn_wc__get_pristine_props(apr_hash_t **
          while a simple add does not.  */
       SVN_ERR(svn_wc__db_scan_addition(&status, NULL,
                                        NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
     }
@@ -2422,7 +2430,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
                  apr_pool_t *scratch_pool)
 {
   enum svn_prop_kind prop_kind = svn_property_kind(NULL, name);
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const char *dir_abspath;
 
   /* we don't do entry properties here */
@@ -2446,7 +2454,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
   SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
                                scratch_pool));
 
-  if (kind == svn_wc__db_kind_dir)
+  if (kind == svn_kind_dir)
     dir_abspath = local_abspath;
   else
     dir_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
@@ -2466,7 +2474,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
         return SVN_NO_ERROR;
 
       SVN_ERR(do_propset(wc_ctx->db, local_abspath,
-                         kind == svn_wc__db_kind_dir
+                         kind == svn_kind_dir
                             ? svn_node_dir
                             : svn_node_file,
                          name, value, skip_checks,

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/props.h?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/props.h Tue Oct 11 19:52:34 2011
@@ -45,7 +45,7 @@ extern "C" {
    For 1.7, we're removing this support. Some old code is being left around
    in case we decide to change this.
 
-   For more information, see ^/notes/api-errata/wc006.txt
+   For more information, see ^/notes/api-errata/1.7/wc006.txt
 */
 #undef SVN__SUPPORT_BASE_MERGE
 
@@ -106,7 +106,7 @@ svn_wc__merge_props(svn_skel_t **work_it
                     apr_hash_t **new_actual_props,
                     svn_wc__db_t *db,
                     const char *local_abspath,
-                    svn_wc__db_kind_t kind,
+                    svn_kind_t kind,
                     const svn_wc_conflict_version_t *left_version,
                     const svn_wc_conflict_version_t *right_version,
                     apr_hash_t *server_baseprops,

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/questions.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/questions.c Tue Oct 11 19:52:34 2011
@@ -244,7 +244,7 @@ svn_wc__internal_file_modified_p(svn_boo
   svn_stream_t *pristine_stream;
   svn_filesize_t pristine_size;
   svn_wc__db_status_t status;
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const svn_checksum_t *checksum;
   svn_filesize_t recorded_size;
   apr_time_t recorded_mod_time;
@@ -265,7 +265,7 @@ svn_wc__internal_file_modified_p(svn_boo
   /* If we don't have a pristine or the node has a status that allows a
      pristine, just say that the node is modified */
   if (!checksum
-      || (kind != svn_wc__db_kind_file)
+      || (kind != svn_kind_file)
       || ((status != svn_wc__db_status_normal)
           && (status != svn_wc__db_status_added)))
     {
@@ -335,12 +335,22 @@ svn_wc__internal_file_modified_p(svn_boo
                                    scratch_pool, scratch_pool));
 
   /* Check all bytes, and verify checksum if requested. */
-  SVN_ERR(compare_and_verify(modified_p, db,
+  {
+    svn_error_t *err;
+    err = compare_and_verify(modified_p, db,
                              local_abspath, dirent->filesize,
                              pristine_stream, pristine_size,
                              has_props, props_mod,
                              exact_comparison,
-                             scratch_pool));
+                             scratch_pool);
+
+    /* At this point we already opened the pristine file, so we know that
+       the access denied applies to the working copy path */
+    if (err && APR_STATUS_IS_EACCES(err->apr_err))
+      return svn_error_create(SVN_ERR_WC_PATH_ACCESS_DENIED, err, NULL);
+    else
+      SVN_ERR(err);
+  }
 
   if (!*modified_p)
     {
@@ -384,7 +394,7 @@ svn_wc__internal_conflicted_p(svn_boolea
                               apr_pool_t *scratch_pool)
 {
   svn_node_kind_t kind;
-  svn_wc__db_kind_t node_kind;
+  svn_kind_t node_kind;
   const apr_array_header_t *conflicts;
   int i;
   svn_boolean_t conflicted;

Modified: subversion/branches/svn_mutex/subversion/libsvn_wc/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn_mutex/subversion/libsvn_wc/relocate.c?rev=1182053&r1=1182052&r2=1182053&view=diff
==============================================================================
--- subversion/branches/svn_mutex/subversion/libsvn_wc/relocate.c (original)
+++ subversion/branches/svn_mutex/subversion/libsvn_wc/relocate.c Tue Oct 11 19:52:34 2011
@@ -85,7 +85,7 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
                  void *validator_baton,
                  apr_pool_t *scratch_pool)
 {
-  svn_wc__db_kind_t kind;
+  svn_kind_t kind;
   const char *repos_relpath;
   const char *old_repos_root, *old_url;
   const char *new_repos_root, *new_url;
@@ -131,7 +131,7 @@ svn_wc_relocate4(svn_wc_context_t *wc_ct
                                wc_ctx->db, local_abspath, scratch_pool,
                                scratch_pool));
 
-  if (kind != svn_wc__db_kind_dir)
+  if (kind != svn_kind_dir)
     return svn_error_create(SVN_ERR_CLIENT_INVALID_RELOCATION, NULL,
                             _("Cannot relocate a single file"));