subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pbu...@apache.org
Subject svn commit: r1354186 [20/33] - in /subversion/branches/inheritable-props: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/directory-i...
Date Tue, 26 Jun 2012 19:28:22 GMT
Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/adm_ops.c Tue Jun 26 19:26:49 2012
@@ -59,7 +59,7 @@
 #include "svn_private_config.h"
 #include "private/svn_io_private.h"
 #include "private/svn_wc_private.h"
-
+#include "private/svn_subr_private.h"
 
 
 struct svn_wc_committed_queue_t
@@ -264,7 +264,10 @@ svn_wc__process_committed_internal(svn_w
 
   /* Only check kind after processing the node itself. The node might
      have been deleted */
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
+  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
+                               TRUE /* allow_missing */,
+                               TRUE /* show_hidden */,
+                               scratch_pool));
 
   if (recurse && kind == svn_kind_dir)
     {
@@ -1805,25 +1808,30 @@ revert_restore(svn_wc__db_t *db,
                 }
               else
                 {
-                  svn_boolean_t read_only;
-                  svn_string_t *needs_lock_prop;
+                  if (status == svn_wc__db_status_normal)
+                    {
+                      svn_boolean_t read_only;
+                      svn_string_t *needs_lock_prop;
 
-                  SVN_ERR(svn_io__is_finfo_read_only(&read_only, &finfo,
-                                                     scratch_pool));
+                      SVN_ERR(svn_io__is_finfo_read_only(&read_only, &finfo,
+                                                         scratch_pool));
 
-                  needs_lock_prop = apr_hash_get(props, SVN_PROP_NEEDS_LOCK,
-                                                 APR_HASH_KEY_STRING);
-                  if (needs_lock_prop && !read_only)
-                    {
-                      SVN_ERR(svn_io_set_file_read_only(local_abspath,
-                                                        FALSE, scratch_pool));
-                      notify_required = TRUE;
-                    }
-                  else if (!needs_lock_prop && read_only)
-                    {
-                      SVN_ERR(svn_io_set_file_read_write(local_abspath,
-                                                         FALSE, scratch_pool));
-                      notify_required = TRUE;
+                      needs_lock_prop = apr_hash_get(props, SVN_PROP_NEEDS_LOCK,
+                                                     APR_HASH_KEY_STRING);
+                      if (needs_lock_prop && !read_only)
+                        {
+                          SVN_ERR(svn_io_set_file_read_only(local_abspath,
+                                                            FALSE,
+                                                            scratch_pool));
+                          notify_required = TRUE;
+                        }
+                      else if (!needs_lock_prop && read_only)
+                        {
+                          SVN_ERR(svn_io_set_file_read_write(local_abspath,
+                                                             FALSE,
+                                                             scratch_pool));
+                          notify_required = TRUE;
+                        }
                     }
 
 #if !defined(WIN32) && !defined(__OS2__)
@@ -2119,7 +2127,9 @@ revert_partial(svn_wc__db_t *db,
         {
           svn_kind_t kind;
 
-          SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE,
+          SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
+                                       FALSE /* allow_missing */,
+                                       FALSE /* show_hidden */,
                                        iterpool));
           if (kind != svn_kind_file)
             continue;
@@ -2251,6 +2261,71 @@ svn_wc_get_pristine_contents2(svn_stream
 }
 
 
+typedef struct get_pristine_lazyopen_baton_t
+{
+  svn_wc_context_t *wc_ctx;
+  const char *wri_abspath;
+  const svn_checksum_t *checksum;
+
+} get_pristine_lazyopen_baton_t;
+
+
+/* Implements svn_stream_lazyopen_func_t */
+static svn_error_t *
+get_pristine_lazyopen_func(svn_stream_t **stream,
+                           void *baton,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  get_pristine_lazyopen_baton_t *b = baton;
+  const svn_checksum_t *sha1_checksum;
+
+  /* svn_wc__db_pristine_read() wants a SHA1, so if we have an MD5,
+     we'll use it to lookup the SHA1. */
+  if (b->checksum->kind == svn_checksum_sha1)
+    sha1_checksum = b->checksum;
+  else
+    SVN_ERR(svn_wc__db_pristine_get_sha1(&sha1_checksum, b->wc_ctx->db,
+                                         b->wri_abspath, b->checksum,
+                                         scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, b->wc_ctx->db,
+                                   b->wri_abspath, sha1_checksum,
+                                   result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents,
+                                          svn_wc_context_t *wc_ctx,
+                                          const char *wri_abspath,
+                                          const svn_checksum_t *checksum,
+                                          apr_pool_t *result_pool,
+                                          apr_pool_t *scratch_pool)
+{
+  svn_boolean_t present;
+  
+  *contents = NULL;
+
+  SVN_ERR(svn_wc__db_pristine_check(&present, wc_ctx->db, wri_abspath,
+                                    checksum, scratch_pool));
+
+  if (present)
+    {
+      get_pristine_lazyopen_baton_t *gpl_baton;
+
+      gpl_baton = apr_pcalloc(result_pool, sizeof(*gpl_baton));
+      gpl_baton->wc_ctx = wc_ctx;
+      gpl_baton->wri_abspath = wri_abspath;
+      gpl_baton->checksum = checksum;
+      
+      *contents = svn_stream_lazyopen_create(get_pristine_lazyopen_func,
+                                             gpl_baton, result_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc__internal_remove_from_revision_control(svn_wc__db_t *db,
                                               const char *local_abspath,
@@ -2631,8 +2706,12 @@ svn_wc_get_changelists(svn_wc_context_t 
                        void *cancel_baton,
                        apr_pool_t *scratch_pool)
 {
-  struct get_cl_fn_baton gnb = { wc_ctx->db, NULL,
-                                 callback_func, callback_baton };
+  struct get_cl_fn_baton gnb;
+
+  gnb.db = wc_ctx->db;
+  gnb.clhash = NULL;
+  gnb.callback_func = callback_func;
+  gnb.callback_baton = callback_baton;
 
   if (changelist_filter)
     SVN_ERR(svn_hash_from_cstring_keys(&gnb.clhash, changelist_filter,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c Tue Jun 26 19:26:49 2012
@@ -44,6 +44,7 @@
 #include "wc.h"
 #include "wc_db.h"
 #include "conflicts.h"
+#include "workqueue.h"
 
 #include "private/svn_wc_private.h"
 #include "private/svn_skel.h"
@@ -115,40 +116,10 @@ svn_wc__conflict_skel_add_prop_conflict(
 
 /*** Resolving a conflict automatically ***/
 
-
-/* Helper for resolve_conflict_on_entry.  Delete the file FILE_ABSPATH
-   in if it exists.  Set WAS_PRESENT to TRUE if the file existed, and
-   leave it UNTOUCHED otherwise. */
-static svn_error_t *
-attempt_deletion(const char *file_abspath,
-                 svn_boolean_t *was_present,
-                 apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  if (file_abspath == NULL)
-    return SVN_NO_ERROR;
-
-  err = svn_io_remove_file2(file_abspath, FALSE, scratch_pool);
-
-  if (err == NULL || !APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      *was_present = TRUE;
-      return svn_error_trace(err);
-    }
-
-  svn_error_clear(err);
-  return SVN_NO_ERROR;
-}
-
-
 /* Conflict resolution involves removing the conflict files, if they exist,
    and clearing the conflict filenames from the entry.  The latter needs to
    be done whether or not the conflict files exist.
 
-   Tree conflicts are not resolved here, because the data stored in one
-   entry does not refer to that entry but to children of it.
-
    PATH is the path to the item to be resolved, BASE_NAME is the basename
    of PATH, and CONFLICT_DIR is the access baton for PATH.  ORIG_ENTRY is
    the entry prior to resolution. RESOLVE_TEXT and RESOLVE_PROPS are TRUE
@@ -158,36 +129,30 @@ attempt_deletion(const char *file_abspat
    else do not change *DID_RESOLVE.
 
    See svn_wc_resolved_conflict5() for how CONFLICT_CHOICE behaves.
-
-   ### FIXME: This function should be loggy, otherwise an interruption can
-   ### leave, for example, one of the conflict artifact files deleted but
-   ### the entry still referring to it and trying to use it for the next
-   ### attempt at resolving.
-
-   ### Does this still apply in the world of WC-NG?  -hkw
 */
 static svn_error_t *
-resolve_conflict_on_node(svn_wc__db_t *db,
+resolve_conflict_on_node(svn_boolean_t *did_resolve,
+                         svn_wc__db_t *db,
                          const char *local_abspath,
                          svn_boolean_t resolve_text,
                          svn_boolean_t resolve_props,
+                         svn_boolean_t resolve_tree,
                          svn_wc_conflict_choice_t conflict_choice,
-                         svn_boolean_t *did_resolve,
+                         svn_cancel_func_t cancel_func_t,
+                         void *cancel_baton,
                          apr_pool_t *pool)
 {
-  svn_boolean_t found_file;
   const char *conflict_old = NULL;
   const char *conflict_new = NULL;
   const char *conflict_working = NULL;
   const char *prop_reject_file = NULL;
-  svn_kind_t kind;
   int i;
   const apr_array_header_t *conflicts;
-  const char *conflict_dir_abspath;
+  svn_skel_t *work_items = NULL;
+  svn_skel_t *work_item;
 
   *did_resolve = FALSE;
 
-  SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, pool));
   SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
                                     pool, pool));
 
@@ -208,11 +173,6 @@ resolve_conflict_on_node(svn_wc__db_t *d
         prop_reject_file = desc->their_abspath;
     }
 
-  if (kind == svn_kind_dir)
-    conflict_dir_abspath = local_abspath;
-  else
-    conflict_dir_abspath = svn_dirent_dirname(local_abspath, pool);
-
   if (resolve_text)
     {
       const char *auto_resolve_src;
@@ -247,7 +207,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
                   : svn_diff_conflict_display_modified;
 
                 SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir, db,
-                                                       conflict_dir_abspath,
+                                                       local_abspath,
                                                        pool, pool));
                 SVN_ERR(svn_stream_open_unique(&tmp_stream,
                                                &auto_resolve_src,
@@ -281,39 +241,99 @@ resolve_conflict_on_node(svn_wc__db_t *d
         }
 
       if (auto_resolve_src)
-        SVN_ERR(svn_io_copy_file(
-          svn_dirent_join(conflict_dir_abspath, auto_resolve_src, pool),
-          local_abspath, TRUE, pool));
+        {
+          SVN_ERR(svn_wc__wq_build_file_copy_translated(
+                    &work_item, db, local_abspath,
+                    auto_resolve_src, local_abspath, pool, pool));
+          work_items = svn_wc__wq_merge(work_items, work_item, pool);
+        }
     }
 
-  /* Records whether we found any of the conflict files.  */
-  found_file = FALSE;
-
   if (resolve_text)
     {
-      SVN_ERR(attempt_deletion(conflict_old, &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_new, &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_working, &found_file, pool));
-      resolve_text = conflict_old || conflict_new || conflict_working;
+      svn_node_kind_t node_kind;
+
+      /* Legacy behavior: Only report text conflicts as resolved when at least
+         one conflict marker file exists.
+
+         If not the UI shows the conflict as already resolved
+         (and in this case we just remove the in-db conflict) */
+
+      if (conflict_old)
+        {
+          SVN_ERR(svn_io_check_path(conflict_old, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_old,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
+
+      if (conflict_new)
+        {
+          SVN_ERR(svn_io_check_path(conflict_new, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_new,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
+
+      if (conflict_working)
+        {
+          SVN_ERR(svn_io_check_path(conflict_working, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_working,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
     }
   if (resolve_props)
     {
-      if (prop_reject_file != NULL)
-        SVN_ERR(attempt_deletion(prop_reject_file, &found_file, pool));
-      else
-        resolve_props = FALSE;
+      svn_node_kind_t node_kind;
+
+      /* Legacy behavior: Only report property conflicts as resolved when the
+         property reject file exists
+
+         If not the UI shows the conflict as already resolved
+         (and in this case we just remove the in-db conflict) */
+
+      if (prop_reject_file)
+        {
+          SVN_ERR(svn_io_check_path(prop_reject_file, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   prop_reject_file,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
     }
+  if (resolve_tree)
+    *did_resolve = TRUE;
 
-  if (resolve_text || resolve_props)
+  if (resolve_text || resolve_props || resolve_tree)
     {
       SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                           resolve_text, resolve_props,
-                                          FALSE, pool));
+                                          resolve_tree, work_items, pool));
 
-      /* No feedback if no files were deleted and all we did was change the
-         entry, such a file did not appear as a conflict */
-      if (found_file)
-        *did_resolve = TRUE;
+      /* Run the work queue to remove conflict marker files. */
+      SVN_ERR(svn_wc__wq_run(db, local_abspath,
+                             cancel_func_t, cancel_baton,
+                             pool));
     }
 
   return SVN_NO_ERROR;
@@ -328,32 +348,53 @@ svn_wc__resolve_text_conflict(svn_wc__db
   svn_boolean_t ignored_result;
 
   return svn_error_trace(resolve_conflict_on_node(
+                           &ignored_result,
                            db, local_abspath,
                            TRUE /* resolve_text */,
                            FALSE /* resolve_props */,
+                           FALSE /* resolve_tree */,
                            svn_wc_conflict_choose_merged,
-                           &ignored_result,
+                           NULL, NULL, /* cancel_func */
                            scratch_pool));
 }
 
 
-/* */
+/* Baton for conflict_status_walker */
+struct conflict_status_walker_baton
+{
+  svn_wc__db_t *db;
+  svn_boolean_t resolve_text;
+  const char *resolve_prop;
+  svn_boolean_t resolve_tree;
+  svn_wc_conflict_choice_t conflict_choice;
+  svn_wc_conflict_resolver_func2_t conflict_func;
+  void *conflict_baton;
+  svn_cancel_func_t cancel_func;
+  void *cancel_baton;
+  svn_wc_notify_func2_t notify_func;
+  void *notify_baton;
+};
+
+/* Implements svn_wc_status4_t to walk all conflicts to resolve */
 static svn_error_t *
-resolve_one_conflict(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_boolean_t resolve_text,
-                     const char *resolve_prop,
-                     svn_boolean_t resolve_tree,
-                     svn_wc_conflict_choice_t conflict_choice,
-                     svn_wc_notify_func2_t notify_func,
-                     void *notify_baton,
-                     apr_pool_t *scratch_pool)
+conflict_status_walker(void *baton,
+                       const char *local_abspath,
+                       const svn_wc_status3_t *status,
+                       apr_pool_t *scratch_pool)
 {
+  struct conflict_status_walker_baton *cswb = baton;
+  svn_wc__db_t *db = cswb->db;
+
   const apr_array_header_t *conflicts;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool;
   int i;
   svn_boolean_t resolved = FALSE;
 
+  if (!status->conflicted)
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(scratch_pool);
+
   SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
                                     scratch_pool, iterpool));
 
@@ -361,22 +402,42 @@ resolve_one_conflict(svn_wc__db_t *db,
     {
       const svn_wc_conflict_description2_t *cd;
       svn_boolean_t did_resolve;
+      svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
 
       cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);
 
       svn_pool_clear(iterpool);
 
+      if (my_choice == svn_wc_conflict_choose_unspecified)
+        {
+          svn_wc_conflict_result_t *result;
+
+          if (!cswb->conflict_func)
+            return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+                                    _("No conflict-callback and no "
+                                      "pre-defined conflict-choice provided"));
+
+          SVN_ERR(cswb->conflict_func(&result, cd, cswb->conflict_baton,
+                                      iterpool, iterpool));
+
+          my_choice = result->choice;
+        }
+
+
+      if (my_choice == svn_wc_conflict_choose_postpone)
+        continue;
+
       switch (cd->kind)
         {
           case svn_wc_conflict_kind_tree:
-            if (!resolve_tree)
+            if (!cswb->resolve_tree)
               break;
 
             /* For now, we only clear tree conflict information and resolve
              * to the working state. There is no way to pick theirs-full
              * or mine-full, etc. Throw an error if the user expects us
              * to be smarter than we really are. */
-            if (conflict_choice != svn_wc_conflict_choose_merged)
+            if (my_choice != svn_wc_conflict_choose_merged)
               {
                 return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                          NULL,
@@ -387,22 +448,33 @@ resolve_one_conflict(svn_wc__db_t *db,
                                                                 iterpool));
               }
 
-            SVN_ERR(svn_wc__db_op_set_tree_conflict(db, local_abspath, NULL,
-                                                    iterpool));
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
+                                             local_abspath,
+                                             FALSE /* resolve_text */,
+                                             FALSE /* resolve_props */,
+                                             TRUE /* resolve_tree */,
+                                             my_choice,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
+                                             iterpool));
 
             resolved = TRUE;
             break;
 
           case svn_wc_conflict_kind_text:
-            if (!resolve_text)
+            if (!cswb->resolve_text)
               break;
 
-            SVN_ERR(resolve_conflict_on_node(db,
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
                                              local_abspath,
                                              TRUE /* resolve_text */,
                                              FALSE /* resolve_props */,
-                                             conflict_choice,
-                                             &did_resolve,
+                                             FALSE /* resolve_tree */,
+                                             my_choice,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
                                              iterpool));
 
             if (did_resolve)
@@ -410,25 +482,28 @@ resolve_one_conflict(svn_wc__db_t *db,
             break;
 
           case svn_wc_conflict_kind_property:
-            if (!resolve_prop)
+            if (!cswb->resolve_prop)
               break;
 
             /* ### this is bogus. resolve_conflict_on_node() does not handle
                ### individual property resolution.  */
-            if (*resolve_prop != '\0' &&
-                strcmp(resolve_prop, cd->property_name) != 0)
+            if (*cswb->resolve_prop != '\0' &&
+                strcmp(cswb->resolve_prop, cd->property_name) != 0)
               {
                 break; /* Skip this property conflict */
               }
 
 
             /* We don't have property name handling here yet :( */
-            SVN_ERR(resolve_conflict_on_node(db,
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
                                              local_abspath,
                                              FALSE /* resolve_text */,
                                              TRUE /* resolve_props */,
-                                             conflict_choice,
-                                             &did_resolve,
+                                             FALSE /* resolve_tree */,
+                                             my_choice,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
                                              iterpool));
 
             if (did_resolve)
@@ -442,161 +517,28 @@ resolve_one_conflict(svn_wc__db_t *db,
     }
 
   /* Notify */
-  if (notify_func && resolved)
-    notify_func(notify_baton,
-                svn_wc_create_notify(local_abspath, svn_wc_notify_resolved,
-                                     iterpool),
-                iterpool);
-
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-recursive_resolve_conflict(svn_wc__db_t *db,
-                           const char *local_abspath,
-                           svn_boolean_t this_is_conflicted,
-                           svn_depth_t depth,
-                           svn_boolean_t resolve_text,
-                           const char *resolve_prop,
-                           svn_boolean_t resolve_tree,
-                           svn_wc_conflict_choice_t conflict_choice,
-                           svn_cancel_func_t cancel_func,
-                           void *cancel_baton,
-                           svn_wc_notify_func2_t notify_func,
-                           void *notify_baton,
-                           apr_pool_t *scratch_pool)
-{
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  const apr_array_header_t *children;
-  apr_hash_t *visited = apr_hash_make(scratch_pool);
-  svn_depth_t child_depth;
-  int i;
-
-  if (cancel_func)
-    SVN_ERR(cancel_func(cancel_baton));
-
-  if (this_is_conflicted)
-    {
-      SVN_ERR(resolve_one_conflict(db,
-                                   local_abspath,
-                                   resolve_text,
-                                   resolve_prop,
-                                   resolve_tree,
-                                   conflict_choice,
-                                   notify_func, notify_baton,
-                                   iterpool));
-    }
-
-  if (depth < svn_depth_files)
-    return SVN_NO_ERROR;
-
-  child_depth = (depth < svn_depth_infinity) ? svn_depth_empty : depth;
-
-  SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
-                                   scratch_pool, iterpool));
-
-  for (i = 0; i < children->nelts; i++)
-    {
-      const char *name = APR_ARRAY_IDX(children, i, const char *);
-      const char *child_abspath;
-      svn_wc__db_status_t status;
-      svn_kind_t kind;
-      svn_boolean_t conflicted;
-
-      svn_pool_clear(iterpool);
-
-      if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
-
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
-      SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   &conflicted, NULL, NULL, NULL, NULL, NULL,
-                                   NULL,
-                                   db, child_abspath, iterpool, iterpool));
-
-      if (status == svn_wc__db_status_not_present
-          || status == svn_wc__db_status_excluded
-          || status == svn_wc__db_status_server_excluded)
-        continue;
-
-      apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
-      if (kind == svn_kind_dir && depth < svn_depth_immediates)
-        continue;
-
-      if (kind == svn_kind_dir)
-        SVN_ERR(recursive_resolve_conflict(db,
-                                           child_abspath,
-                                           conflicted,
-                                           child_depth,
-                                           resolve_text,
-                                           resolve_prop,
-                                           resolve_tree,
-                                           conflict_choice,
-                                           cancel_func, cancel_baton,
-                                           notify_func, notify_baton,
-                                           iterpool));
-      else if (conflicted)
-        SVN_ERR(resolve_one_conflict(db,
-                                     child_abspath,
-                                     resolve_text,
-                                     resolve_prop,
-                                     resolve_tree,
-                                     conflict_choice,
-                                     notify_func, notify_baton,
-                                     iterpool));
-    }
-
-    SVN_ERR(svn_wc__db_read_conflict_victims(&children, db, local_abspath,
-                                           scratch_pool, iterpool));
-
-  for (i = 0; i < children->nelts; i++)
-    {
-      const char *name = APR_ARRAY_IDX(children, i, const char *);
-      const char *child_abspath;
-
-      svn_pool_clear(iterpool);
-
-      if (apr_hash_get(visited, name, APR_HASH_KEY_STRING) != NULL)
-        continue; /* Already visited */
-
-      if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
-
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
-      /* We only have to resolve one level of tree conflicts. All other
-         conflicts are resolved in the other loop */
-      SVN_ERR(resolve_one_conflict(db,
-                                   child_abspath,
-                                   FALSE /*resolve_text*/,
-                                   FALSE /*resolve_prop*/,
-                                   resolve_tree,
-                                   conflict_choice,
-                                   notify_func, notify_baton,
-                                   iterpool));
-    }
-
+  if (cswb->notify_func && resolved)
+    cswb->notify_func(cswb->notify_baton,
+                      svn_wc_create_notify(local_abspath,
+                                           svn_wc_notify_resolved,
+                                           iterpool),
+                      iterpool);
 
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
-svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
+svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
                           const char *local_abspath,
                           svn_depth_t depth,
                           svn_boolean_t resolve_text,
                           const char *resolve_prop,
                           svn_boolean_t resolve_tree,
                           svn_wc_conflict_choice_t conflict_choice,
+                          svn_wc_conflict_resolver_func2_t conflict_func,
+                          void *conflict_baton,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           svn_wc_notify_func2_t notify_func,
@@ -605,6 +547,8 @@ svn_wc_resolved_conflict5(svn_wc_context
 {
   svn_kind_t kind;
   svn_boolean_t conflicted;
+  struct conflict_status_walker_baton cswb;
+
   /* ### the underlying code does NOT support resolving individual
      ### properties. bail out if the caller tries it.  */
   if (resolve_prop != NULL && *resolve_prop != '\0')
@@ -612,6 +556,8 @@ svn_wc_resolved_conflict5(svn_wc_context
                             U_("Resolving a single property is not (yet) "
                                "supported."));
 
+  /* ### Just a versioned check? */
+  /* Conflicted is set to allow invoking on actual only nodes */
   SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
@@ -626,16 +572,69 @@ svn_wc_resolved_conflict5(svn_wc_context
   else if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
-  return svn_error_trace(recursive_resolve_conflict(
-                           wc_ctx->db,
-                           local_abspath,
-                           conflicted,
-                           depth,
-                           resolve_text,
-                           resolve_prop,
-                           resolve_tree,
-                           conflict_choice,
-                           cancel_func, cancel_baton,
-                           notify_func, notify_baton,
-                           scratch_pool));
+  cswb.db = wc_ctx->db;
+  cswb.resolve_text = resolve_text;
+  cswb.resolve_prop = resolve_prop;
+  cswb.resolve_tree = resolve_tree;
+  cswb.conflict_choice = conflict_choice;
+
+  cswb.conflict_func = conflict_func;
+  cswb.conflict_baton = conflict_baton;
+
+  cswb.cancel_func = cancel_func;
+  cswb.cancel_baton = cancel_baton;
+
+  cswb.notify_func = notify_func;
+  cswb.notify_baton = notify_baton;
+
+  if (notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                    svn_wc_notify_conflict_resolver_starting,
+                                    scratch_pool),
+                scratch_pool);
+
+  SVN_ERR(svn_wc_walk_status(wc_ctx,
+                             local_abspath,
+                             depth,
+                             FALSE /* get_all */,
+                             FALSE /* no_ignore */,
+                             TRUE /* ignore_text_mods */,
+                             NULL /* ignore_patterns */,
+                             conflict_status_walker, &cswb,
+                             cancel_func, cancel_baton,
+                             scratch_pool));
+
+  if (notify_func)
+    notify_func(notify_baton,
+                svn_wc_create_notify(local_abspath,
+                                    svn_wc_notify_conflict_resolver_done,
+                                    scratch_pool),
+                scratch_pool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
+                          const char *local_abspath,
+                          svn_depth_t depth,
+                          svn_boolean_t resolve_text,
+                          const char *resolve_prop,
+                          svn_boolean_t resolve_tree,
+                          svn_wc_conflict_choice_t conflict_choice,
+                          svn_cancel_func_t cancel_func,
+                          void *cancel_baton,
+                          svn_wc_notify_func2_t notify_func,
+                          void *notify_baton,
+                          apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_wc__resolve_conflicts(wc_ctx, local_abspath,
+                                                   depth, resolve_text,
+                                                   resolve_prop, resolve_tree,
+                                                   conflict_choice,
+                                                   NULL, NULL,
+                                                   cancel_func, cancel_baton,
+                                                   notify_func, notify_baton,
+                                                   scratch_pool));
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/copy.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/copy.c Tue Jun 26 19:26:49 2012
@@ -35,10 +35,7 @@
 
 #include "wc.h"
 #include "workqueue.h"
-#include "adm_files.h"
 #include "props.h"
-#include "translate.h"
-#include "entries.h"
 
 #include "svn_private_config.h"
 #include "private/svn_wc_private.h"
@@ -53,23 +50,32 @@
    SRC_ABSPATH doesn't exist then set *DST_ABSPATH to NULL to indicate
    that no copy was made. */
 static svn_error_t *
-copy_to_tmpdir(const char **dst_abspath,
+copy_to_tmpdir(svn_skel_t **work_item,
                svn_node_kind_t *kind,
+               svn_wc__db_t *db,
                const char *src_abspath,
+               const char *dst_abspath,
                const char *tmpdir_abspath,
-               svn_boolean_t recursive,
+               svn_boolean_t file_copy,
+               svn_boolean_t unversioned,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
+               apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
 {
   svn_boolean_t is_special;
   svn_io_file_del_t delete_when;
+  const char *dst_tmp_abspath;
+  svn_node_kind_t dsk_kind;
+  if (!kind)
+    kind = &dsk_kind;
+
+  *work_item = NULL;
 
   SVN_ERR(svn_io_check_special_path(src_abspath, kind, &is_special,
                                     scratch_pool));
   if (*kind == svn_node_none)
     {
-      *dst_abspath = NULL;
       return SVN_NO_ERROR;
     }
   else if (*kind == svn_node_unknown)
@@ -89,87 +95,68 @@ copy_to_tmpdir(const char **dst_abspath,
      ### handle the directory case and b) we need to be able to remove
      ### the cleanup before queueing the move work item. */
 
-  /* Set DST_ABSPATH to a temporary unique path.  If *KIND is file, leave a
-     file there and then overwrite it; otherwise leave no node on disk at
+  if (file_copy && !unversioned)
+    {
+      svn_boolean_t modified;
+      /* It's faster to look for mods on the source now, as
+         the timestamp might match, than to examine the
+         destination later as the destination timestamp will
+         never match. */
+      SVN_ERR(svn_wc__internal_file_modified_p(&modified,
+                                               db, src_abspath,
+                                               FALSE, scratch_pool));
+      if (!modified)
+        {
+          /* Why create a temp copy if we can just reinstall from pristine? */
+          SVN_ERR(svn_wc__wq_build_file_install(work_item,
+                                                db, dst_abspath, NULL, FALSE,
+                                                TRUE,
+                                                result_pool, scratch_pool));
+          return SVN_NO_ERROR;
+        }
+    }
+
+  /* Set DST_TMP_ABSPATH to a temporary unique path.  If *KIND is file, leave
+     a file there and then overwrite it; otherwise leave no node on disk at
      that path.  In the latter case, something else might use that path
      before we get around to using it a moment later, but never mind. */
-  SVN_ERR(svn_io_open_unique_file3(NULL, dst_abspath, tmpdir_abspath,
+  SVN_ERR(svn_io_open_unique_file3(NULL, &dst_tmp_abspath, tmpdir_abspath,
                                    delete_when, scratch_pool, scratch_pool));
 
   if (*kind == svn_node_dir)
     {
-      if (recursive)
-        SVN_ERR(svn_io_copy_dir_recursively(src_abspath,
-                                            tmpdir_abspath,
-                                            svn_dirent_basename(*dst_abspath,
-                                                                scratch_pool),
-                                            TRUE, /* copy_perms */
-                                            cancel_func, cancel_baton,
-                                            scratch_pool));
+      if (file_copy)
+        SVN_ERR(svn_io_copy_dir_recursively(
+                           src_abspath,
+                           tmpdir_abspath,
+                           svn_dirent_basename(dst_tmp_abspath, scratch_pool),
+                           TRUE, /* copy_perms */
+                           cancel_func, cancel_baton,
+                           scratch_pool));
       else
-        SVN_ERR(svn_io_dir_make(*dst_abspath, APR_OS_DEFAULT, scratch_pool));
+        SVN_ERR(svn_io_dir_make(dst_tmp_abspath, APR_OS_DEFAULT, scratch_pool));
     }
   else if (!is_special)
-    SVN_ERR(svn_io_copy_file(src_abspath, *dst_abspath, TRUE, /* copy_perms */
+    SVN_ERR(svn_io_copy_file(src_abspath, dst_tmp_abspath,
+                             TRUE /* copy_perms */,
                              scratch_pool));
   else
-    SVN_ERR(svn_io_copy_link(src_abspath, *dst_abspath, scratch_pool));
-
-
-  return SVN_NO_ERROR;
-}
-
+    SVN_ERR(svn_io_copy_link(src_abspath, dst_tmp_abspath, scratch_pool));
 
-/* If SRC_ABSPATH and DST_ABSPATH use different pristine stores, copy the
-   pristine text of SRC_ABSPATH (if there is one) into the pristine text
-   store connected to DST_ABSPATH.  This will only happen when copying into
-   a separate WC such as an external directory.
- */
-static svn_error_t *
-copy_pristine_text_if_necessary(svn_wc__db_t *db,
-                                const char *src_abspath,
-                                const char *dst_abspath,
-                                const char *tmpdir_abspath,
-                                const svn_checksum_t *checksum,
-                                svn_cancel_func_t cancel_func,
-                                void *cancel_baton,
-                                apr_pool_t *scratch_pool)
-{
-  svn_boolean_t present;
-  svn_stream_t *src_pristine, *tmp_pristine;
-  const char *tmp_pristine_abspath;
-  const svn_checksum_t *sha1_checksum, *md5_checksum;
-
-  SVN_ERR_ASSERT(checksum->kind == svn_checksum_sha1);
-
-  /* If it's already in DST_ABSPATH's pristine store, we're done. */
-  SVN_ERR(svn_wc__db_pristine_check(&present, db, dst_abspath, checksum,
-                                    scratch_pool));
-  if (present)
-    return SVN_NO_ERROR;
+  if (file_copy)
+    {
+      /* Remove 'read-only' from the destination file; it's a local add now. */
+      SVN_ERR(svn_io_set_file_read_write(dst_tmp_abspath,
+                                         FALSE, scratch_pool));
+    }
 
-  sha1_checksum = checksum;
-  SVN_ERR(svn_wc__db_pristine_get_md5(&md5_checksum, db,
-                                      src_abspath, checksum,
-                                      scratch_pool, scratch_pool));
-
-  SVN_ERR(svn_wc__db_pristine_read(&src_pristine, NULL, db,
-                                   src_abspath, sha1_checksum,
-                                   scratch_pool, scratch_pool));
-  SVN_ERR(svn_stream_open_unique(&tmp_pristine, &tmp_pristine_abspath,
-                                 tmpdir_abspath, svn_io_file_del_none,
-                                 scratch_pool, scratch_pool));
-  SVN_ERR(svn_stream_copy3(src_pristine, tmp_pristine,
-                           cancel_func, cancel_baton,
-                           scratch_pool));
-  SVN_ERR(svn_wc__db_pristine_install(db, tmp_pristine_abspath,
-                                      sha1_checksum, md5_checksum,
-                                      scratch_pool));
+  SVN_ERR(svn_wc__wq_build_file_move(work_item, db, dst_abspath,
+                                     dst_tmp_abspath, dst_abspath,
+                                     result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
-
 /* Copy the versioned file SRC_ABSPATH in DB to the path DST_ABSPATH in DB.
    If METADATA_ONLY is true, copy only the versioned metadata,
    otherwise copy both the versioned metadata and the filesystem node (even
@@ -178,6 +165,9 @@ copy_pristine_text_if_necessary(svn_wc__
    If IS_MOVE is true, record move information in working copy meta
    data in addition to copying the file.
 
+   If COPY_PRISTINE_FILE is true, make sure the necessary pristine files are
+   available in the destination working copy.
+
    If the versioned file has a text conflict, and the .mine file exists in
    the filesystem, copy the .mine file to DST_ABSPATH.  Otherwise, copy the
    versioned file itself.
@@ -190,7 +180,7 @@ copy_versioned_file(svn_wc__db_t *db,
                     const char *dst_abspath,
                     const char *dst_op_root_abspath,
                     const char *tmpdir_abspath,
-                    const svn_checksum_t *checksum,
+                    svn_boolean_t copy_pristine_file,
                     svn_boolean_t metadata_only,
                     svn_boolean_t conflicted,
                     svn_boolean_t is_move,
@@ -201,26 +191,23 @@ copy_versioned_file(svn_wc__db_t *db,
                     apr_pool_t *scratch_pool)
 {
   svn_skel_t *work_items = NULL;
-  const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
 
   /* In case we are copying from one WC to another (e.g. an external dir),
      ensure the destination WC has a copy of the pristine text. */
 
-  /* Checksum is NULL for local additions */
-  if (checksum != NULL)
-    SVN_ERR(copy_pristine_text_if_necessary(db, src_abspath, dst_abspath,
-                                            tmpdir_abspath, checksum,
-                                            cancel_func, cancel_baton,
-                                            scratch_pool));
+  if (copy_pristine_file)
+    SVN_ERR(svn_wc__db_pristine_transfer(db, src_abspath, NULL,
+                                         dst_op_root_abspath,
+                                         cancel_func, cancel_baton,
+                                         scratch_pool));
 
   /* Prepare a temp copy of the filesystem node.  It is usually a file, but
      copy recursively if it's a dir. */
   if (!metadata_only)
     {
-      const char *tmp_dst_abspath;
-      svn_node_kind_t disk_kind;
       const char *my_src_abspath = NULL;
       int i;
+      svn_boolean_t handle_as_unversioned = FALSE;
 
       /* By default, take the copy source as given. */
       my_src_abspath = src_abspath;
@@ -257,57 +244,20 @@ copy_versioned_file(svn_wc__db_t *db,
                                         scratch_pool));
 
               if (working_kind == svn_node_file)
-                my_src_abspath = conflict_working;
-            }
-        }
-
-      SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, my_src_abspath,
-                             tmpdir_abspath,
-                             TRUE, /* recursive */
-                             cancel_func, cancel_baton, scratch_pool));
-
-      if (tmp_dst_abspath)
-        {
-          svn_skel_t *work_item;
-
-          /* Remove 'read-only' from the destination file; it's a local add. */
-            {
-              const svn_string_t *needs_lock;
-              SVN_ERR(svn_wc__internal_propget(&needs_lock, db, src_abspath,
-                                               SVN_PROP_NEEDS_LOCK,
-                                               scratch_pool, scratch_pool));
-              if (needs_lock)
-                SVN_ERR(svn_io_set_file_read_write(tmp_dst_abspath,
-                                                   FALSE, scratch_pool));
-            }
-
-          SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
-                                             tmp_dst_abspath, dst_abspath,
-                                             scratch_pool, scratch_pool));
-          work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
-
-          if (disk_kind == svn_node_file)
-            {
-              svn_boolean_t modified;
-
-              /* It's faster to look for mods on the source now, as
-                 the timestamp might match, than to examine the
-                 destination later as the destination timestamp will
-                 never match. */
-              SVN_ERR(svn_wc__internal_file_modified_p(&modified,
-                                                       db, src_abspath,
-                                                       FALSE, scratch_pool));
-              if (!modified)
                 {
-                  SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
-                                                           db, dst_abspath, 0,
-                                                           scratch_pool,
-                                                           scratch_pool));
-                  work_items = svn_wc__wq_merge(work_items, work_item,
-                                                scratch_pool);
+                   /* Don't perform unmodified/pristine optimization */
+                  handle_as_unversioned = TRUE;
+                  my_src_abspath = conflict_working;
                 }
             }
         }
+
+      SVN_ERR(copy_to_tmpdir(&work_items, NULL, db, my_src_abspath,
+                             dst_abspath, tmpdir_abspath,
+                             TRUE /* file_copy */,
+                             handle_as_unversioned /* unversioned */,
+                             cancel_func, cancel_baton,
+                             scratch_pool, scratch_pool));
     }
 
   /* Copy the (single) node's metadata, and move the new filesystem node
@@ -315,8 +265,6 @@ copy_versioned_file(svn_wc__db_t *db,
   SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
                              dst_op_root_abspath, is_move, work_items,
                              scratch_pool));
-  SVN_ERR(svn_wc__wq_run(db, dir_abspath,
-                         cancel_func, cancel_baton, scratch_pool));
 
   if (notify_func)
     {
@@ -324,6 +272,11 @@ copy_versioned_file(svn_wc__db_t *db,
         = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
                                scratch_pool);
       notify->kind = svn_node_file;
+
+      /* When we notify that we performed a copy, make sure we already did */
+      if (work_items != NULL)
+        SVN_ERR(svn_wc__wq_run(db, dst_abspath,
+                               cancel_func, cancel_baton, scratch_pool));
       (*notify_func)(notify_baton, notify, scratch_pool);
     }
   return SVN_NO_ERROR;
@@ -334,7 +287,10 @@ copy_versioned_file(svn_wc__db_t *db,
    otherwise copy both the versioned metadata and the filesystem nodes (even
    if they are the wrong kind, and including unversioned children).
    If IS_MOVE is true, record move information in working copy meta
-   data in addition to copying the directory. */
+   data in addition to copying the directory.
+
+   WITHIN_ONE_WC is TRUE if the copy/move is within a single working copy (root)
+ */
 static svn_error_t *
 copy_versioned_dir(svn_wc__db_t *db,
                    const char *src_abspath,
@@ -343,6 +299,7 @@ copy_versioned_dir(svn_wc__db_t *db,
                    const char *tmpdir_abspath,
                    svn_boolean_t metadata_only,
                    svn_boolean_t is_move,
+                   svn_boolean_t within_one_wc,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    svn_wc_notify_func2_t notify_func,
@@ -351,29 +308,23 @@ copy_versioned_dir(svn_wc__db_t *db,
 {
   svn_skel_t *work_items = NULL;
   const char *dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool);
-  const apr_array_header_t *versioned_children;
+  apr_hash_t *versioned_children;
+  apr_hash_t *conflicted_children;
   apr_hash_t *disk_children;
+  apr_hash_index_t *hi;
   svn_node_kind_t disk_kind;
   apr_pool_t *iterpool;
-  int i;
 
   /* Prepare a temp copy of the single filesystem node (usually a dir). */
   if (!metadata_only)
     {
-      const char *tmp_dst_abspath;
-
-      SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind, src_abspath,
-                             tmpdir_abspath, FALSE, /* recursive */
-                             cancel_func, cancel_baton, scratch_pool));
-      if (tmp_dst_abspath)
-        {
-          svn_skel_t *work_item;
-
-          SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
-                                             tmp_dst_abspath, dst_abspath,
-                                             scratch_pool, scratch_pool));
-          work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
-        }
+      SVN_ERR(copy_to_tmpdir(&work_items, &disk_kind,
+                             db, src_abspath, dst_abspath,
+                             tmpdir_abspath,
+                             FALSE /* file_copy */,
+                             FALSE /* unversioned */,
+                             cancel_func, cancel_baton,
+                             scratch_pool, scratch_pool));
     }
 
   /* Copy the (single) node's metadata, and move the new filesystem node
@@ -381,8 +332,6 @@ copy_versioned_dir(svn_wc__db_t *db,
   SVN_ERR(svn_wc__db_op_copy(db, src_abspath, dst_abspath,
                              dst_op_root_abspath, is_move, work_items,
                              scratch_pool));
-  SVN_ERR(svn_wc__wq_run(db, dir_abspath,
-                         cancel_func, cancel_baton, scratch_pool));
 
   if (notify_func)
     {
@@ -390,6 +339,12 @@ copy_versioned_dir(svn_wc__db_t *db,
         = svn_wc_create_notify(dst_abspath, svn_wc_notify_add,
                                scratch_pool);
       notify->kind = svn_node_dir;
+
+      /* When we notify that we performed a copy, make sure we already did */
+      if (work_items != NULL)
+        SVN_ERR(svn_wc__wq_run(db, dir_abspath,
+                               cancel_func, cancel_baton, scratch_pool));
+
       (*notify_func)(notify_baton, notify, scratch_pool);
     }
 
@@ -403,79 +358,61 @@ copy_versioned_dir(svn_wc__db_t *db,
     disk_children = NULL;
 
   /* Copy all the versioned children */
-  SVN_ERR(svn_wc__db_read_children(&versioned_children, db, src_abspath,
-                                   scratch_pool, scratch_pool));
   iterpool = svn_pool_create(scratch_pool);
-  for (i = 0; i < versioned_children->nelts; ++i)
+  SVN_ERR(svn_wc__db_read_children_info(&versioned_children,
+                                        &conflicted_children,
+                                        db, src_abspath,
+                                        scratch_pool, iterpool));
+  for (hi = apr_hash_first(scratch_pool, versioned_children);
+       hi;
+       hi = apr_hash_next(hi))
     {
       const char *child_name, *child_src_abspath, *child_dst_abspath;
-      svn_wc__db_status_t child_status;
-      svn_kind_t child_kind;
-      svn_boolean_t op_root;
-      svn_boolean_t conflicted;
-      const svn_checksum_t *checksum;
+      struct svn_wc__db_info_t *info;
 
       svn_pool_clear(iterpool);
+
       if (cancel_func)
         SVN_ERR(cancel_func(cancel_baton));
 
-      child_name = APR_ARRAY_IDX(versioned_children, i, const char *);
+      child_name = svn__apr_hash_index_key(hi);
+      info = svn__apr_hash_index_val(hi);
       child_src_abspath = svn_dirent_join(src_abspath, child_name, iterpool);
       child_dst_abspath = svn_dirent_join(dst_abspath, child_name, iterpool);
 
-      SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL,
-                                   &checksum, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, &conflicted,
-                                   &op_root, NULL, NULL, NULL, NULL, NULL,
-                                   db, child_src_abspath,
-                                   iterpool, iterpool));
-
-      if (op_root)
+      if (info->op_root)
         SVN_ERR(svn_wc__db_op_copy_shadowed_layer(db,
                                                   child_src_abspath,
                                                   child_dst_abspath,
                                                   is_move,
                                                   scratch_pool));
 
-      if (child_status == svn_wc__db_status_normal
-          || child_status == svn_wc__db_status_added)
+      if (info->status == svn_wc__db_status_normal
+          || info->status == svn_wc__db_status_added)
         {
           /* We have more work to do than just changing the DB */
-          if (child_kind == svn_kind_file)
+          if (info->kind == svn_kind_file)
             {
-              svn_boolean_t skip = FALSE;
-
               /* We should skip this node if this child is a file external
                  (issues #3589, #4000) */
-              if (child_status == svn_wc__db_status_normal)
-                {
-                  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL,
-                                                   NULL, NULL, NULL, NULL,
-                                                   NULL, NULL, NULL, NULL,
-                                                   NULL, NULL, &skip,
-                                                   db, child_src_abspath,
-                                                   scratch_pool,
-                                                   scratch_pool));
-                }
-
-              if (!skip)
+              if (!info->file_external)
                 SVN_ERR(copy_versioned_file(db,
                                             child_src_abspath,
                                             child_dst_abspath,
                                             dst_op_root_abspath,
-                                            tmpdir_abspath, checksum,
-                                            metadata_only, conflicted,
+                                            tmpdir_abspath,
+                                            !within_one_wc && info->has_checksum,
+                                            metadata_only, info->conflicted,
                                             is_move,
                                             cancel_func, cancel_baton,
                                             NULL, NULL,
                                             iterpool));
             }
-          else if (child_kind == svn_kind_dir)
+          else if (info->kind == svn_kind_dir)
             SVN_ERR(copy_versioned_dir(db,
                                        child_src_abspath, child_dst_abspath,
                                        dst_op_root_abspath, tmpdir_abspath,
-                                       metadata_only, is_move,
+                                       metadata_only, is_move, within_one_wc,
                                        cancel_func, cancel_baton, NULL, NULL,
                                        iterpool));
           else
@@ -484,9 +421,9 @@ copy_versioned_dir(svn_wc__db_t *db,
                                      svn_dirent_local_style(child_src_abspath,
                                                             scratch_pool));
         }
-      else if (child_status == svn_wc__db_status_deleted
-          || child_status == svn_wc__db_status_not_present
-          || child_status == svn_wc__db_status_excluded)
+      else if (info->status == svn_wc__db_status_deleted
+          || info->status == svn_wc__db_status_not_present
+          || info->status == svn_wc__db_status_excluded)
         {
           /* This will be copied as some kind of deletion. Don't touch
              any actual files */
@@ -497,7 +434,7 @@ copy_versioned_dir(svn_wc__db_t *db,
           /* Don't recurse on children while all we do is creating not-present
              children */
         }
-      else if (child_status == svn_wc__db_status_incomplete)
+      else if (info->status == svn_wc__db_status_incomplete)
         {
           /* Should go ahead and copy incomplete to incomplete? Try to
              copy as much as possible, or give up early? */
@@ -508,7 +445,7 @@ copy_versioned_dir(svn_wc__db_t *db,
         }
       else
         {
-          SVN_ERR_ASSERT(child_status == svn_wc__db_status_server_excluded);
+          SVN_ERR_ASSERT(info->status == svn_wc__db_status_server_excluded);
 
           return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                                    _("Cannot copy '%s' excluded by server"),
@@ -517,8 +454,8 @@ copy_versioned_dir(svn_wc__db_t *db,
         }
 
       if (disk_children
-          && (child_status == svn_wc__db_status_normal
-              || child_status == svn_wc__db_status_added))
+          && (info->status == svn_wc__db_status_normal
+              || info->status == svn_wc__db_status_added))
         {
           /* Remove versioned child as it has been handled */
           apr_hash_set(disk_children, child_name, APR_HASH_KEY_STRING, NULL);
@@ -527,21 +464,22 @@ copy_versioned_dir(svn_wc__db_t *db,
 
   /* Copy the remaining filesystem children, which are unversioned, skipping
      any conflict-marker files. */
-  if (disk_children)
+  if (disk_children && apr_hash_count(disk_children))
     {
-      apr_hash_index_t *hi;
       apr_hash_t *marker_files;
 
       SVN_ERR(svn_wc__db_get_conflict_marker_files(&marker_files, db,
                                                    src_abspath, scratch_pool,
                                                    scratch_pool));
 
+      work_items = NULL;
+
       for (hi = apr_hash_first(scratch_pool, disk_children); hi;
            hi = apr_hash_next(hi))
         {
           const char *name = svn__apr_hash_index_key(hi);
           const char *unver_src_abspath, *unver_dst_abspath;
-          const char *tmp_dst_abspath;
+          svn_skel_t *work_item;
 
           if (svn_wc_is_adm_dir(name, iterpool))
             continue;
@@ -550,31 +488,23 @@ copy_versioned_dir(svn_wc__db_t *db,
               apr_hash_get(marker_files, name, APR_HASH_KEY_STRING))
             continue;
 
-          svn_pool_clear(iterpool);
           if (cancel_func)
             SVN_ERR(cancel_func(cancel_baton));
 
+          svn_pool_clear(iterpool);
           unver_src_abspath = svn_dirent_join(src_abspath, name, iterpool);
           unver_dst_abspath = svn_dirent_join(dst_abspath, name, iterpool);
 
-          SVN_ERR(copy_to_tmpdir(&tmp_dst_abspath, &disk_kind,
-                                 unver_src_abspath, tmpdir_abspath,
-                                 TRUE, /* recursive */
-                                 cancel_func, cancel_baton, iterpool));
-          if (tmp_dst_abspath)
-            {
-              svn_skel_t *work_item;
-              SVN_ERR(svn_wc__wq_build_file_move(&work_item, db, dir_abspath,
-                                                 tmp_dst_abspath,
-                                                 unver_dst_abspath,
-                                                 iterpool, iterpool));
-              SVN_ERR(svn_wc__db_wq_add(db, dst_abspath, work_item,
-                                        iterpool));
-            }
+          SVN_ERR(copy_to_tmpdir(&work_item, NULL, db, unver_src_abspath,
+                                 unver_dst_abspath, tmpdir_abspath,
+                                 TRUE /* recursive */, TRUE /* unversioned */,
+                                 cancel_func, cancel_baton,
+                                 scratch_pool, iterpool));
 
+          if (work_item)
+            work_items = svn_wc__wq_merge(work_items, work_item, scratch_pool);
         }
-      SVN_ERR(svn_wc__wq_run(db, dst_abspath, cancel_func, cancel_baton,
-                             scratch_pool));
+      SVN_ERR(svn_wc__db_wq_add(db, dst_abspath, work_items, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -604,6 +534,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
   svn_boolean_t conflicted;
   const svn_checksum_t *checksum;
   const char *tmpdir_abspath;
+  const char *src_wcroot_abspath;
+  const char *dst_wcroot_abspath;
+  svn_boolean_t within_one_wc;
+  svn_error_t *err;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(src_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath));
@@ -616,7 +550,6 @@ copy_or_move(svn_wc_context_t *wc_ctx,
     svn_wc__db_status_t src_status, dstdir_status;
     const char *src_repos_root_url, *dst_repos_root_url;
     const char *src_repos_uuid, *dst_repos_uuid;
-    svn_error_t *err;
 
     err = svn_wc__db_read_info(&src_status, &src_db_kind, NULL, NULL,
                                &src_repos_root_url, &src_repos_uuid, NULL,
@@ -637,6 +570,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
     else
       SVN_ERR(err);
 
+    /* Do this now, as we know the right data is cached */
+    SVN_ERR(svn_wc__db_get_wcroot(&src_wcroot_abspath, db, src_abspath,
+                                  scratch_pool, scratch_pool));
+
     switch (src_status)
       {
         case svn_wc__db_status_deleted:
@@ -665,6 +602,10 @@ copy_or_move(svn_wc_context_t *wc_ctx,
                                  db, dstdir_abspath,
                                  scratch_pool, scratch_pool));
 
+    /* Do this now, as we know the right data is cached */
+    SVN_ERR(svn_wc__db_get_wcroot(&dst_wcroot_abspath, db, dstdir_abspath,
+                                  scratch_pool, scratch_pool));
+
     if (!src_repos_root_url)
       {
         if (src_status == svn_wc__db_status_added)
@@ -721,7 +662,6 @@ copy_or_move(svn_wc_context_t *wc_ctx,
      disk, before actually doing the file copy. */
   {
     svn_wc__db_status_t dst_status;
-    svn_error_t *err;
 
     err = svn_wc__db_read_info(&dst_status, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -777,29 +717,42 @@ copy_or_move(svn_wc_context_t *wc_ctx,
     }
 
   SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmpdir_abspath, db,
-                                         dst_abspath,
+                                         dstdir_abspath,
                                          scratch_pool, scratch_pool));
 
+  within_one_wc = (strcmp(src_wcroot_abspath, dst_wcroot_abspath) == 0);
+
   if (src_db_kind == svn_kind_file
       || src_db_kind == svn_kind_symlink)
     {
-      SVN_ERR(copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
-                                  tmpdir_abspath, checksum,
-                                  metadata_only, conflicted, is_move,
-                                  cancel_func, cancel_baton,
-                                  notify_func, notify_baton,
-                                  scratch_pool));
+      err = copy_versioned_file(db, src_abspath, dst_abspath, dst_abspath,
+                                tmpdir_abspath,
+                                !within_one_wc && (checksum != NULL),
+                                metadata_only, conflicted, is_move,
+                                cancel_func, cancel_baton,
+                                notify_func, notify_baton,
+                                scratch_pool);
     }
   else
     {
-      SVN_ERR(copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
-                                 tmpdir_abspath,
-                                 metadata_only, is_move,
-                                 cancel_func, cancel_baton,
-                                 notify_func, notify_baton,
-                                 scratch_pool));
+      err = copy_versioned_dir(db, src_abspath, dst_abspath, dst_abspath,
+                               tmpdir_abspath,
+                               metadata_only, is_move, within_one_wc,
+                               cancel_func, cancel_baton,
+                               notify_func, notify_baton,
+                               scratch_pool);
     }
 
+  if (err && svn_error_find_cause(err, SVN_ERR_CANCELLED))
+    return svn_error_trace(err);
+
+  /* Run the work queue with the remaining work */
+  SVN_ERR(svn_error_compose_create(
+                                err,
+                                svn_wc__wq_run(db, dst_abspath,
+                                                   cancel_func, cancel_baton,
+                                                   scratch_pool)));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/deprecated.c Tue Jun 26 19:26:49 2012
@@ -932,7 +932,9 @@ svn_wc_add3(const char *path,
     {
       svn_kind_t kind;
 
-      SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath, FALSE, pool));
+      SVN_ERR(svn_wc__db_read_kind(&kind, wc_db, local_abspath,
+                                   FALSE /* allow_missing */,
+                                   FALSE /* show_hidden */, pool));
       if (kind == svn_kind_dir)
         {
           svn_wc_adm_access_t *adm_access;
@@ -4185,6 +4187,49 @@ svn_wc_copy(const char *src_path,
 /*** From merge.c ***/
 
 svn_error_t *
+svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
+              svn_wc_context_t *wc_ctx,
+              const char *left_abspath,
+              const char *right_abspath,
+              const char *target_abspath,
+              const char *left_label,
+              const char *right_label,
+              const char *target_label,
+              const svn_wc_conflict_version_t *left_version,
+              const svn_wc_conflict_version_t *right_version,
+              svn_boolean_t dry_run,
+              const char *diff3_cmd,
+              const apr_array_header_t *merge_options,
+              const apr_array_header_t *prop_diff,
+              svn_wc_conflict_resolver_func2_t conflict_func,
+              void *conflict_baton,
+              svn_cancel_func_t cancel_func,
+              void *cancel_baton,
+              apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+            svn_wc_merge5(merge_outcome,
+                          NULL /* merge_props_outcome */,
+                          wc_ctx,
+                          left_abspath,
+                          right_abspath,
+                          target_abspath,
+                          left_label,
+                          right_label,
+                          target_label,
+                          left_version,
+                          right_version,
+                          dry_run,
+                          diff3_cmd,
+                          merge_options,
+                          NULL /* original_props */,
+                          prop_diff,
+                          conflict_func, conflict_baton,
+                          cancel_func, cancel_baton,
+                          scratch_pool));
+}
+
+svn_error_t *
 svn_wc_merge3(enum svn_wc_merge_outcome_t *merge_outcome,
               const char *left,
               const char *right,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/diff_local.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/diff_local.c Tue Jun 26 19:26:49 2012
@@ -564,7 +564,9 @@ svn_wc_diff6(svn_wc_context_t *wc_ctx,
   svn_boolean_t get_all;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, FALSE,
+  SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
+                               FALSE /* allow_missing */,
+                               FALSE /* show_hidden */,
                                scratch_pool));
 
   if (kind == svn_kind_dir)

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/entries.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/entries.c Tue Jun 26 19:26:49 2012
@@ -55,7 +55,7 @@
 typedef struct db_node_t {
   apr_int64_t wc_id;
   const char *local_relpath;
-  apr_int64_t op_depth;
+  int op_depth;
   apr_int64_t repos_id;
   const char *repos_relpath;
   const char *parent_relpath;
@@ -1426,7 +1426,7 @@ insert_node(svn_sqlite__db_t *sdb,
   SVN_ERR_ASSERT(node->op_depth > 0 || node->repos_relpath);
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "isisnnnnsnrisnnni",
+  SVN_ERR(svn_sqlite__bindf(stmt, "isdsnnnnsnrisnnni",
                             node->wc_id,
                             node->local_relpath,
                             node->op_depth,
@@ -1444,7 +1444,7 @@ insert_node(svn_sqlite__db_t *sdb,
                                      node->repos_id));
       SVN_ERR(svn_sqlite__bind_text(stmt, 6,
                                     node->repos_relpath));
-      SVN_ERR(svn_sqlite__bind_int64(stmt, 7, node->revision));
+      SVN_ERR(svn_sqlite__bind_revnum(stmt, 7, node->revision));
     }
 
   if (node->presence == svn_wc__db_status_normal)

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c Tue Jun 26 19:26:49 2012
@@ -1134,19 +1134,17 @@ is_external_rolled_out(svn_boolean_t *is
                        svn_wc__committable_external_info_t *xinfo,
                        apr_pool_t *scratch_pool)
 {
-  const char *x_repos_relpath;
-  const char *x_repos_root_url;
+  const char *repos_relpath;
+  const char *repos_root_url;
   svn_error_t *err;
 
   *is_rolled_out = FALSE;
 
-  err = svn_wc__node_get_origin(NULL, NULL,
-                                &x_repos_relpath,
-                                &x_repos_root_url,
-                                NULL, NULL,
-                                wc_ctx, xinfo->local_abspath,
-                                FALSE, /* scan_deleted */
-                                scratch_pool, scratch_pool);
+  err = svn_wc__db_base_get_info(NULL, NULL, NULL, &repos_relpath,
+                                 &repos_root_url, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 wc_ctx->db, xinfo->local_abspath,
+                                 scratch_pool, scratch_pool);
 
   if (err)
     {
@@ -1158,8 +1156,8 @@ is_external_rolled_out(svn_boolean_t *is
       SVN_ERR(err);
     }
 
-  *is_rolled_out = (strcmp(xinfo->repos_root_url, x_repos_root_url) == 0 &&
-                    strcmp(xinfo->repos_relpath, x_repos_relpath) == 0);
+  *is_rolled_out = (strcmp(xinfo->repos_root_url, repos_root_url) == 0 &&
+                    strcmp(xinfo->repos_relpath, repos_relpath) == 0);
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c Tue Jun 26 19:26:49 2012
@@ -920,7 +920,9 @@ svn_wc_adm_retrieve(svn_wc_adm_access_t 
   if (associated)
     {
       err = svn_wc__db_read_kind(&kind, svn_wc__adm_get_db(associated),
-                                 local_abspath, TRUE, pool);
+                                 local_abspath,
+                                 TRUE /* allow_missing */,
+                                 FALSE /* show_hidden */, pool);
 
       if (err)
         {
@@ -980,7 +982,9 @@ svn_wc_adm_probe_retrieve(svn_wc_adm_acc
   SVN_ERR_ASSERT(associated != NULL);
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  SVN_ERR(svn_wc__db_read_kind(&kind, associated->db, local_abspath, TRUE, pool));
+  SVN_ERR(svn_wc__db_read_kind(&kind, associated->db, local_abspath,
+                               TRUE /* allow_missing */, FALSE /* show_hidden*/,
+                               pool));
 
   if (kind == svn_kind_dir)
     dir = path;
@@ -1515,7 +1519,8 @@ svn_wc__acquire_write_lock(const char **
   svn_error_t *err;
 
   SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath,
-                               (lock_root_abspath != NULL),
+                               (lock_root_abspath != NULL) /* allow_missing*/,
+                               FALSE /* show_hidden */,
                                scratch_pool));
 
   if (!lock_root_abspath && kind != svn_kind_dir)
@@ -1532,7 +1537,9 @@ svn_wc__acquire_write_lock(const char **
       SVN_ERR_ASSERT(lock_root_abspath != NULL);
 
       parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-      err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath, TRUE,
+      err = svn_wc__db_read_kind(&parent_kind, db, parent_abspath,
+                                 TRUE /* allow_missing */,
+                                 FALSE /* show_missing */,
                                  scratch_pool);
       if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
         {
@@ -1565,7 +1572,9 @@ svn_wc__acquire_write_lock(const char **
       /* Can't lock parents that don't exist */
       if (kind == svn_kind_unknown)
         {
-          SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, FALSE,
+          SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath,
+                                       FALSE /* allow_missing */,
+                                       FALSE /* show_hidden */,
                                        scratch_pool));
 
           if (kind != svn_kind_dir)

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c Tue Jun 26 19:26:49 2012
@@ -926,9 +926,12 @@ maybe_resolve_conflicts(svn_skel_t **wor
 
 
 /* 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 in case the
+ * The merge is trivial if the file at LEFT_ABSPATH equals the detranslated
+ * form of the target at DETRANSLATED_TARGET_ABSPATH, because in this case
+ * the content of RIGHT_ABSPATH can be copied to the target.
+ * Another trivial case is if DETRANSLATED_TARGET_ABSPATH is identical to 
+ * RIGHT_ABSPATH - we can just accept the existing content as merge result.
+ * On success, set *MERGE_OUTCOME to SVN_WC_MERGE_MERGED in case the
  * target was changed, or to SVN_WC_MERGE_UNCHANGED if the target was not
  * changed. Install work queue items allocated in RESULT_POOL in *WORK_ITEMS.
  * On failure, set *MERGE_OUTCOME to SVN_WC_MERGE_NO_MERGE. */
@@ -938,6 +941,7 @@ merge_file_trivial(svn_skel_t **work_ite
                    const char *left_abspath,
                    const char *right_abspath,
                    const char *target_abspath,
+                   const char *detranslated_target_abspath,
                    svn_boolean_t dry_run,
                    svn_wc__db_t *db,
                    apr_pool_t *result_pool,
@@ -960,7 +964,8 @@ merge_file_trivial(svn_skel_t **work_ite
   /* 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,
-                                       target_abspath, scratch_pool));
+                                       detranslated_target_abspath,
+                                       scratch_pool));
   if (same_contents)
     {
       /* Check whether the left side equals the right side.
@@ -989,6 +994,23 @@ merge_file_trivial(svn_skel_t **work_ite
 
       return SVN_NO_ERROR;
     }
+  else
+    {
+      /* Check whether the existing version equals the right side. If it 
+       * does, the locally existing, changed file equals the incoming
+       * file, so there is no conflict. For binary files, we historically
+       * conflicted them needlessly, while merge_text_file figured it out 
+       * eventually and returned svn_wc_merge_unchanged for them, which
+       * is what we do here. */
+      SVN_ERR(svn_io_files_contents_same_p(&same_contents,
+                                           detranslated_target_abspath,
+                                           right_abspath, scratch_pool));
+      if (same_contents)
+        {
+          *merge_outcome = svn_wc_merge_unchanged;
+          return SVN_NO_ERROR;
+        }
+    }
 
   *merge_outcome = svn_wc_merge_no_merge;
   return SVN_NO_ERROR;
@@ -1418,8 +1440,8 @@ svn_wc__internal_merge(svn_skel_t **work
 
   SVN_ERR(merge_file_trivial(work_items, merge_outcome,
                              left_abspath, right_abspath,
-                             target_abspath, dry_run, db,
-                             result_pool, scratch_pool));
+                             target_abspath, detranslated_target_abspath,
+                             dry_run, db, result_pool, scratch_pool));
   if (*merge_outcome == svn_wc_merge_no_merge)
     {
       if (is_binary)
@@ -1476,7 +1498,8 @@ svn_wc__internal_merge(svn_skel_t **work
 
 
 svn_error_t *
-svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+              enum svn_wc_notify_state_t *merge_props_outcome,
               svn_wc_context_t *wc_ctx,
               const char *left_abspath,
               const char *right_abspath,
@@ -1489,6 +1512,7 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
               svn_boolean_t dry_run,
               const char *diff3_cmd,
               const apr_array_header_t *merge_options,
+              apr_hash_t *original_props,
               const apr_array_header_t *prop_diff,
               svn_wc_conflict_resolver_func2_t conflict_func,
               void *conflict_baton,
@@ -1497,8 +1521,11 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
               apr_pool_t *scratch_pool)
 {
   const char *dir_abspath = svn_dirent_dirname(target_abspath, scratch_pool);
+  svn_skel_t *prop_items = NULL;
   svn_skel_t *work_items;
-  apr_hash_t *actual_props;
+  apr_hash_t *pristine_props = NULL;
+  apr_hash_t *actual_props = NULL;
+  apr_hash_t *new_actual_props = NULL;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(left_abspath));
   SVN_ERR_ASSERT(svn_dirent_is_absolute(right_abspath));
@@ -1508,37 +1535,86 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
   if (!dry_run)
     SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
 
-  /* Sanity check:  the merge target must be under revision control,
-   * unless the merge target is a copyfrom text, which lives in a
-   * temporary file and does not exist in ACTUAL yet. */
+  /* Sanity check:  the merge target must be a file under revision control */
   {
+    svn_wc__db_status_t status;
     svn_kind_t kind;
-    svn_boolean_t hidden;
-    SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, target_abspath, TRUE,
-                                 scratch_pool));
+    svn_boolean_t had_props;
+    svn_boolean_t props_mod;
 
-    if (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,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, &had_props, &props_mod, NULL, NULL,
+                                 NULL,
+                                 wc_ctx->db, target_abspath,
+                                 scratch_pool, scratch_pool));
+
+    if (kind != svn_kind_file || (status != svn_wc__db_status_normal
+                                  && status != svn_wc__db_status_added))
       {
-        *merge_outcome = svn_wc_merge_no_merge;
+        *merge_content_outcome = svn_wc_merge_no_merge;
+        if (merge_props_outcome)
+          *merge_props_outcome = svn_wc_notify_state_unchanged;
         return SVN_NO_ERROR;
       }
 
-    SVN_ERR(svn_wc__db_node_hidden(&hidden, wc_ctx->db, target_abspath,
-                                   scratch_pool));
+    if (merge_props_outcome && had_props)
+      {
+        SVN_ERR(svn_wc__db_read_pristine_props(&pristine_props,
+                                               wc_ctx->db, target_abspath,
+                                               scratch_pool, scratch_pool));
+      }
+    else if (merge_props_outcome)
+      pristine_props = apr_hash_make(scratch_pool);
 
-    if (hidden)
+    if (props_mod)
       {
-        *merge_outcome = svn_wc_merge_no_merge;
-        return SVN_NO_ERROR;
+        SVN_ERR(svn_wc__db_read_props(&actual_props,
+                                      wc_ctx->db, target_abspath,
+                                      scratch_pool, scratch_pool));
       }
+    else if (pristine_props)
+      actual_props = apr_hash_copy(scratch_pool, pristine_props);
+    else
+      actual_props = apr_hash_make(scratch_pool);
   }
 
-  SVN_ERR(svn_wc__db_read_props(&actual_props, wc_ctx->db, target_abspath,
-                                scratch_pool, scratch_pool));
+  if (merge_props_outcome)
+    {
+      int i;
+      apr_hash_t *new_pristine_props;
+      /* The PROPCHANGES may not have non-"normal" properties in it. If entry
+         or wc props were allowed, then the following code would install them
+         into the BASE and/or WORKING properties(!).  */
+      for (i = prop_diff->nelts; i--; )
+        {
+          const svn_prop_t *change = &APR_ARRAY_IDX(prop_diff, i, svn_prop_t);
+
+          if (!svn_wc_is_normal_prop(change->name))
+            return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
+                                     _("The property '%s' may not be merged "
+                                       "into '%s'."),
+                                     change->name,
+                                     svn_dirent_local_style(target_abspath,
+                                                            scratch_pool));
+        }
+
+      SVN_ERR(svn_wc__merge_props(&prop_items, merge_props_outcome,
+                                  &new_pristine_props, &new_actual_props,
+                                  wc_ctx->db, target_abspath, svn_kind_file,
+                                  left_version, right_version,
+                                  original_props, pristine_props, actual_props,
+                                  prop_diff, FALSE /* base_merge */,
+                                  dry_run,
+                                  conflict_func, conflict_baton,
+                                  cancel_func, cancel_baton,
+                                  scratch_pool, scratch_pool));
+    }
 
   /* Queue all the work.  */
   SVN_ERR(svn_wc__internal_merge(&work_items,
-                                 merge_outcome,
+                                 merge_content_outcome,
                                  wc_ctx->db,
                                  left_abspath, left_version,
                                  right_abspath, right_version,
@@ -1554,16 +1630,24 @@ svn_wc_merge4(enum svn_wc_merge_outcome_
                                  cancel_func, cancel_baton,
                                  scratch_pool, scratch_pool));
 
+  work_items = svn_wc__wq_merge(prop_items, work_items, scratch_pool);
+
   /* If this isn't a dry run, then run the work!  */
   if (!dry_run)
     {
-      SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
-                                scratch_pool));
+      if (new_actual_props)
+        SVN_ERR(svn_wc__db_op_set_props(wc_ctx->db, target_abspath,
+                                        new_actual_props,
+                                        svn_wc__has_magic_property(prop_diff),
+                                        NULL, work_items, scratch_pool));
+      else
+        SVN_ERR(svn_wc__db_wq_add(wc_ctx->db, target_abspath, work_items,
+                                  scratch_pool));
       SVN_ERR(svn_wc__wq_run(wc_ctx->db, target_abspath,
                              cancel_func, cancel_baton,
                              scratch_pool));
     }
-
+  
   return SVN_NO_ERROR;
 }
 



Mime
View raw message