You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/08/16 12:18:03 UTC

svn commit: r1373783 [28/50] - in /subversion/branches/compressed-pristines: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/client-side/svn-push/ contrib/client-side/svnmerge/ cont...

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/conflicts.h
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/conflicts.h?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/conflicts.h (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/conflicts.h Thu Aug 16 10:17:48 2012
@@ -49,24 +49,44 @@ extern "C" {
 #define SVN_WC__CONFLICT_KIND_REJECT "reject"
 #define SVN_WC__CONFLICT_KIND_OBSTRUCTED "obstructed"
 
+#define SVN_WC__CONFLICT_SRC_SUBVERSION "subversion"
 
+/* Return a new conflict skel, allocated in RESULT_POOL.
 
-/* Return a new conflict skel, allocated in RESULT_POOL. */
+   Typically creating a conflict starts with calling this function and then
+   collecting details via one or more calls to svn_wc__conflict_skel_add_*().
+
+   The caller can then (when necessary) add operation details via
+   svn_wc__conflict_skel_set_op_*() and store the resulting conflict together
+   with the result of its operation in the working copy database.
+*/
 svn_skel_t *
-svn_wc__conflict_skel_new(apr_pool_t *result_pool);
+svn_wc__conflict_skel_create(apr_pool_t *result_pool);
+
+/* Return a boolean in *COMPLETE indicating whether CONFLICT_SKEL contains
+   everything needed for installing in the working copy database.
+
+   This typically checks if CONFLICT_SKEL contains at least one conflict
+   and an operation.
+ */
+svn_error_t *
+svn_wc__conflict_skel_is_complete(svn_boolean_t *complete,
+                                  const svn_skel_t *conflict_skel);
 
 
 /* Set 'update' as the conflicting operation in CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
-   BASE_REVISION is the revision the node was at before the update.
-   TARGET_REVISION is the revision being updated to.
+   ORIGINAL specifies the BASE node before updating.
 
-   Do temporary allocations in SCRATCH_POOL. */
+   It is an error to set another operation to a conflict skel that
+   already has an operation.
+
+   Do temporary allocations in SCRATCH_POOL. The new skel data is
+   completely stored in RESULT-POOL. */
 svn_error_t *
 svn_wc__conflict_skel_set_op_update(svn_skel_t *conflict_skel,
-                                    svn_revnum_t base_revision,
-                                    svn_revnum_t target_revision,
+                                    const svn_wc_conflict_version_t *original,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
 
@@ -74,208 +94,296 @@ svn_wc__conflict_skel_set_op_update(svn_
 /* Set 'switch' as the conflicting operation in CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
-   BASE_REVISION is the revision the node was at before the switch.
-   TARGET_REVISION is the revision being switched to.
-   REPOS_RELPATH is the path being switched to, relative to the
-   repository root.
+   ORIGINAL specifies the BASE node before switching.
+
+   It is an error to set another operation to a conflict skel that
+   already has an operation.
 
    Do temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_wc__conflict_skel_set_op_switch(svn_skel_t *conflict_skel,
-                                    svn_revnum_t base_revision,
-                                    svn_revnum_t target_revision,
-                                    const char *repos_relpath,
+                                    const svn_wc_conflict_version_t *original,
+                                    apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
 
 
 /* Set 'merge' as conflicting operation in CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
-   REPOS_UUID is the UUID of the repository accessed via REPOS_ROOT_URL.
+   LEFT and RIGHT paths are the merge-left and merge-right merge
+   sources of the merge.
 
-   LEFT_REPOS_RELPATH and RIGHT_REPOS_RELPATH paths to the merge-left
-   and merge-right merge sources, relative to REPOS_URL
-
-   LEFT_REVISION is the merge-left revision.
-   RIGHT_REVISION is the merge-right revision.
+   It is an error to set another operation to a conflict skel that
+   already has an operation.
 
    Do temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_wc__conflict_skel_set_op_merge(svn_skel_t *conflict_skel,
-                                   const char *repos_uuid,
-                                   const char *repos_root_url,
-                                   svn_revnum_t left_revision,
-                                   const char *left_repos_relpath,
-                                   svn_revnum_t right_revision,
-                                   const char *right_repos_relpath,
+                                   const svn_wc_conflict_version_t *left,
+                                   const svn_wc_conflict_version_t *right,
                                    apr_pool_t *result_pool,
                                    apr_pool_t *scratch_pool);
 
 
-/* Set 'patch' as the conflicting operation in CONFLICT_SKEL.
+/* Add a text conflict to CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
-   PATCH_SOURCE_LABEL is a string identifying the patch source in
-   some way, for display purposes. It is usually the absolute path
-   to the patch file, or a token such as "<stdin>" if the patch source
-   is not a file.
+   The DB, WRI_ABSPATH pair specifies in which working copy the conflict
+   will be recorded. (Needed for making the paths relative).
+
+   MINE_ABSPATH, THEIR_OLD_ABSPATH and THEIR_ABSPATH specify the marker
+   files for this text conflict. Each of these values can be NULL to specify
+   that the node doesn't exist in this case.
+
+   ### It is expected that in a future version we will also want to store
+   ### the sha1 checksum of these files to allow reinstalling the conflict
+   ### markers from the pristine store.
+
+   It is an error to add another text conflict to a conflict skel that
+   already contains a text conflict.
 
    Do temporary allocations in SCRATCH_POOL.
 */
 svn_error_t *
-svn_wc__conflict_skel_set_op_patch(svn_skel_t *conflict_skel,
-                                   const char *patch_source_label,
-                                   apr_pool_t *result_pool,
-                                   apr_pool_t *scratch_pool);
+svn_wc__conflict_skel_add_text_conflict(svn_skel_t *conflict_skel,
+                                        svn_wc__db_t *db,
+                                        const char *wri_abspath,
+                                        const char *mine_abspath,
+                                        const char *their_old_abspath,
+                                        const char *their_abspath,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool);
 
 
-/* Add a text conflict to CONFLICT_SKEL.
+/* Add property conflict details to CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
-   All checksums passed should be suitable for retreiving conflicted
-   versions of the file from the pristine store.
+   The DB, WRI_ABSPATH pair specifies in which working copy the conflict
+   will be recorded. (Needed for making the paths relative).
 
-   ORIGINAL_CHECKSUM is the checksum of the BASE version of the conflicted
-   file (without local modifications).
-   MINE_CHECKSUM is the checksum of the WORKING version of the conflicted
-   file as of the time the conflicting operation was run (i.e. including
-   local modifications).
-   INCOMING_CHECKSUM is the checksum of the incoming file causing the
-   conflict. ### is this needed for update? what about merge?
-
-   It is an error (### which one?) if no conflicting operation has been
-   set on CONFLICT_SKEL before calling this function.
-   It is an error (### which one?) if CONFLICT_SKEL already contains
-   a text conflict.
+   The MINE_PROPS, THEIR_OLD_PROPS and THEIR_PROPS are hashes mapping a
+   const char * property name to a const svn_string_t* value.
 
-   Do temporary allocations in SCRATCH_POOL.
-*/
-svn_error_t *
-svn_wc__conflict_skel_add_text_conflict(
-  svn_skel_t *conflict_skel,
-  const svn_checksum_t *original_checksum,
-  const svn_checksum_t *mine_checksum,
-  const svn_checksum_t *incoming_checksum,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
-
-
-/* Add a property conflict to SKEL.
-
-   PROP_NAME is the name of the conflicted property.
-
-   ORIGINAL_VALUE is the property's value at the BASE revision. MINE_VALUE
-   is the property's value in WORKING (BASE + local modifications).
-   INCOMING_VALUE is the incoming property value brought in by the
-   operation. When merging, INCOMING_BASE_VALUE is the base value against
-   which INCOMING_VALUE ws being applied. For updates, INCOMING_BASE_VALUE
-   should be the same as ORIGINAL_VALUE.
-
-   *_VALUE may be NULL, indicating no value was present.
-
-   It is an error (### which one?) if no conflicting operation has been
-   set on CONFLICT_SKEL before calling this function.
-   It is an error (### which one?) if CONFLICT_SKEL already cotains
-   a propery conflict for PROP_NAME.
+   The CONFLICTED_PROP_NAMES is a const char * property name value mapping
+   to "", recording which properties aren't resolved yet in the current
+   property values.
+   ### Needed for creating the marker file from this conflict data.
+   ### Would also allow per property marking as resolved.
+   ### Maybe useful for calling (legacy) conflict resolvers that expect one
+   ### property conflict per invocation.
+
+   It is an error to add another text conflict to a conflict skel that
+   already contains a text conflict.
 
-   The conflict recorded in SKEL will be allocated from RESULT_POOL. Do
-   temporary allocations in SCRATCH_POOL.
+   Do temporary allocations in SCRATCH_POOL.
 */
 svn_error_t *
-svn_wc__conflict_skel_add_prop_conflict(
-  svn_skel_t *skel,
-  const char *prop_name,
-  const svn_string_t *original_value,
-  const svn_string_t *mine_value,
-  const svn_string_t *incoming_value,
-  const svn_string_t *incoming_base_value,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
+svn_wc__conflict_skel_add_prop_conflict(svn_skel_t *conflict_skel,
+                                        svn_wc__db_t *db,
+                                        const char *wri_abspath,
+                                        const char *marker_abspath,
+                                        apr_hash_t *mine_props,
+                                        apr_hash_t *their_old_props,
+                                        apr_hash_t *their_props,
+                                        apr_hash_t *conflicted_prop_names,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool);
 
 
 /* Add a tree conflict to CONFLICT_SKEL.
    Allocate data stored in the skel in RESULT_POOL.
 
    LOCAL_CHANGE is the local tree change made to the node.
-   ORIGINAL_LOCAL_KIND is the kind of the local node in BASE.
-   If ORIGINAL_LOCAL_KIND is svn_node_file, ORIGINAL_CHECKSUM is the checksum
-   for the BASE of the file, for retrieval from the pristine store.
-
-   MINE_LOCAL_KIND is the kind of the local node in WORKING at the
-   time the conflict was flagged.
-   If MINE_LOCAL_KIND is svn_node_file, ORIGINAL_CHECKSUM is the checksum
-   of the WORKING version of the file at the time the conflict was flagged,
-   for retrieval from the pristine store.
-
-   INCOMING_KIND is the kind of the incoming node.
-   If INCOMING_KIND is svn_node_file, INCOMING_CHECKSUM is the checksum
-   of the INCOMING version of the file, for retrieval from the pristine store.
-
-   It is an error (### which one?) if no conflicting operation has been
-   set on CONFLICT_SKEL before calling this function.
-   It is an error (### which one?) if CONFLICT_SKEL already contains
-   a tree conflict.
+   INCOMING_CHANGE is the incoming change made to the node.
+
+   It is an error to add another tree conflict to a conflict skel that
+   already contains a tree conflict.
+
+   ### Is it an error to add a tree conflict to any existing conflict?
 
    Do temporary allocations in SCRATCH_POOL.
 */
 svn_error_t *
-svn_wc__conflict_skel_add_tree_conflict(
-  svn_skel_t *skel,
-  svn_wc_conflict_reason_t local_change,
-  svn_kind_t original_local_kind,
-  const svn_checksum_t *original_checksum,
-  svn_kind_t mine_local_kind,
-  const svn_checksum_t *mine_checksum,
-  svn_wc_conflict_action_t incoming_change,
-  svn_kind_t incoming_kind,
-  const svn_checksum_t *incoming_checksum,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
-
-
-/* Add a reject conflict to CONFLICT_SKEL.
-   Allocate data stored in the skel in RESULT_POOL.
-
-   HUNK_ORIGINAL_OFFSET, HUNK_ORIGINAL_LENGTH, HUNK_MODIFIED_OFFSET,
-   and HUNK_MODIFIED_LENGTH is hunk-header data identifying the hunk
-   which was rejected.
-
-   REJECT_DIFF_CHECKSUM is the checksum of the text of the rejected
-   diff, for retrieval from the pristine store.
-
-   It is an error (### which one?) if no conflicting operation has been
-   set on CONFLICT_SKEL before calling this function.
-   It is an error (### which one?) if CONFLICT_SKEL already contains
-   a reject conflict for the hunk.
+svn_wc__conflict_skel_add_tree_conflict(svn_skel_t *conflict_skel,
+                                        svn_wc__db_t *db,
+                                        const char *wri_abspath,
+                                        svn_wc_conflict_reason_t local_change,
+                                        svn_wc_conflict_action_t incoming_change,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool);
+
+/* Allows resolving specific conflicts stored in CONFLICT_SKEL.
+
+   When RESOLVE_TEXT is TRUE and CONFLICT_SKEL contains a text conflict,
+   resolve/remove the text conflict in CONFLICT_SKEL.
+
+   When RESOLVE_PROP is "" and CONFLICT_SKEL contains a property conflict,
+   resolve/remove all property conflicts in CONFLICT_SKEL.
+
+   When RESOLVE_PROP is not NULL and not "", remove the property conflict on
+   the property RESOLVE_PROP in CONFLICT_SKEL. When RESOLVE_PROP was the last
+   property in CONFLICT_SKEL remove the property conflict info from
+   CONFLICT_SKEL.
+
+   When RESOLVE_TREE is TRUE and CONFLICT_SKEL contains a tree conflict,
+   resolve/remove the tree conflict in CONFLICT_SKEL.
+
+   If COMPLETELY_RESOLVED is not NULL, then set *COMPLETELY_RESOLVED to TRUE,
+   when no conflict registration is left in CONFLICT_SKEL after editting,
+   otherwise to FALSE.
 
-   Do temporary allocations in SCRATCH_POOL.
-*/
+   Allocate data stored in the skel in RESULT_POOL.
+
+   This functions edits CONFLICT_SKEL. New skels might be created in
+   RESULT_POOL. Temporary allocations will use SCRATCH_POOL.
+ */
+/* ### db, wri_abspath is currently unused. Remove? */
 svn_error_t *
-svn_wc__conflict_skel_add_reject_conflict(
-  svn_skel_t *conflict_skel,
-  svn_linenum_t hunk_original_offset,
-  svn_linenum_t hunk_original_length,
-  svn_linenum_t hunk_modified_offset,
-  svn_linenum_t hunk_modified_length,
-  const svn_checksum_t *reject_diff_checksum,
-  apr_pool_t *result_pool,
-  apr_pool_t *scratch_pool);
-
-
-/* Add an obstruction conflict to CONFLICT_SKEL.
-   Allocate data stored in the skel in RESULT_POOL.
-
-   It is an error (### which one?) if no conflicting operation has been
-   set on CONFLICT_SKEL before calling this function.
-   It is an error (### which one?) if CONFLICT_SKEL already contains
-   an obstruction.
+svn_wc__conflict_skel_resolve(svn_boolean_t *completely_resolved,
+                              svn_skel_t *conflict_skel,
+                              svn_wc__db_t *db,
+                              const char *wri_abspath,
+                              svn_boolean_t resolve_text,
+                              const char *resolve_prop,
+                              svn_boolean_t resolve_tree,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
 
-   Do temporary allocations in SCRATCH_POOL.
-*/
+/*
+ * -----------------------------------------------------------
+ * Reading conflict skels. Maybe this can be made private later
+ * -----------------------------------------------------------
+ */
+
+/* Read common information from CONFLICT_SKEL to determine the operation
+ * and merge origins.
+ *
+ * Output arguments can be NULL if the value is not necessary.
+ *
+ * TEXT_, PROP_ and TREE_CONFLICTED (when not NULL) will be set to TRUE
+ * when the conflict contains the specified kind of conflict, otherwise
+ * to false.
+ *
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_read_info(svn_wc_operation_t *operation,
+                           const apr_array_header_t **locations,
+                           svn_boolean_t *text_conflicted,
+                           svn_boolean_t *prop_conflicted,
+                           svn_boolean_t *tree_conflicted,
+                           svn_wc__db_t *db,
+                           const char *wri_abspath,
+                           const svn_skel_t *conflict_skel,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
+/* Reads back the original data stored by svn_wc__conflict_add_text_conflict()
+ * in CONFLICT_SKEL for a node in DB, WRI_ABSPATH.
+ *
+ * Values as documented for svn_wc__conflict_add_text_conflict().
+ *
+ * Output arguments can be NULL if the value is not necessary.
+ *
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_read_text_conflict(const char **mine_abspath,
+                                    const char **their_old_abspath,
+                                    const char **their_abspath,
+                                    svn_wc__db_t *db,
+                                    const char *wri_abspath,
+                                    const svn_skel_t *conflict_skel,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
+
+/* Reads back the original data stored by svn_wc__conflict_add_prop_conflict()
+ * in CONFLICT_SKEL for a node in DB, WRI_ABSPATH.
+ *
+ * Values as documented for svn_wc__conflict_add_prop_conflict().
+ *
+ * Output arguments can be NULL if the value is not necessary
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_read_prop_conflict(const char **marker_abspath,
+                                    apr_hash_t **mine_props,
+                                    apr_hash_t **their_old_props,
+                                    apr_hash_t **their_props,
+                                    apr_hash_t **conflicted_prop_names,
+                                    svn_wc__db_t *db,
+                                    const char *wri_abspath,
+                                    const svn_skel_t *conflict_skel,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
+
+/* Reads back the original data stored by svn_wc__conflict_add_tree_conflict()
+ * in CONFLICT_SKEL for a node in DB, WRI_ABSPATH.
+ *
+ * Values as documented for svn_wc__conflict_add_tree_conflict().
+ *
+ * Output arguments can be NULL if the value is not necessary
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_read_tree_conflict(svn_wc_conflict_reason_t *local_change,
+                                    svn_wc_conflict_action_t *incoming_change,
+                                    svn_wc__db_t *db,
+                                    const char *wri_abspath,
+                                    const svn_skel_t *conflict_skel,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
+
+/* Reads in *MARKERS a list of const char * absolute paths of the marker files
+   referenced from CONFLICT_SKEL.
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_read_markers(const apr_array_header_t **markers,
+                              svn_wc__db_t *db,
+                              const char *wri_abspath,
+                              const svn_skel_t *conflict_skel,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
+
+/* Create the necessary marker files for the conflicts stored in
+ * CONFLICT_SKEL and return the work items to fill the markers from
+ * the work queue.
+ *
+ * Currently only used for property conflicts as text conflict markers
+ * are just in-wc files.
+ *
+ * Allocate the result in RESULT_POOL. Perform temporary allocations in
+ * SCRATCH_POOL.
+ */
+svn_error_t *
+svn_wc__conflict_create_markers(svn_skel_t **work_item,
+                                svn_wc__db_t *db,
+                                const char *local_abspath,
+                                svn_skel_t *conflict_skel,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool);
+
+/* Call the interactive conflict resolver RESOLVER_FUNC with RESOLVER_BATON to
+   allow resolving the conflicts on LOCAL_ABSPATH.
+
+   CONFLICT_SKEL contains the details of the conflicts on LOCAL_ABSPATH.
+   Resolver actions are directly applied to the in-db state of LOCAL_ABSPATH,
+   so the conflict and the state in CONFLICT_SKEL must already be installed in
+   wc.db. */
 svn_error_t *
-svn_wc__conflict_skel_add_obstruction(svn_skel_t *conflict_skel,
-                                      apr_pool_t *result_pool,
-                                      apr_pool_t *scratch_pool);
+svn_wc__conflict_invoke_resolver(svn_wc__db_t *db,
+                                 const char *local_abspath,
+                                 const svn_skel_t *conflict_skel,
+                                 const apr_array_header_t *merge_options,
+                                 svn_wc_conflict_resolver_func2_t resolver_func,
+                                 void *resolver_baton,
+                                 apr_pool_t *scratch_pool);
 
 
 /* Resolve text conflicts on the given node.  */

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/copy.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/copy.c Thu Aug 16 10:17:48 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;
-}
-
-
-/* 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(svn_io_copy_link(src_abspath, dst_tmp_abspath, scratch_pool));
 
-  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;
@@ -231,8 +218,8 @@ copy_versioned_file(svn_wc__db_t *db,
           const char *conflict_working = NULL;
 
           /* Is there a text conflict at the source path? */
-          SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, src_abspath,
-                                            scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__read_conflicts(&conflicts, db, src_abspath,
+                                         scratch_pool, scratch_pool));
 
           for (i = 0; i < conflicts->nelts; i++)
             {
@@ -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,54 +464,48 @@ 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;
 
-          if (marker_files &&
-              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));
-            }
+          if (marker_files &&
+              apr_hash_get(marker_files, unver_src_abspath,
+                           APR_HASH_KEY_STRING))
+            continue;
+
+          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 +535,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 +551,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 +571,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 +603,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 +663,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 +718,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;
 }
 
@@ -840,8 +794,8 @@ remove_node_conflict_markers(svn_wc__db_
 {
   const apr_array_header_t *conflicts;
 
-  SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, src_abspath,
-                                    scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__read_conflicts(&conflicts, db, src_abspath,
+                                 scratch_pool, scratch_pool));
 
   /* Do we have conflict markers that should be removed? */
   if (conflicts != NULL)

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/crop.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/crop.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/crop.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/crop.c Thu Aug 16 10:17:48 2012
@@ -31,24 +31,10 @@
 #include "svn_path.h"
 
 #include "wc.h"
+#include "workqueue.h"
 
 #include "svn_private_config.h"
 
-/* Evaluate EXPR.  If it returns an error, return that error, unless
-   the error's code is SVN_ERR_WC_LEFT_LOCAL_MOD, in which case clear
-   the error and do not return. */
-#define IGNORE_LOCAL_MOD(expr)                                   \
-  do {                                                           \
-    svn_error_t *__temp = (expr);                                \
-    if (__temp)                                                  \
-      {                                                          \
-        if (__temp->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)        \
-          svn_error_clear(__temp);                               \
-        else                                                     \
-          return svn_error_trace(__temp);                       \
-      }                                                          \
-  } while (0)
-
 /* Helper function that crops the children of the LOCAL_ABSPATH, under the
  * constraint of NEW_DEPTH. The DIR_PATH itself will never be cropped. The
  * whole subtree should have been locked.
@@ -121,29 +107,25 @@ crop_children(svn_wc__db_t *db,
                                             ? svn_depth_immediates
                                             : svn_depth_files;
           if (new_depth < remove_below)
-            SVN_ERR(svn_wc__db_op_remove_node(db, local_abspath,
-                                              SVN_INVALID_REVNUM,
-                                              svn_kind_unknown,
-                                              iterpool));
+            SVN_ERR(svn_wc__db_base_remove(db, local_abspath, FALSE,
+                                           SVN_INVALID_REVNUM,
+                                           NULL, NULL, iterpool));
 
           continue;
         }
       else if (kind == svn_kind_file)
         {
-          /* We currently crop on a directory basis. So don't worry about
-             svn_depth_exclude here. And even we permit excluding a single
-             file in the future, svn_wc_remove_from_revision_control() can
-             also handle it. We only need to skip the notification in that
-             case. */
           if (new_depth == svn_depth_empty)
-            IGNORE_LOCAL_MOD(
-              svn_wc__internal_remove_from_revision_control(
-                                                   db,
-                                                   child_abspath,
-                                                   TRUE, /* destroy */
-                                                   FALSE, /* instant error */
-                                                   cancel_func, cancel_baton,
-                                                   iterpool));
+            SVN_ERR(svn_wc__db_op_remove_node(NULL,
+                                              db, child_abspath,
+                                              TRUE /* destroy */,
+                                              FALSE /* destroy_changes */,
+                                              SVN_INVALID_REVNUM,
+                                              svn_wc__db_status_not_present,
+                                              svn_kind_none,
+                                              NULL, NULL,
+                                              cancel_func, cancel_baton,
+                                              iterpool));
           else
             continue;
 
@@ -152,15 +134,16 @@ crop_children(svn_wc__db_t *db,
         {
           if (new_depth < svn_depth_immediates)
             {
-              IGNORE_LOCAL_MOD(
-                svn_wc__internal_remove_from_revision_control(
-                                                     db,
-                                                     child_abspath,
-                                                     TRUE, /* destroy */
-                                                     FALSE, /* instant error */
-                                                     cancel_func,
-                                                     cancel_baton,
-                                                     iterpool));
+              SVN_ERR(svn_wc__db_op_remove_node(NULL,
+                                                db, child_abspath,
+                                                TRUE /* destroy */,
+                                                FALSE /* destroy_changes */,
+                                                SVN_INVALID_REVNUM,
+                                                svn_wc__db_status_not_present,
+                                                svn_kind_none,
+                                                NULL, NULL,
+                                                cancel_func, cancel_baton,
+                                                iterpool));
             }
           else
             {
@@ -272,27 +255,21 @@ svn_wc_exclude(svn_wc_context_t *wc_ctx,
         break; /* Ok to exclude */
     }
 
-  /* ### This could use some kind of transaction */
-
   /* Remove all working copy data below local_abspath */
-  IGNORE_LOCAL_MOD(svn_wc__internal_remove_from_revision_control(
-                                    wc_ctx->db,
-                                    local_abspath,
-                                    TRUE,
-                                    FALSE,
+  SVN_ERR(svn_wc__db_op_remove_node(NULL,
+                                    wc_ctx->db, local_abspath,
+                                    TRUE /* destroy */,
+                                    FALSE /* destroy_changes */,
+                                    revision,
+                                    svn_wc__db_status_excluded,
+                                    kind,
+                                    NULL, NULL,
                                     cancel_func, cancel_baton,
                                     scratch_pool));
 
-  SVN_ERR(svn_wc__db_base_add_excluded_node(wc_ctx->db,
-                                            local_abspath,
-                                            repos_relpath,
-                                            repos_root,
-                                            repos_uuid,
-                                            revision,
-                                            kind,
-                                            svn_wc__db_status_excluded,
-                                            NULL, NULL,
-                                            scratch_pool));
+  SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
+                         cancel_func, cancel_baton,
+                         scratch_pool));
 
   if (notify_func)
     {
@@ -372,7 +349,11 @@ svn_wc_crop_tree2(svn_wc_context_t *wc_c
         SVN_ERR_MALFUNCTION();
     }
 
-  return crop_children(db, local_abspath, dir_depth, depth,
-                       notify_func, notify_baton,
-                       cancel_func, cancel_baton, scratch_pool);
+  SVN_ERR(crop_children(db, local_abspath, dir_depth, depth,
+                        notify_func, notify_baton,
+                        cancel_func, cancel_baton, scratch_pool));
+
+  return svn_error_trace(svn_wc__wq_run(db, local_abspath,
+                                        cancel_func, cancel_baton,
+                                        scratch_pool));
 }

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/deprecated.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/deprecated.c Thu Aug 16 10:17:48 2012
@@ -36,6 +36,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 
+#include "private/svn_subr_private.h"
 #include "private/svn_wc_private.h"
 
 #include "wc.h"
@@ -688,9 +689,8 @@ svn_wc_queue_committed(svn_wc_committed_
   const svn_checksum_t *md5_checksum;
 
   if (digest)
-    md5_checksum = svn_checksum__from_digest(
-                   digest, svn_checksum_md5,
-                   svn_wc__get_committed_queue_pool(*queue));
+    md5_checksum = svn_checksum__from_digest_md5(
+                     digest, svn_wc__get_committed_queue_pool(*queue));
   else
     md5_checksum = NULL;
 
@@ -748,7 +748,7 @@ svn_wc_process_committed4(const char *pa
     new_date = 0;
 
   if (digest)
-    md5_checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
+    md5_checksum = svn_checksum__from_digest_md5(digest, pool);
   else
     md5_checksum = NULL;
 
@@ -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,
@@ -4284,6 +4329,17 @@ svn_wc_merge(const char *left,
 
 /*** From util.c ***/
 
+svn_wc_conflict_version_t *
+svn_wc_conflict_version_create(const char *repos_url,
+                               const char *path_in_repos,
+                               svn_revnum_t peg_rev,
+                               svn_node_kind_t node_kind,
+                               apr_pool_t *pool)
+{
+  return svn_wc_conflict_version_create2(repos_url, NULL, path_in_repos,
+                                         peg_rev, node_kind, pool);
+}
+
 svn_wc_conflict_description_t *
 svn_wc_conflict_description_create_text(const char *path,
                                         svn_wc_adm_access_t *adm_access,

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_editor.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_editor.c Thu Aug 16 10:17:48 2012
@@ -61,6 +61,7 @@
 #include "svn_path.h"
 #include "svn_hash.h"
 
+#include "private/svn_subr_private.h"
 #include "private/svn_wc_private.h"
 
 #include "wc.h"
@@ -1494,9 +1495,8 @@ window_handler(svn_txdelta_window_t *win
 
   if (!window)
     {
-      fb->result_checksum = svn_checksum__from_digest(whb->result_digest,
-                                                      svn_checksum_md5,
-                                                      fb->pool);
+      fb->result_checksum = svn_checksum__from_digest_md5(whb->result_digest,
+                                                          fb->pool);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_local.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/diff_local.c Thu Aug 16 10:17:48 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/compressed-pristines/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/entries.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/entries.c Thu Aug 16 10:17:48 2012
@@ -37,6 +37,7 @@
 
 #include "wc.h"
 #include "adm_files.h"
+#include "conflicts.h"
 #include "entries.h"
 #include "lock.h"
 #include "tree_conflicts.h"
@@ -55,7 +56,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;
@@ -452,9 +453,9 @@ read_one_entry(const svn_wc_entry_t **ne
           child_abspath = svn_dirent_join(dir_abspath, child_name,
                                           scratch_pool);
 
-          SVN_ERR(svn_wc__db_read_conflicts(&child_conflicts,
-                                            db, child_abspath,
-                                            scratch_pool, scratch_pool));
+          SVN_ERR(svn_wc__read_conflicts(&child_conflicts,
+                                         db, child_abspath,
+                                         scratch_pool, scratch_pool));
 
           for (j = 0; j < child_conflicts->nelts; j++)
             {
@@ -875,8 +876,8 @@ read_one_entry(const svn_wc_entry_t **ne
     {
       const apr_array_header_t *conflicts;
       int j;
-      SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, entry_abspath,
-                                        scratch_pool, scratch_pool));
+      SVN_ERR(svn_wc__read_conflicts(&conflicts, db, entry_abspath,
+                                     scratch_pool, scratch_pool));
 
       for (j = 0; j < conflicts->nelts; j++)
         {
@@ -1426,7 +1427,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 +1445,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)
@@ -1501,10 +1502,15 @@ insert_node(svn_sqlite__db_t *sdb,
 /* */
 static svn_error_t *
 insert_actual_node(svn_sqlite__db_t *sdb,
+                   svn_wc__db_t *db,
+                   const char *wri_abspath,
                    const db_actual_node_t *actual_node,
                    apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
+#if SVN_WC__VERSION >= SVN_WC__USES_CONFLICT_SKELS
+  svn_skel_t *conflict_data = NULL;
+#endif
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_ACTUAL_NODE));
 
@@ -1516,21 +1522,44 @@ insert_actual_node(svn_sqlite__db_t *sdb
     SVN_ERR(svn_sqlite__bind_properties(stmt, 4, actual_node->properties,
                                         scratch_pool));
 
-  if (actual_node->conflict_old)
-    {
-      SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->conflict_old));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 6, actual_node->conflict_new));
-      SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_working));
+  if (actual_node->changelist)
+    SVN_ERR(svn_sqlite__bind_text(stmt, 5, actual_node->changelist));
+
+#if SVN_WC__VERSION < SVN_WC__USES_CONFLICT_SKELS
+  if (actual_node->conflict_old
+      || actual_node->conflict_new
+      || actual_node->conflict_working)
+    {
+      SVN_ERR(svn_sqlite__bind_text(stmt, 7, actual_node->conflict_old));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->conflict_new));
+      SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->conflict_working));
     }
 
   if (actual_node->prop_reject)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 8, actual_node->prop_reject));
-
-  if (actual_node->changelist)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 9, actual_node->changelist));
+    SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->prop_reject));
 
   if (actual_node->tree_conflict_data)
-    SVN_ERR(svn_sqlite__bind_text(stmt, 10, actual_node->tree_conflict_data));
+    SVN_ERR(svn_sqlite__bind_text(stmt, 11, actual_node->tree_conflict_data));
+#else
+  SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(
+                                &conflict_data,
+                                db, wri_abspath,
+                                actual_node->local_relpath,
+                                actual_node->conflict_old,
+                                actual_node->conflict_working,
+                                actual_node->conflict_new,
+                                actual_node->prop_reject,
+                                actual_node->tree_conflict_data,
+                                strlen(actual_node->tree_conflict_data),
+                                scratch_pool, scratch_pool));
+
+  if (conflict_data)
+    {
+      svn_stringbuf_t *data = svn_skel__unparse(conflict_data, scratch_pool);
+
+      SVN_ERR(svn_sqlite__bind_blob(stmt, 6, data->data, data->len));
+    }
+#endif
 
   /* Execute and reset the insert clause. */
   return svn_error_trace(svn_sqlite__insert(NULL, stmt));
@@ -2189,7 +2218,8 @@ write_entry(struct write_baton **entry_n
       actual_node->local_relpath = local_relpath;
       actual_node->parent_relpath = parent_relpath;
 
-      SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
+      SVN_ERR(insert_actual_node(sdb, db, tmp_entry_abspath,
+                                 actual_node, scratch_pool));
     }
 
   if (entry_node)
@@ -2217,6 +2247,8 @@ write_entry(struct write_baton **entry_n
 static svn_error_t *
 write_actual_only_entries(apr_hash_t *tree_conflicts,
                           svn_sqlite__db_t *sdb,
+                          svn_wc__db_t *db,
+                          const char *wri_abspath,
                           apr_int64_t wc_id,
                           const char *parent_relpath,
                           apr_pool_t *scratch_pool)
@@ -2235,7 +2267,8 @@ write_actual_only_entries(apr_hash_t *tr
       actual_node->parent_relpath = parent_relpath;
       actual_node->tree_conflict_data = svn__apr_hash_index_val(hi);
 
-      SVN_ERR(insert_actual_node(sdb, actual_node, scratch_pool));
+      SVN_ERR(insert_actual_node(sdb, db, wri_abspath, actual_node,
+                                 scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -2317,8 +2350,9 @@ svn_wc__write_upgraded_entries(void **di
     }
 
   if (dir_node->tree_conflicts)
-    SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb,
-                                      wc_id, dir_relpath, iterpool));
+    SVN_ERR(write_actual_only_entries(dir_node->tree_conflicts, sdb, db,
+                                      new_root_abspath, wc_id, dir_relpath,
+                                      iterpool));
 
   *dir_baton = dir_node;
   svn_pool_destroy(iterpool);

Modified: subversion/branches/compressed-pristines/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/compressed-pristines/subversion/libsvn_wc/externals.c?rev=1373783&r1=1373782&r2=1373783&view=diff
==============================================================================
--- subversion/branches/compressed-pristines/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/compressed-pristines/subversion/libsvn_wc/externals.c Thu Aug 16 10:17:48 2012
@@ -600,10 +600,11 @@ close_file(void *file_baton,
       eb->new_pristine_abspath = NULL;
     }
 
-  /* ### TODO: Merge the changes */
+  /* Merge the changes */
 
   {
     svn_skel_t *all_work_items = NULL;
+    svn_skel_t *conflict_skel = NULL;
     svn_skel_t *work_item;
     apr_hash_t *base_props = NULL;
     apr_hash_t *actual_props = NULL;
@@ -675,26 +676,20 @@ close_file(void *file_baton,
 
       if (regular_prop_changes->nelts > 0)
         {
-          SVN_ERR(svn_wc__merge_props(&work_item, &prop_state,
+          SVN_ERR(svn_wc__merge_props(&conflict_skel,
+                                      &prop_state,
                                       &new_pristine_props,
                                       &new_actual_props,
                                       eb->db, eb->local_abspath,
                                       svn_kind_file,
-                                      NULL, NULL,
                                       NULL /* server_baseprops*/,
                                       base_props,
                                       actual_props,
                                       regular_prop_changes,
                                       TRUE /* base_merge */,
                                       FALSE /* dry_run */,
-                                      eb->conflict_func,
-                                      eb->conflict_baton,
                                       eb->cancel_func, eb->cancel_baton,
                                       pool, pool));
-
-          if (work_item)
-            all_work_items = svn_wc__wq_merge(all_work_items, work_item,
-                                              pool);
         }
       else
         {
@@ -740,6 +735,7 @@ close_file(void *file_baton,
                 enum svn_wc_merge_outcome_t merge_outcome;
                 /* Ok, we have to do some work to merge a local change */
                 SVN_ERR(svn_wc__perform_file_merge(&work_item,
+                                                   &conflict_skel,
                                                    &merge_outcome,
                                                    eb->db,
                                                    eb->local_abspath,
@@ -752,8 +748,6 @@ close_file(void *file_baton,
                                                    *eb->target_revision,
                                                    eb->propchanges,
                                                    eb->diff3cmd,
-                                                   eb->conflict_func,
-                                                   eb->conflict_baton,
                                                    eb->cancel_func,
                                                    eb->cancel_baton,
                                                    pool, pool));
@@ -784,6 +778,29 @@ close_file(void *file_baton,
         /* ### Retranslate on magic property changes, etc. */
       }
 
+    if (conflict_skel)
+      {
+        SVN_ERR(svn_wc__conflict_skel_set_op_switch(
+                            conflict_skel,
+                            svn_wc_conflict_version_create2(
+                                    eb->repos_root_url,
+                                    eb->repos_uuid,
+                                    repos_relpath,
+                                    eb->original_revision,
+                                    svn_node_file,
+                                    pool),
+                            pool, pool));
+
+
+        SVN_ERR(svn_wc__conflict_create_markers(&work_item,
+                                                eb->db, eb->local_abspath,
+                                                conflict_skel,
+                                                pool, pool));
+
+        all_work_items = svn_wc__wq_merge(all_work_items, work_item,
+                                          pool);
+      }
+
     SVN_ERR(svn_wc__db_external_add_file(
                         eb->db,
                         eb->local_abspath,
@@ -804,6 +821,7 @@ close_file(void *file_baton,
                         eb->recorded_revision,
                         TRUE, new_actual_props,
                         FALSE /* keep_recorded_info */,
+                        conflict_skel,
                         all_work_items,
                         pool));
 
@@ -1134,19 +1152,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 +1174,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;
 }
 
@@ -1272,6 +1288,7 @@ svn_error_t *
 svn_wc__external_remove(svn_wc_context_t *wc_ctx,
                         const char *wri_abspath,
                         const char *local_abspath,
+                        svn_boolean_t declaration_only,
                         svn_cancel_func_t cancel_func,
                         void *cancel_baton,
                         apr_pool_t *scratch_pool)
@@ -1287,15 +1304,22 @@ 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 (declaration_only)
+    return SVN_NO_ERROR;
+
   if (kind == svn_kind_dir)
     SVN_ERR(svn_wc_remove_from_revision_control2(wc_ctx, local_abspath,
-                                                 TRUE, FALSE,
+                                                 TRUE, TRUE,
                                                  cancel_func, cancel_baton,
                                                  scratch_pool));
   else
     {
-      SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath, scratch_pool));
-      SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
+      SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
+                                     FALSE, SVN_INVALID_REVNUM,
+                                     NULL, NULL, scratch_pool));
+      SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,
+                             cancel_func, cancel_baton,
+                             scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -1530,7 +1554,7 @@ svn_wc__resolve_relative_external_url(co
   /* 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))
+  if (svn_path_is_backpath_present(url))
     return svn_error_createf(SVN_ERR_BAD_URL, 0,
                              _("The external relative URL '%s' cannot have "
                                "backpaths, i.e. '..'"),