subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pbu...@apache.org
Subject svn commit: r1367697 [4/5] - in /subversion/branches/inheritable-props: ./ notes/ notes/directory-index/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/swig/ subversion/bindings/swig/...
Date Tue, 31 Jul 2012 18:05:24 GMT
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=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/externals.c Tue Jul 31 18:05:21 2012
@@ -1288,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)
@@ -1303,9 +1304,12 @@ 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
@@ -1550,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. '..'"),

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=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/lock.c Tue Jul 31 18:05:21 2012
@@ -1529,6 +1529,21 @@ svn_wc__acquire_write_lock(const char **
                              svn_dirent_local_style(local_abspath,
                                                     scratch_pool));
 
+  if (lock_anchor && kind == svn_kind_dir)
+    {
+      svn_boolean_t is_wcroot;
+
+      SVN_ERR_ASSERT(lock_root_abspath != NULL);
+
+      /* Perform a cheap check to avoid looking for a parent working copy,
+         which might be very expensive in some specific scenarios */
+      SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath,
+                                   scratch_pool));
+
+      if (is_wcroot)
+        lock_anchor = FALSE;
+    }
+
   if (lock_anchor)
     {
       const char *parent_abspath;

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=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/merge.c Tue Jul 31 18:05:21 2012
@@ -241,13 +241,11 @@ detranslate_wc_file(const char **detrans
 
   if (force_copy || keywords || eol || special)
     {
-      const char *wcroot_abspath, *temp_dir_abspath;
+      const char *temp_dir_abspath;
       const char *detranslated;
 
       /* Force a copy into the temporary wc area to avoid having
          temporary files created below to appear in the actual wc. */
-      SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath, mt->db, mt->wri_abspath,
-                                    scratch_pool, scratch_pool));
       SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, mt->db,
                                              mt->wri_abspath,
                                              scratch_pool, scratch_pool));
@@ -531,7 +529,8 @@ preserve_pre_merge_files(svn_skel_t **wo
       SVN_ERR(svn_io_copy_file(left_abspath, tmp_left, TRUE, scratch_pool));
 
       /* And create a wq item to remove the file later */
-      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, tmp_left,
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath,
+                                           tmp_left,
                                            result_pool, scratch_pool));
 
       last_items = svn_wc__wq_merge(last_items, work_item, result_pool);
@@ -547,7 +546,8 @@ preserve_pre_merge_files(svn_skel_t **wo
       SVN_ERR(svn_io_copy_file(right_abspath, tmp_right, TRUE, scratch_pool));
 
       /* And create a wq item to remove the file later */
-      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, tmp_right,
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath,
+                                           tmp_right,
                                            result_pool, scratch_pool));
 
       last_items = svn_wc__wq_merge(last_items, work_item, result_pool);
@@ -597,7 +597,7 @@ preserve_pre_merge_files(svn_skel_t **wo
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
   /* And maybe delete some tempfiles */
-  SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db,
+  SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, wcroot_abspath,
                                        detranslated_target_copy,
                                        result_pool, scratch_pool));
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
@@ -626,6 +626,8 @@ merge_file_trivial(svn_skel_t **work_ite
                    const char *detranslated_target_abspath,
                    svn_boolean_t dry_run,
                    svn_wc__db_t *db,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
 {
@@ -670,6 +672,43 @@ merge_file_trivial(svn_skel_t **work_ite
           *merge_outcome = svn_wc_merge_merged;
           if (!dry_run)
             {
+              const char *wcroot_abspath;
+              svn_boolean_t delete_src = FALSE;
+
+              /* The right_abspath might be outside our working copy. In that
+                 case we should copy the file to a safe location before
+                 installing to avoid breaking the workqueue.
+
+                 This matches the behavior in preserve_pre_merge_files */
+
+              SVN_ERR(svn_wc__db_get_wcroot(&wcroot_abspath,
+                                            db, target_abspath,
+                                            scratch_pool, scratch_pool));
+
+              if (!svn_dirent_is_child(wcroot_abspath, right_abspath, NULL))
+                {
+                  svn_stream_t *tmp_src;
+                  svn_stream_t *tmp_dst;
+
+                  SVN_ERR(svn_stream_open_readonly(&tmp_src, right_abspath,
+                                                   scratch_pool,
+                                                   scratch_pool));
+
+                  SVN_ERR(svn_wc__open_writable_base(&tmp_dst, &right_abspath,
+                                                     NULL, NULL,
+                                                     db, target_abspath,
+                                                     scratch_pool,
+                                                     scratch_pool));
+
+                  SVN_ERR(svn_stream_copy3(tmp_src, tmp_dst,
+                                           cancel_func, cancel_baton,
+                                           scratch_pool));
+
+                  /* no need to strdup right_abspath, as the wq_build_()
+                     call already does that for us */
+                  delete_src = TRUE;
+                }
+
               SVN_ERR(svn_wc__wq_build_file_install(
                         &work_item, db, target_abspath, right_abspath,
                         FALSE /* use_commit_times */,
@@ -677,6 +716,16 @@ merge_file_trivial(svn_skel_t **work_ite
                         result_pool, scratch_pool));
               *work_items = svn_wc__wq_merge(*work_items, work_item,
                                              result_pool);
+
+              if (delete_src)
+                {
+                  SVN_ERR(svn_wc__wq_build_file_remove(
+                                    &work_item, db, wcroot_abspath,
+                                    right_abspath,
+                                    result_pool, scratch_pool));
+                  *work_items = svn_wc__wq_merge(*work_items, work_item,
+                                                 result_pool);
+                }
             }
         }
 
@@ -786,9 +835,7 @@ merge_text_file(svn_skel_t **work_items,
                     result_pool, scratch_pool));
           *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
-          /* Track the three conflict files in the metadata.
-           * ### TODO WC-NG: Do this outside the work queue: see
-           * svn_wc__wq_tmp_build_set_text_conflict_markers()'s doc string. */
+          /* Track the conflict marker files in the metadata. */
 
           if (!*conflict_skel)
             *conflict_skel = svn_wc__conflict_skel_create(result_pool);
@@ -842,8 +889,8 @@ merge_text_file(svn_skel_t **work_items,
 
 done:
   /* Remove the tempfile after use */
-  SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                       mt->db, result_target,
+  SVN_ERR(svn_wc__wq_build_file_remove(&work_item, mt->db, mt->local_abspath,
+                                       result_target,
                                        result_pool, scratch_pool));
 
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
@@ -1019,7 +1066,8 @@ svn_wc__internal_merge(svn_skel_t **work
   SVN_ERR(merge_file_trivial(work_items, merge_outcome,
                              left_abspath, right_abspath,
                              target_abspath, detranslated_target_abspath,
-                             dry_run, db, result_pool, scratch_pool));
+                             dry_run, db, cancel_func, cancel_baton,
+                             result_pool, scratch_pool));
   if (*merge_outcome == svn_wc_merge_no_merge)
     {
       if (is_binary)

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/props.c?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/props.c Tue Jul 31 18:05:21 2012
@@ -1208,7 +1208,7 @@ svn_wc__merge_props(svn_skel_t **conflic
   *new_actual_props = NULL;
 
   if (!server_baseprops)
-    server_baseprops = pristine_props;
+    server_baseprops = apr_hash_copy(scratch_pool, pristine_props);
 
   their_props = apr_hash_copy(scratch_pool, server_baseprops);
 
@@ -1228,7 +1228,9 @@ svn_wc__merge_props(svn_skel_t **conflic
       const char *propname;
       svn_boolean_t conflict_remains;
       const svn_prop_t *incoming_change;
-      const svn_string_t *from_val, *to_val, *base_val;
+      const svn_string_t *base_val; /* Pristine in WC */
+      const svn_string_t *from_val; /* Merge left */
+      const svn_string_t *to_val; /* Merge right */
 
       svn_pool_clear(iterpool);
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/status.c?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/status.c Tue Jul 31 18:05:21 2012
@@ -1354,7 +1354,19 @@ get_dir_status(const struct walk_status_
   /* Handle "this-dir" first. */
   if (! skip_this_dir)
     {
-#ifdef HAVE_SYMLINK
+      /* This code is not conditional on HAVE_SYMLINK as some systems that do
+         not allow creating symlinks (!HAVE_SYMLINK) can still encounter
+         symlinks (or in case of Windows also 'Junctions') created by other
+         methods.
+
+         Without this block a working copy in the root of a junction is
+         reported as an obstruction, because the junction itself is reported as
+         special.
+
+         Systems that have no symlink support at all, would always see
+         dirent->special as FALSE, so even there enabling this code shouldn't
+         produce problems.
+       */
       if (dirent->special)
         {
           svn_io_dirent2_t *this_dirent = svn_io_dirent2_dup(dirent, iterpool);
@@ -1375,7 +1387,6 @@ get_dir_status(const struct walk_status_
                                         iterpool));
         }
      else
-#endif
         SVN_ERR(send_status_structure(wb, local_abspath,
                                       parent_repos_root_url,
                                       parent_repos_relpath,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c Tue Jul 31 18:05:21 2012
@@ -286,13 +286,6 @@ struct dir_baton
   /* Absolute path of this directory */
   const char *local_abspath;
 
-  /* Absolute path to the new location of the directory if it was moved away,
-   * and the op-root of the move operation.
-   * This is set on the root of a move operation and all children.
-   * If the directory was not moved away, this is NULL. */
-  const char *moved_to_abspath;
-  const char *moved_to_op_root_abspath;
-
   /* The repository relative path this directory will correspond to. */
   const char *new_relpath;
 
@@ -630,8 +623,6 @@ make_dir_baton(struct dir_baton **d_p,
   d->adding_dir   = adding;
   d->changed_rev  = SVN_INVALID_REVNUM;
   d->not_present_files = apr_hash_make(dir_pool);
-  d->moved_to_abspath = NULL;
-  d->moved_to_op_root_abspath = NULL;
 
   /* Copy some flags from the parent baton */
   if (pb)
@@ -714,10 +705,6 @@ struct file_baton
   /* Absolute path to this file */
   const char *local_abspath;
 
-  /* Absolute path to the new location of the file if it was moved away.
-   * If the file was not moved away, this is NULL. */
-  const char *moved_to_abspath;
-
   /* The repository relative path this file will correspond to. */
   const char *new_relpath;
 
@@ -857,6 +844,56 @@ make_file_baton(struct file_baton **f_p,
   return SVN_NO_ERROR;
 }
 
+/* Complete a conflict skel by describing the update.
+ *
+ * All temporary allocations are be made in SCRATCH_POOL, while allocations
+ * needed for the returned conflict struct are made in RESULT_POOL.
+ */
+static svn_error_t *
+complete_conflict(svn_skel_t *conflict,
+                  const struct dir_baton *pb,
+                  const char *local_abspath,
+                  const char *old_repos_relpath,
+                  svn_revnum_t old_revision,
+                  svn_node_kind_t kind,
+                  apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+  const struct edit_baton *eb = pb->edit_baton;
+  svn_wc_conflict_version_t *src_left_version;
+  svn_boolean_t is_complete;
+
+  if (!conflict)
+    return SVN_NO_ERROR; /* Not conflicted */
+
+  SVN_ERR(svn_wc__conflict_skel_is_complete(&is_complete, conflict));
+
+  if (is_complete)
+    return SVN_NO_ERROR; /* Already competed */
+
+  if (old_repos_relpath)
+    src_left_version = svn_wc_conflict_version_create2(eb->repos_root,
+                                                       eb->repos_uuid,
+                                                       old_repos_relpath,
+                                                       old_revision,
+                                                       kind,
+                                                       result_pool);
+  else
+    src_left_version = NULL;
+
+
+  if (eb->switch_relpath)
+    SVN_ERR(svn_wc__conflict_skel_set_op_switch(conflict,
+                                                src_left_version,
+                                                result_pool, scratch_pool));
+  else
+    SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict,
+                                                src_left_version,
+                                                result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+
 /* Called when a directory is really edited, to avoid marking a
    tree conflict on a node for a no-change edit */
 static svn_error_t *
@@ -873,6 +910,11 @@ mark_directory_edited(struct dir_baton *
   if (db->edit_conflict)
     {
       /* We have a (delayed) tree conflict to install */
+
+      SVN_ERR(complete_conflict(db->edit_conflict, db->parent_baton,
+                                db->local_abspath, db->old_repos_relpath,
+                                db->old_revision, svn_node_dir,
+                                db->pool, scratch_pool));
       SVN_ERR(svn_wc__db_op_mark_conflict(db->edit_baton->db,
                                           db->local_abspath,
                                           db->edit_conflict, NULL,
@@ -901,6 +943,12 @@ mark_file_edited(struct file_baton *fb, 
   if (fb->edit_conflict)
     {
       /* We have a (delayed) tree conflict to install */
+
+      SVN_ERR(complete_conflict(fb->edit_conflict, fb->dir_baton,
+                                fb->local_abspath, fb->old_repos_relpath,
+                                fb->old_revision, svn_node_file,
+                                fb->pool, scratch_pool));
+
       SVN_ERR(svn_wc__db_op_mark_conflict(fb->edit_baton->db,
                                           fb->local_abspath,
                                           fb->edit_conflict, NULL,
@@ -1154,25 +1202,6 @@ open_root(void *edit_baton,
                                                         pool));
     }
 
-  /* Check if this directory was moved away. */
-  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL,
-                             eb->db, db->local_abspath, pool, pool);
-  if (err)
-    {
-      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        svn_error_clear(err);
-      else
-        return svn_error_trace(err);
-    }
-  else if (status == svn_wc__db_status_deleted)
-    SVN_ERR(svn_wc__db_scan_deletion(NULL, &db->moved_to_abspath, NULL,
-                                     &db->moved_to_op_root_abspath,
-                                     eb->db, db->local_abspath, db->pool, pool));
-
   return SVN_NO_ERROR;
 }
 
@@ -1186,6 +1215,7 @@ typedef struct modcheck_baton_t {
   svn_boolean_t found_mod;  /* whether a modification has been found */
   svn_boolean_t found_not_delete;  /* Found a not-delete modification */
   svn_boolean_t is_copy; /* check for post-copy modifications only */
+  const char *modcheck_root_abspath;
 } modcheck_baton_t;
 
 /* An implementation of svn_wc_status_func4_t. */
@@ -1215,10 +1245,19 @@ modcheck_callback(void *baton,
       case svn_wc_status_obstructed:
         if (status->prop_status != svn_wc_status_modified)
           break;
-        /* Fall through in the found modification case */
+
+        mb->found_mod = TRUE;
+        mb->found_not_delete = TRUE;
+        /* Exit from the status walker: We know what we want to know */
+        return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
 
       case svn_wc_status_added:
-        if (!mb->is_copy)
+        /* Ignore the copy status if we expect a copy, but don't ignore
+           other changes */
+        if (!mb->is_copy
+            || status->text_status == svn_wc_status_modified
+            || status->prop_status == svn_wc_status_modified
+            || strcmp(mb->modcheck_root_abspath, local_abspath) != 0)
           {
             mb->found_mod = TRUE;
             mb->found_not_delete = TRUE;
@@ -1262,6 +1301,7 @@ node_has_local_mods(svn_boolean_t *modif
 
   modcheck_baton.db = db;
   modcheck_baton.is_copy = is_copy;
+  modcheck_baton.modcheck_root_abspath = local_abspath;
 
   /* Walk the WC tree for status with depth infinity, looking for any local
    * modifications. If it's a "sparse" directory, that's OK: there can be
@@ -1285,136 +1325,9 @@ node_has_local_mods(svn_boolean_t *modif
   return SVN_NO_ERROR;
 }
 
-
 /* Indicates an unset svn_wc_conflict_reason_t. */
 #define SVN_WC_CONFLICT_REASON_NONE (svn_wc_conflict_reason_t)(-1)
 
-/* Create a tree conflict struct.
- *
- * The REASON is stored directly in the tree conflict info.
- *
- * All temporary allocations are be made in SCRATCH_POOL, while allocations
- * needed for the returned conflict struct are made in RESULT_POOL.
- *
- * All other parameters are identical to and described by
- * check_tree_conflict(), with the slight modification that this function
- * relies on the reason passed in REASON instead of actively looking for one. */
-static svn_error_t *
-create_tree_conflict(svn_skel_t **pconflict,
-                     struct edit_baton *eb,
-                     const char *local_abspath,
-                     svn_wc_conflict_reason_t reason,
-                     svn_wc_conflict_action_t action,
-                     apr_pool_t *result_pool, apr_pool_t *scratch_pool)
-{
-  const char *left_repos_relpath;
-  svn_revnum_t left_revision;
-  svn_node_kind_t left_kind;
-  svn_wc_conflict_version_t *src_left_version;
-
-  *pconflict = NULL;
-
-  SVN_ERR_ASSERT(reason != SVN_WC_CONFLICT_REASON_NONE);
-
-  /* Get the source-left information, i.e. the local state of the node
-   * before any changes were made to the working copy, i.e. the state the
-   * node would have if it was reverted. */
-  if (reason == svn_wc_conflict_reason_added ||
-      reason == svn_wc_conflict_reason_moved_here)
-    {
-      /* ###TODO: It would be nice to tell the user at which URL and
-       * ### revision source-left was empty, which could be quite difficult
-       * ### to code, and is a slight theoretical leap of the svn mind.
-       * ### Update should show
-       * ###   URL: svn_wc__db_scan_addition( &repos_relpath )
-       * ###   REV: The base revision of the parent of before this update
-       * ###        started
-       * ###        ### BUT what if parent was updated/switched away with
-       * ###        ### depth=empty after this node was added?
-       * ### Switch should show
-       * ###   URL: scan_addition URL of before this switch started
-       * ###   REV: same as above */
-
-      /* In case of a local addition, source-left is non-existent / empty. */
-      left_kind = svn_node_none;
-      left_revision = SVN_INVALID_REVNUM;
-      left_repos_relpath = NULL;
-    }
-  else if (reason == svn_wc_conflict_reason_unversioned)
-    {
-      /* Obstructed by an unversioned node. Source-left is
-       * non-existent/empty. */
-      left_kind = svn_node_none;
-      left_revision = SVN_INVALID_REVNUM;
-      left_repos_relpath = NULL;
-    }
-  else
-    {
-      /* A BASE node should exist. */
-      svn_kind_t base_kind;
-
-      /* If anything else shows up, then this assertion is probably naive
-       * and that other case should also be handled. */
-      SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_edited
-                     || reason == svn_wc_conflict_reason_deleted
-                     || reason == svn_wc_conflict_reason_moved_away
-                     || reason == svn_wc_conflict_reason_moved_away_and_edited
-                     || reason == svn_wc_conflict_reason_replaced
-                     || reason == svn_wc_conflict_reason_obstructed);
-
-      SVN_ERR(svn_wc__db_base_get_info(NULL, &base_kind,
-                                       &left_revision,
-                                       &left_repos_relpath,
-                                       NULL, NULL,
-                                       NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, NULL, NULL,
-                                       eb->db, local_abspath,
-                                       result_pool, scratch_pool));
-      /* Translate the node kind. */
-      if (base_kind == svn_kind_file
-          || base_kind == svn_kind_symlink)
-        left_kind = svn_node_file;
-      else if (base_kind == svn_kind_dir)
-        left_kind = svn_node_dir;
-      else
-        SVN_ERR_MALFUNCTION();
-    }
-
-  /* Construct the tree conflict info structs. */
-
-  if (left_repos_relpath == NULL)
-    /* A locally added or unversioned path in conflict with an incoming add.
-     * Send an 'empty' left revision. */
-    src_left_version = NULL;
-  else
-    src_left_version = svn_wc_conflict_version_create2(eb->repos_root,
-                                                       eb->repos_uuid,
-                                                       left_repos_relpath,
-                                                       left_revision,
-                                                       left_kind,
-                                                       result_pool);
-
-  *pconflict = svn_wc__conflict_skel_create(result_pool);
-
-  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(*pconflict,
-                                                  eb->db, local_abspath,
-                                                  reason,
-                                                  action,
-                                                  result_pool, scratch_pool));
-
-  if (eb->switch_relpath)
-    SVN_ERR(svn_wc__conflict_skel_set_op_switch(*pconflict,
-                                                src_left_version,
-                                                result_pool, scratch_pool));
-  else
-    SVN_ERR(svn_wc__conflict_skel_set_op_update(*pconflict,
-                                                src_left_version,
-                                                result_pool, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Check whether the incoming change ACTION on FULL_PATH would conflict with
  * LOCAL_ABSPATH's scheduled change. If so, then raise a tree conflict with
  * LOCAL_ABSPATH as the victim.
@@ -1431,7 +1344,7 @@ create_tree_conflict(svn_skel_t **pconfl
  * while *PCONFLICT is always overwritten.
  *
  * The tree conflict is allocated in RESULT_POOL. Temporary allocations use
- * SCRACTH_POOl.
+ * SCRATCH_POOL.
  */
 static svn_error_t *
 check_tree_conflict(svn_skel_t **pconflict,
@@ -1441,12 +1354,10 @@ check_tree_conflict(svn_skel_t **pconfli
                     svn_kind_t working_kind,
                     svn_boolean_t exists_in_repos,
                     svn_wc_conflict_action_t action,
-                    const char *moved_to_abspath,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
   svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE;
-  svn_boolean_t locally_replaced = FALSE;
   svn_boolean_t modified = FALSE;
   svn_boolean_t all_mods_are_deletes = FALSE;
 
@@ -1459,21 +1370,7 @@ check_tree_conflict(svn_skel_t **pconfli
       case svn_wc__db_status_added:
       case svn_wc__db_status_moved_here:
       case svn_wc__db_status_copied:
-        /* Is it a replace? */
-        if (exists_in_repos)
-          {
-            svn_wc__db_status_t base_status;
-            SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL,
-                                             NULL, NULL, NULL, NULL, NULL,
-                                             NULL, NULL, NULL, NULL, NULL,
-                                             NULL, NULL,
-                                             eb->db, local_abspath,
-                                             scratch_pool, scratch_pool));
-            if (base_status != svn_wc__db_status_not_present)
-              locally_replaced = TRUE;
-          }
-
-        if (!locally_replaced)
+        if (!exists_in_repos)
           {
             /* The node is locally added, and it did not exist before.  This
              * is an 'update', so the local add can only conflict with an
@@ -1507,28 +1404,7 @@ check_tree_conflict(svn_skel_t **pconfli
 
 
       case svn_wc__db_status_deleted:
-        if (!moved_to_abspath)
-          reason = svn_wc_conflict_reason_deleted;
-        else if (action == svn_wc_conflict_action_delete)
-          {
-            svn_boolean_t all_edits_are_deletes = FALSE;
-
-            /* The update wants to delete a node which was locally moved
-             * away. We allow this only if the node wasn't modified post-move.
-             * If the only post-move changes within a subtree are deletions,
-             * allow the update to delete the entire subtree. */
-            if (working_kind == svn_kind_dir)
-              SVN_ERR(node_has_local_mods(&modified, &all_edits_are_deletes,
-                                          TRUE, eb->db, moved_to_abspath,
-                                          eb->cancel_func, eb->cancel_baton,
-                                          scratch_pool));
-            else
-              SVN_ERR(svn_wc__internal_file_modified_p(&modified, eb->db,
-                                                       moved_to_abspath,
-                                                       FALSE, scratch_pool));
-            if (modified && !all_edits_are_deletes)
-              reason = svn_wc_conflict_reason_moved_away_and_edited;
-          }
+        reason = svn_wc_conflict_reason_deleted;
         break;
 
       case svn_wc__db_status_incomplete:
@@ -1545,6 +1421,10 @@ check_tree_conflict(svn_skel_t **pconfli
            * but we don't handle those here.) */
           return SVN_NO_ERROR;
 
+        /* Replace is handled as delete and then specifically in
+           add_directory() and add_file(), so we only expect deletes here */
+        SVN_ERR_ASSERT(action == svn_wc_conflict_action_delete);
+
         /* Check if the update wants to delete or replace a locally
          * modified node. */
 
@@ -1609,11 +1489,16 @@ check_tree_conflict(svn_skel_t **pconfli
     SVN_ERR_ASSERT(action == svn_wc_conflict_action_add);
 
 
-  /* A conflict was detected. Append log commands to the log accumulator
-   * to record it. */
-  return svn_error_trace(create_tree_conflict(pconflict, eb, local_abspath,
-                                              reason, action,
-                                              result_pool, scratch_pool));
+  /* A conflict was detected. Create a conflict skel to record it. */
+  *pconflict = svn_wc__conflict_skel_create(result_pool);
+
+  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(*pconflict,
+                                                  eb->db, local_abspath,
+                                                  reason,
+                                                  action,
+                                                  result_pool, scratch_pool));
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -1695,10 +1580,9 @@ delete_entry(const char *path,
   const char *base = svn_relpath_basename(path, NULL);
   const char *local_abspath;
   const char *repos_relpath;
-  const char *moved_to_abspath = NULL;
   svn_kind_t kind, base_kind;
+  svn_revnum_t old_revision;
   svn_boolean_t conflicted;
-  svn_boolean_t have_base;
   svn_boolean_t have_work;
   svn_skel_t *tree_conflict = NULL;
   svn_wc__db_status_t status;
@@ -1739,11 +1623,11 @@ delete_entry(const char *path,
       }
   }
 
-  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, &repos_relpath, NULL, NULL,
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, &old_revision, &repos_relpath,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
-                               NULL, NULL, NULL,
-                               &have_base, NULL, &have_work,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               &conflicted, NULL, NULL, NULL,
+                               NULL, NULL, &have_work,
                                eb->db, local_abspath,
                                scratch_pool, scratch_pool));
 
@@ -1753,7 +1637,7 @@ delete_entry(const char *path,
       base_kind = kind;
     }
   else
-    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, NULL,
+    SVN_ERR(svn_wc__db_base_get_info(&base_status, &base_kind, &old_revision,
                                      &repos_relpath,
                                      NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                      NULL, NULL, NULL, NULL,
@@ -1798,13 +1682,6 @@ delete_entry(const char *path,
       return SVN_NO_ERROR;
     }
 
-  /* Has the to-be-deleted node been moved away? */
-  if (status == svn_wc__db_status_deleted)
-    SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath, NULL,
-                                     NULL, eb->db, local_abspath,
-                                     pool, pool));
-
-
   /* Is this path the victim of a newly-discovered tree conflict?  If so,
    * remember it and notify the client. Then (if it was existing and
    * modified), re-schedule the node to be added back again, as a (modified)
@@ -1817,7 +1694,7 @@ delete_entry(const char *path,
       SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                   status, kind, TRUE,
                                   svn_wc_conflict_action_delete,
-                                  moved_to_abspath, pb->pool, scratch_pool));
+                                  pb->pool, scratch_pool));
     }
 
   if (tree_conflict != NULL)
@@ -1865,24 +1742,13 @@ delete_entry(const char *path,
       else
         SVN_ERR_MALFUNCTION();  /* other reasons are not expected here */
     }
-  else if (moved_to_abspath)
-    {
-      /* No tree conflict was flagged, and the node was moved-away.
-       * Automatically merge the incoming deletion with the local move
-       * by deleting the node from the moved-away subtree. */
-      /* ### This should probably use a work queue. */
-      SVN_ERR(svn_wc__db_op_delete(eb->db, moved_to_abspath, NULL,
-                                   NULL, NULL,
-                                   eb->cancel_func, eb->cancel_baton,
-                                   NULL, NULL, /* notify below */
-                                   scratch_pool));
-      if (kind == svn_kind_dir)
-        SVN_ERR(svn_io_remove_dir2(moved_to_abspath, TRUE,
-                                   eb->cancel_func, eb->cancel_baton,
-                                   scratch_pool));
-      else
-        SVN_ERR(svn_io_remove_file2(moved_to_abspath, TRUE, scratch_pool));
-    }
+
+  SVN_ERR(complete_conflict(tree_conflict, pb, local_abspath, repos_relpath,
+                            old_revision,
+                            (kind == svn_kind_dir)
+                                ? svn_node_dir
+                                : svn_node_file,
+                            pb->pool, scratch_pool));
 
   /* Issue a wq operation to delete the BASE_NODE data and to delete actual
      nodes based on that from disk, but leave any WORKING_NODEs on disk.
@@ -1931,8 +1797,7 @@ delete_entry(const char *path,
       else
         node_kind = svn_node_file;
 
-      do_notification(eb, moved_to_abspath ? moved_to_abspath : local_abspath,
-                      node_kind, action, scratch_pool);
+      do_notification(eb, local_abspath, node_kind, action, scratch_pool);
     }
 
   svn_pool_destroy(scratch_pool);
@@ -2108,11 +1973,10 @@ add_directory(const char *path,
 
           /* And now stop checking for conflicts here and just perform
              a shadowed update */
+          db->edit_conflict = tree_conflict; /* Cache for close_directory */
           tree_conflict = NULL; /* No direct notification */
           db->shadowed = TRUE; /* Just continue */
           conflicted = FALSE; /* No skip */
-
-          db->edit_conflict = tree_conflict; /* Cache for close_directory */
         }
       else
         SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -2202,7 +2066,7 @@ add_directory(const char *path,
                                       db->local_abspath,
                                       status, wc_kind, FALSE,
                                       svn_wc_conflict_action_add,
-                                      NULL, pool, pool));
+                                      pool, pool));
         }
 
       if (tree_conflict == NULL)
@@ -2223,15 +2087,22 @@ add_directory(const char *path,
           db->shadowed = TRUE;
 
           /* Mark a conflict */
-          SVN_ERR(create_tree_conflict(&tree_conflict, eb,
-                                       db->local_abspath,
-                                       svn_wc_conflict_reason_unversioned,
-                                       svn_wc_conflict_action_add,
-                                       pool, pool));
-          SVN_ERR_ASSERT(tree_conflict != NULL);
+          tree_conflict = svn_wc__conflict_skel_create(db->pool);
+
+          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+                                        tree_conflict,
+                                        eb->db, db->local_abspath,
+                                        svn_wc_conflict_reason_unversioned,
+                                        svn_wc_conflict_action_add,
+                                        db->pool, pool));
+          db->edit_conflict = tree_conflict;
         }
     }
 
+  SVN_ERR(complete_conflict(tree_conflict, pb, db->local_abspath,
+                            db->old_repos_relpath, db->old_revision,
+                            svn_node_dir, db->pool, pool));
+
   SVN_ERR(svn_wc__db_base_add_incomplete_directory(
                                      eb->db, db->local_abspath,
                                      db->new_relpath,
@@ -2246,8 +2117,8 @@ add_directory(const char *path,
                                      pool));
 
   /* Make sure there is a real directory at LOCAL_ABSPATH, unless we are just
-     updating the DB or the parent was moved away. */
-  if (!db->shadowed && !pb->moved_to_abspath)
+     updating the DB */
+  if (!db->shadowed)
     SVN_ERR(svn_wc__ensure_directory(db->local_abspath, pool));
 
   if (tree_conflict != NULL)
@@ -2256,17 +2127,6 @@ add_directory(const char *path,
       do_notification(eb, db->local_abspath, svn_node_dir,
                       svn_wc_notify_tree_conflict, pool);
     }
-  else if (wc_kind == svn_kind_unknown &&
-           versioned_locally_and_present == FALSE &&
-           pb->moved_to_abspath)
-    {
-      /* The parent directory of the directory we're adding was moved.
-       * Add the new directory at the new location. */
-      db->moved_to_abspath = svn_dirent_join(pb->moved_to_abspath,
-                                             db->name, db->pool);
-      db->moved_to_op_root_abspath = pb->moved_to_op_root_abspath;
-    }
-
 
 
   /* If this add was obstructed by dir scheduled for addition without
@@ -2287,9 +2147,7 @@ add_directory(const char *path,
 
       db->already_notified = TRUE;
 
-      do_notification(eb, db->moved_to_abspath ? db->moved_to_abspath
-                                               : db->local_abspath,
-                      svn_node_dir, action, pool);
+      do_notification(eb, db->local_abspath, svn_node_dir, action, pool);
     }
 
   return SVN_NO_ERROR;
@@ -2310,7 +2168,6 @@ open_directory(const char *path,
   svn_skel_t *tree_conflict = NULL;
   svn_wc__db_status_t status, base_status;
   svn_kind_t wc_kind;
-  svn_error_t *err;
 
   SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
   *child_baton = db;
@@ -2386,33 +2243,13 @@ open_directory(const char *path,
   /* Is this path a fresh tree conflict victim?  If so, skip the tree
      with one notification. */
 
-  /* Check if this directory was moved away. */
-  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL,
-                             eb->db, db->local_abspath, pool, pool);
-  if (err)
-    {
-      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-        svn_error_clear(err);
-      else
-        return svn_error_trace(err);
-    }
-  else if (status == svn_wc__db_status_deleted)
-    SVN_ERR(svn_wc__db_scan_deletion(NULL, &db->moved_to_abspath, NULL,
-                                     &db->moved_to_op_root_abspath,
-                                     eb->db, db->local_abspath,
-                                     db->pool, pool));
-
   /* Check for conflicts only when we haven't already recorded
    * a tree-conflict on a parent node. */
   if (!db->shadowed)
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit,
-                                db->moved_to_abspath, db->pool, pool));
+                                db->pool, pool));
 
   /* Remember the roots of any locally deleted trees. */
   if (tree_conflict != NULL)
@@ -2834,41 +2671,14 @@ close_directory(void *dir_baton,
       if (conflict_skel)
         {
           svn_skel_t *work_item;
-          svn_boolean_t completed;
 
-          SVN_ERR(svn_wc__conflict_skel_is_complete(&completed,
-                                                    conflict_skel));
-
-          if (completed)
-            {
-              /* Avoid assertion */
-            }
-          else if (eb->switch_relpath)
-            SVN_ERR(svn_wc__conflict_skel_set_op_switch(
-                        conflict_skel,
-                        db->adding_dir
-                            ? NULL
-                            : svn_wc_conflict_version_create2(
-                                            eb->repos_root,
-                                            eb->repos_uuid,
-                                            db->old_repos_relpath,
-                                            db->old_revision,
-                                            svn_node_dir,
-                                            scratch_pool),
-                        db->pool, db->pool));
-          else
-            SVN_ERR(svn_wc__conflict_skel_set_op_update(
-                        conflict_skel,
-                        db->adding_dir
-                            ? NULL
-                            : svn_wc_conflict_version_create2(
-                                            eb->repos_root,
-                                            eb->repos_uuid,
-                                            db->old_repos_relpath,
-                                            db->old_revision,
-                                            svn_node_dir,
-                                            scratch_pool),
-                        db->pool, db->pool));
+          SVN_ERR(complete_conflict(conflict_skel,
+                                    db->parent_baton,
+                                    db->local_abspath,
+                                    db->old_repos_relpath,
+                                    db->old_revision,
+                                    svn_node_dir,
+                                    db->pool, scratch_pool));
 
           SVN_ERR(svn_wc__conflict_create_markers(&work_item,
                                                   eb->db, db->local_abspath,
@@ -2899,41 +2709,6 @@ close_directory(void *dir_baton,
                 new_actual_props,
                 all_work_items,
                 scratch_pool));
-
-      if (db->moved_to_abspath)
-        {
-          /* Perform another in-DB move of the directory to sync meta-data
-           * of the moved-away node with the new BASE node. */
-          apr_array_header_t *children = NULL;
-          apr_hash_t *children_hash = apr_hash_get(eb->dir_dirents,
-                                                   db->new_relpath,
-                                                   APR_HASH_KEY_STRING);
-          /* The op-root of the move needs to retain its moved-here flag.
-           * Its children are normal copied children. */
-          svn_boolean_t is_move = (strcmp(db->moved_to_op_root_abspath,
-                                          db->moved_to_abspath) == 0);
-
-          /* Add the new directory as a copy and create it on disk. */
-          if (children_hash)
-            SVN_ERR(svn_hash_keys(&children, children_hash, scratch_pool));
-          SVN_ERR(svn_wc__db_op_copy_dir(eb->db, db->moved_to_abspath,
-                                         new_actual_props ? new_actual_props
-                                                          : actual_props,
-                                         db->changed_rev,
-                                         db->changed_date,
-                                         db->changed_author,
-                                         db->new_relpath,
-                                         eb->repos_root,
-                                         eb->repos_uuid,
-                                         *eb->target_revision,
-                                         children,
-                                         is_move,
-                                         db->ambient_depth,
-                                         NULL /* conflict */,
-                                         NULL, /* no work, just modify DB */
-                                         scratch_pool));
-          SVN_ERR(svn_wc__ensure_directory(db->moved_to_abspath, pool));
-        }
     }
 
   /* Process all of the queued work items for this directory.  */
@@ -3261,11 +3036,10 @@ add_file(const char *path,
 
           /* And now stop checking for conflicts here and just perform
              a shadowed update */
+          fb->edit_conflict = tree_conflict; /* Cache for close_file */
           tree_conflict = NULL; /* No direct notification */
           fb->shadowed = TRUE; /* Just continue */
           conflicted = FALSE; /* No skip */
-
-          fb->edit_conflict = tree_conflict; /* Cache for close_file */
         }
       else
         SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -3350,7 +3124,7 @@ add_file(const char *path,
           SVN_ERR(check_tree_conflict(&tree_conflict, eb,
                                       fb->local_abspath,
                                       status, wc_kind, FALSE,
-                                      svn_wc_conflict_action_add, NULL,
+                                      svn_wc_conflict_action_add,
                                       scratch_pool, scratch_pool));
         }
 
@@ -3373,12 +3147,14 @@ add_file(const char *path,
           fb->shadowed = TRUE;
 
           /* Mark a conflict */
-          SVN_ERR(create_tree_conflict(&tree_conflict, eb,
-                                       fb->local_abspath,
-                                       svn_wc_conflict_reason_unversioned,
-                                       svn_wc_conflict_action_add,
-                                       scratch_pool, scratch_pool));
-          SVN_ERR_ASSERT(tree_conflict != NULL);
+          tree_conflict = svn_wc__conflict_skel_create(fb->pool);
+
+          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+                                        tree_conflict,
+                                        eb->db, fb->local_abspath,
+                                        svn_wc_conflict_reason_unversioned,
+                                        svn_wc_conflict_action_add,
+                                        fb->pool, scratch_pool));
         }
     }
 
@@ -3395,6 +3171,14 @@ add_file(const char *path,
 
   if (tree_conflict != NULL)
     {
+      SVN_ERR(complete_conflict(tree_conflict,
+                                fb->dir_baton,
+                                fb->local_abspath,
+                                fb->old_repos_relpath,
+                                fb->old_revision,
+                                svn_node_file,
+                                fb->pool, scratch_pool));
+
       SVN_ERR(svn_wc__db_op_mark_conflict(eb->db,
                                           fb->local_abspath,
                                           tree_conflict, NULL,
@@ -3404,15 +3188,6 @@ add_file(const char *path,
       do_notification(eb, fb->local_abspath, svn_node_file,
                       svn_wc_notify_tree_conflict, scratch_pool);
     }
-  else if (wc_kind == svn_kind_unknown &&
-           versioned_locally_and_present == FALSE &&
-           pb->moved_to_abspath)
-    {
-      /* The parent directory of the file we're adding was moved.
-       * Add the new file at the new location. */
-      fb->moved_to_abspath = svn_dirent_join(pb->moved_to_abspath,
-                                             fb->name, fb->pool);
-    }
 
   svn_pool_destroy(scratch_pool);
 
@@ -3492,12 +3267,6 @@ open_file(const char *path,
                                      eb->db, fb->local_abspath,
                                      fb->pool, scratch_pool));
 
-  /* If the file has moved locally look up its new location. */
-  if (status == svn_wc__db_status_deleted)
-    SVN_ERR(svn_wc__db_scan_deletion(NULL, &fb->moved_to_abspath, NULL, NULL,
-                                     eb->db, fb->local_abspath,
-                                     fb->pool, scratch_pool));
-
   /* Is this path a conflict victim? */
   if (conflicted)
     SVN_ERR(node_already_conflicted(&conflicted, eb->db,
@@ -3525,7 +3294,7 @@ open_file(const char *path,
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, fb->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit,
-                                fb->moved_to_abspath, fb->pool, scratch_pool));
+                                fb->pool, scratch_pool));
 
   /* Is this path the victim of a newly-discovered tree conflict? */
   if (tree_conflict != NULL)
@@ -3806,7 +3575,6 @@ svn_wc__perform_file_merge(svn_skel_t **
   /* Merge the changes from the old textbase to the new
      textbase into the file we're updating.
      Remember that this function wants full paths! */
-  /* ### TODO: Pass version info here. */
   SVN_ERR(svn_wc__internal_merge(&work_item,
                                  conflict_skel,
                                  merge_outcome,
@@ -3827,7 +3595,8 @@ svn_wc__perform_file_merge(svn_skel_t **
   /* If we created a temporary left merge file, get rid of it. */
   if (delete_left)
     {
-      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, merge_left,
+      SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, wri_abspath,
+                                           merge_left,
                                            result_pool, scratch_pool));
       *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
     }
@@ -3874,8 +3643,6 @@ merge_file(svn_skel_t **work_items,
   struct dir_baton *pb = fb->dir_baton;
   svn_boolean_t is_locally_modified;
   enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
-  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
-                                                     : fb->local_abspath;
 
   SVN_ERR_ASSERT(! fb->shadowed && !fb->obstruction_found);
 
@@ -3920,7 +3687,7 @@ merge_file(svn_skel_t **work_items,
          files that do not exist and for directories. */
 
       SVN_ERR(svn_wc__internal_file_modified_p(&is_locally_modified,
-                                               eb->db, working_abspath,
+                                               eb->db, fb->local_abspath,
                                                FALSE /* exact_comparison */,
                                                scratch_pool));
     }
@@ -3965,7 +3732,7 @@ merge_file(svn_skel_t **work_items,
                                          conflict_skel,
                                          &merge_outcome,
                                          eb->db,
-                                         working_abspath,
+                                         fb->local_abspath,
                                          pb->local_abspath,
                                          fb->new_text_base_sha1_checksum,
                                          fb->add_existed
@@ -3996,7 +3763,7 @@ merge_file(svn_skel_t **work_items,
       SVN_ERR(svn_wc__get_translate_info(NULL, NULL,
                                          &keywords,
                                          NULL,
-                                         eb->db, working_abspath,
+                                         eb->db, fb->local_abspath,
                                          actual_props, TRUE,
                                          scratch_pool, scratch_pool));
       if (magic_props_changed || keywords)
@@ -4016,7 +3783,7 @@ merge_file(svn_skel_t **work_items,
               /* Copy and DEtranslate the working file to a temp text-base.
                  Note that detranslation is done according to the old props. */
               SVN_ERR(svn_wc__internal_translated_file(
-                        &tmptext, working_abspath, eb->db, working_abspath,
+                        &tmptext, fb->local_abspath, eb->db, fb->local_abspath,
                         SVN_WC_TRANSLATE_TO_NF
                           | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
                         eb->cancel_func, eb->cancel_baton,
@@ -4095,8 +3862,6 @@ close_file(void *file_baton,
   apr_pool_t *scratch_pool = fb->pool; /* Destroyed at function exit */
   svn_boolean_t keep_recorded_info = FALSE;
   const svn_checksum_t *new_checksum;
-  const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
-                                                     : fb->local_abspath;
 
   if (fb->skip_this)
     {
@@ -4190,7 +3955,7 @@ close_file(void *file_baton,
   if ((!fb->adding_file || fb->add_existed)
       && !fb->shadowed)
     SVN_ERR(svn_wc__get_actual_props(&local_actual_props,
-                                     eb->db, working_abspath,
+                                     eb->db, fb->local_abspath,
                                      scratch_pool, scratch_pool));
   if (local_actual_props == NULL)
     local_actual_props = apr_hash_make(scratch_pool);
@@ -4295,7 +4060,7 @@ close_file(void *file_baton,
                                   &new_base_props,
                                   &new_actual_props,
                                   eb->db,
-                                  working_abspath,
+                                  fb->local_abspath,
                                   svn_kind_file,
                                   NULL /* server_baseprops (update, not merge)  */,
                                   current_base_props,
@@ -4323,7 +4088,7 @@ close_file(void *file_baton,
               if (eb->notify_func)
                 {
                   svn_wc_notify_t *notify =svn_wc_create_notify(
-                                working_abspath,
+                                fb->local_abspath,
                                 svn_wc_notify_update_skip_access_denied,
                                 scratch_pool);
 
@@ -4370,7 +4135,7 @@ close_file(void *file_baton,
 
           SVN_ERR(svn_wc__wq_build_file_install(&work_item,
                                                 eb->db,
-                                                working_abspath,
+                                                fb->local_abspath,
                                                 install_from,
                                                 eb->use_commit_times,
                                                 record_fileinfo,
@@ -4386,7 +4151,7 @@ close_file(void *file_baton,
 
              Note: this will also update the executable flag, but ... meh.  */
           SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, eb->db,
-                                                   working_abspath,
+                                                   fb->local_abspath,
                                                    scratch_pool, scratch_pool));
           all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                             scratch_pool);
@@ -4404,10 +4169,10 @@ close_file(void *file_baton,
       /* Remove the INSTALL_FROM file, as long as it doesn't refer to the
          working file.  */
       if (install_from != NULL
-          && strcmp(install_from, working_abspath) != 0)
+          && strcmp(install_from, fb->local_abspath) != 0)
         {
           SVN_ERR(svn_wc__wq_build_file_remove(&work_item, eb->db,
-                                               install_from,
+                                               fb->local_abspath, install_from,
                                                scratch_pool, scratch_pool));
           all_work_items = svn_wc__wq_merge(all_work_items, work_item,
                                             scratch_pool);
@@ -4462,39 +4227,13 @@ close_file(void *file_baton,
 
   if (conflict_skel)
     {
-      svn_boolean_t completed;
-
-      SVN_ERR(svn_wc__conflict_skel_is_complete(&completed,
-                                                    conflict_skel));
-
-      if (completed)
-        {
-          /* Avoid assertion */
-        }
-      else if (eb->switch_relpath)
-        SVN_ERR(svn_wc__conflict_skel_set_op_switch(
-                    conflict_skel,
-                    fb->adding_file
-                      ? NULL
-                      : svn_wc_conflict_version_create2(eb->repos_root,
-                                                        eb->repos_uuid,
-                                                        fb->old_repos_relpath,
-                                                        fb->old_revision,
-                                                        svn_node_file,
-                                                        fb->pool),
-                    fb->pool, fb->pool));
-      else
-        SVN_ERR(svn_wc__conflict_skel_set_op_update(
-                    conflict_skel,
-                    fb->adding_file
-                      ? NULL
-                      : svn_wc_conflict_version_create2(eb->repos_root,
-                                                        eb->repos_uuid,
-                                                        fb->old_repos_relpath,
-                                                        fb->old_revision,
-                                                        svn_node_file,
-                                                        fb->pool),
-                    fb->pool, fb->pool));
+      SVN_ERR(complete_conflict(conflict_skel,
+                                fb->dir_baton,
+                                fb->local_abspath,
+                                fb->old_repos_relpath,
+                                fb->old_revision,
+                                svn_node_file,
+                                fb->pool, scratch_pool));
 
       SVN_ERR(svn_wc__conflict_create_markers(&work_item,
                                               eb->db, fb->local_abspath,
@@ -4539,28 +4278,6 @@ close_file(void *file_baton,
 
   /* Deal with the WORKING tree, based on updates to the BASE tree.  */
 
-  if (fb->moved_to_abspath)
-    {
-      /* Perform another in-DB move of the file to sync meta-data
-       * of the moved-away node with the new BASE node. */
-      SVN_ERR(svn_wc__db_op_copy_file(eb->db, fb->moved_to_abspath,
-                                      new_actual_props,
-                                      fb->changed_rev,
-                                      fb->changed_date,
-                                      fb->changed_author,
-                                      fb->new_relpath,
-                                      eb->repos_root,
-                                      eb->repos_uuid,
-                                      *eb->target_revision,
-                                      new_checksum,
-                                      FALSE /* update_actual_props */,
-                                      NULL /* new_actual_props */,
-                                      TRUE /* is_move */,
-                                      NULL /* conflict */,
-                                      NULL, /* no work, just modify DB */
-                                      scratch_pool));
-    }
-
   apr_hash_set(fb->dir_baton->not_present_files, fb->name,
                APR_HASH_KEY_STRING, NULL);
 
@@ -4597,7 +4314,7 @@ close_file(void *file_baton,
       /* If the file was moved-away, notify for the moved-away node.
        * The original location only had its BASE info changed and
        * we don't usually notify about such changes. */
-      notify = svn_wc_create_notify(working_abspath, action, scratch_pool);
+      notify = svn_wc_create_notify(fb->local_abspath, action, scratch_pool);
       notify->kind = svn_node_file;
       notify->content_state = content_state;
       notify->prop_state = prop_state;
@@ -5672,8 +5389,8 @@ svn_wc_add_repos_file4(svn_wc_context_t 
        it is a temporary file, which needs to be removed.  */
     if (source_abspath != NULL)
       {
-        SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                             db, source_abspath,
+        SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, local_abspath,
+                                             source_abspath,
                                              pool, pool));
         all_work_items = svn_wc__wq_merge(all_work_items, work_item, pool);
       }

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql Tue Jul 31 18:05:21 2012
@@ -163,6 +163,28 @@ WHERE wc_id = ?1 AND IS_STRICT_DESCENDAN
                    AND op_depth > 0)
 ORDER BY local_relpath DESC
 
+-- STMT_SELECT_WORKING_PRESENT
+SELECT local_relpath, kind, checksum, translated_size, last_mod_time
+FROM nodes n
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND presence in ('normal', 'incomplete')
+  AND op_depth = (SELECT MAX(op_depth)
+                  FROM NODES w
+                  WHERE w.wc_id = ?1
+                    AND w.local_relpath = n.local_relpath)
+ORDER BY local_relpath DESC
+
+-- STMT_DELETE_NODE_RECURSIVE
+DELETE FROM NODES
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+
+-- STMT_DELETE_NODE
+DELETE
+FROM NODES
+WHERE wc_id = ?1 AND local_relpath = ?2
+
 -- STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE
 /* The ACTUAL_NODE applies to BASE, unless there is in at least one op_depth
    a WORKING node that could have a conflict */
@@ -968,6 +990,24 @@ SELECT presence, kind, def_local_relpath
 FROM externals WHERE wc_id = ?1 AND local_relpath = ?2
 LIMIT 1
 
+-- STMT_DELETE_FILE_EXTERNALS
+DELETE FROM nodes
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND op_depth = 0
+  AND file_external IS NOT NULL
+
+-- STMT_DELETE_FILE_EXTERNAL_REGISTATIONS
+DELETE FROM externals
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND kind != 'dir'
+
+-- STMT_DELETE_EXTERNAL_REGISTATIONS
+DELETE FROM externals
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+
 /* Select all committable externals, i.e. only unpegged ones on the same
  * repository as the target path ?2, that are defined by WC ?1 to
  * live below the target path. It does not matter which ancestor has the

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc.h?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc.h Tue Jul 31 18:05:21 2012
@@ -564,7 +564,6 @@ svn_error_t *
 svn_wc__internal_remove_from_revision_control(svn_wc__db_t *db,
                                               const char *local_abspath,
                                               svn_boolean_t destroy_wf,
-                                              svn_boolean_t instant_error,
                                               svn_cancel_func_t cancel_func,
                                               void *cancel_baton,
                                               apr_pool_t *scratch_pool);

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.c Tue Jul 31 18:05:21 2012
@@ -2172,7 +2172,7 @@ db_base_remove(void *baton,
               else
                 SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
                                                      rb->db,
-                                                     /* wcroot->abspath, */
+                                                     wcroot->abspath,
                                                      node_abspath,
                                                      iterpool, iterpool));
 
@@ -2191,7 +2191,7 @@ db_base_remove(void *baton,
         }
       else
         SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
-                                             rb->db, /* wcroot->abspath, */
+                                             rb->db, wcroot->abspath,
                                              local_abspath,
                                              scratch_pool, scratch_pool));
 
@@ -6264,7 +6264,7 @@ svn_wc__db_op_revert(svn_wc__db_t *db,
 
 struct revert_list_read_baton {
   svn_boolean_t *reverted;
-  const apr_array_header_t *marker_paths;
+  apr_array_header_t *marker_paths;
   svn_boolean_t *copied_here;
   svn_kind_t *kind;
   apr_pool_t *result_pool;
@@ -6546,8 +6546,17 @@ svn_wc__db_revert_list_done(svn_wc__db_t
 /* Baton for remove_node_txn */
 struct remove_node_baton
 {
+  svn_wc__db_t *db;
+  svn_boolean_t left_changes;
+  svn_boolean_t destroy_wc;
+  svn_boolean_t destroy_changes;
   svn_revnum_t not_present_rev;
+  svn_wc__db_status_t not_present_status;
   svn_kind_t not_present_kind;
+  const svn_skel_t *conflict;
+  const svn_skel_t *work_items;
+  svn_cancel_func_t cancel_func;
+  void *cancel_baton;
 };
 
 /* Implements svn_wc__db_txn_callback_t for svn_wc__db_op_remove_node */
@@ -6563,7 +6572,11 @@ remove_node_txn(void *baton,
   apr_int64_t repos_id;
   const char *repos_relpath;
 
-  SVN_ERR_ASSERT(*local_relpath != '\0'); /* Never on a wcroot */
+  /* Note that unlike many similar functions it is a valid scenario for this
+     function to be called on a wcroot! */
+
+   /* db set when destroying wc */
+  SVN_ERR_ASSERT(!rnb->destroy_wc || rnb->db != NULL);
 
   /* Need info for not_present node? */
   if (SVN_IS_VALID_REVNUM(rnb->not_present_rev))
@@ -6573,14 +6586,189 @@ remove_node_txn(void *baton,
                           wcroot, local_relpath,
                           scratch_pool, scratch_pool));
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE));
+  if (rnb->destroy_wc
+      && (!rnb->destroy_changes || *local_relpath == '\0'))
+    {
+      svn_boolean_t have_row;
+      apr_pool_t *iterpool;
+      svn_error_t *err = NULL;
 
-  /* Remove all nodes at or below local_relpath where op_depth >= 0 */
-  SVN_ERR(svn_sqlite__bindf(stmt, "isd",
-                            wcroot->wc_id, local_relpath, 0));
+      /* Install WQ items for deleting the unmodified files and all dirs */
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_WORKING_PRESENT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is",
+                                wcroot->wc_id, local_relpath));
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+      iterpool = svn_pool_create(scratch_pool);
+
+      while (have_row)
+        {
+          const char *child_relpath;
+          const char *child_abspath;
+          svn_kind_t child_kind;
+          svn_boolean_t have_checksum;
+          svn_filesize_t recorded_size;
+          apr_int64_t recorded_mod_time;
+          const svn_io_dirent2_t *dirent;
+          svn_boolean_t modified_p = TRUE;
+          svn_skel_t *work_item = NULL;
+
+          svn_pool_clear(iterpool);
+
+          child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+          child_kind = svn_sqlite__column_token(stmt, 1, kind_map);
+
+          child_abspath = svn_dirent_join(wcroot->abspath, child_relpath,
+                                          iterpool);
+
+          if (child_kind == svn_kind_file)
+            {
+              have_checksum = !svn_sqlite__column_is_null(stmt, 2);
+              recorded_size = get_recorded_size(stmt, 3);
+              recorded_mod_time = svn_sqlite__column_int64(stmt, 4);
+            }
+
+          if (rnb->cancel_func)
+            err = rnb->cancel_func(rnb->cancel_baton);
+
+          if (err)
+            break;
+
+          err = svn_io_stat_dirent(&dirent, child_abspath, TRUE,
+                                   iterpool, iterpool);
+
+          if (err)
+            break;
+
+          if (rnb->destroy_changes
+              || dirent->kind != svn_node_file
+              || child_kind != svn_kind_file)
+            {
+              /* Not interested in keeping changes */
+              modified_p = FALSE; 
+            }
+          else if (child_kind == svn_kind_file
+                   && dirent->kind == svn_node_file
+                   && dirent->filesize == recorded_size
+                   && dirent->mtime == recorded_mod_time)
+            {
+              modified_p = FALSE; /* File matches recorded state */
+            }
+          else if (have_checksum)
+            err = svn_wc__internal_file_modified_p(&modified_p,
+                                                   rnb->db, child_abspath,
+                                                   FALSE, iterpool);
+
+          if (err)
+            break;
+
+          if (modified_p)
+            rnb->left_changes = TRUE;
+          else if (child_kind == svn_kind_dir)
+            {
+              err = svn_wc__wq_build_dir_remove(&work_item,
+                                                rnb->db, wcroot->abspath,
+                                                child_abspath, FALSE,
+                                                iterpool, iterpool);
+            }
+          else /* svn_kind_file || svn_kind_symlink */
+            {
+              err = svn_wc__wq_build_file_remove(&work_item,
+                                                 rnb->db, wcroot->abspath,
+                                                 child_abspath,
+                                                 iterpool, iterpool);
+            }
+
+          if (err)
+            break;
+
+          if (work_item)
+            {
+              err = add_work_items(wcroot->sdb, work_item, iterpool);
+              if (err)
+                break;
+            }
+
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+        }
+      svn_pool_destroy(iterpool);
+
+      SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+    }
+
+  if (rnb->destroy_wc && *local_relpath != '\0')
+    {
+      /* Create work item for destroying the root */
+      svn_wc__db_status_t status;
+      svn_kind_t kind;
+      SVN_ERR(read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL, NULL,
+                        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                        wcroot, local_relpath,
+                        scratch_pool, scratch_pool));
+
+      if (status == svn_wc__db_status_normal
+          || status == svn_wc__db_status_added
+          || status == svn_wc__db_status_incomplete)
+        {
+          svn_skel_t *work_item = NULL;
+          const char *local_abspath = svn_dirent_join(wcroot->abspath,
+                                                          local_relpath,
+                                                          scratch_pool);
+
+          if (kind == svn_kind_dir)
+            {
+              SVN_ERR(svn_wc__wq_build_dir_remove(&work_item,
+                                                  rnb->db, wcroot->abspath,
+                                                  local_abspath,
+                                                  rnb->destroy_changes
+                                                      /* recursive */,
+                                                  scratch_pool, scratch_pool));
+            }
+          else
+            {
+              svn_boolean_t modified_p = FALSE;
+
+              if (!rnb->destroy_changes)
+                {
+                  SVN_ERR(svn_wc__internal_file_modified_p(&modified_p,
+                                                           rnb->db,
+                                                           local_abspath,
+                                                           FALSE,
+                                                           scratch_pool));
+                }
+
+              if (!modified_p)
+                SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+                                                     rnb->db, wcroot->abspath,
+                                                     local_abspath,
+                                                     scratch_pool,
+                                                     scratch_pool));
+              else
+                rnb->left_changes = TRUE;
+            }
+
+          SVN_ERR(add_work_items(wcroot->sdb, work_item, scratch_pool));
+        }
+    }
+
+  /* Remove all nodes below local_relpath */
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_NODE_RECURSIVE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath, 0));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
+  /* Delete the root NODE when this is not the working copy root */
+  if (local_relpath[0] != '\0')
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath, 0));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_DELETE_ACTUAL_NODE_RECURSIVE));
 
@@ -6596,7 +6784,11 @@ remove_node_txn(void *baton,
       blank_ibb(&ibb);
 
       ibb.repos_id = repos_id;
-      ibb.status = svn_wc__db_status_not_present;
+
+      SVN_ERR_ASSERT(rnb->not_present_status == svn_wc__db_status_not_present
+                     || rnb->not_present_status == svn_wc__db_status_excluded);
+
+      ibb.status = rnb->not_present_status;
       ibb.kind = rnb->not_present_kind;
 
       ibb.repos_relpath = repos_relpath;
@@ -6605,14 +6797,26 @@ remove_node_txn(void *baton,
       SVN_ERR(insert_base_node(&ibb, wcroot, local_relpath, scratch_pool));
     }
 
+  SVN_ERR(add_work_items(wcroot->sdb, rnb->work_items, scratch_pool));
+  if (rnb->conflict)
+    SVN_ERR(mark_conflict(wcroot, local_relpath, rnb->conflict, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_wc__db_op_remove_node(svn_wc__db_t *db,
+svn_wc__db_op_remove_node(svn_boolean_t *left_changes,
+                          svn_wc__db_t *db,
                           const char *local_abspath,
+                          svn_boolean_t destroy_wc,
+                          svn_boolean_t destroy_changes,
                           svn_revnum_t not_present_revision,
+                          svn_wc__db_status_t not_present_status,
                           svn_kind_t not_present_kind,
+                          const svn_skel_t *conflict,
+                          const svn_skel_t *work_items,
+                          svn_cancel_func_t cancel_func,
+                          void *cancel_baton,
                           apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
@@ -6625,8 +6829,17 @@ svn_wc__db_op_remove_node(svn_wc__db_t *
                               local_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
+  rnb.db = db;
+  rnb.left_changes = FALSE;
+  rnb.destroy_wc = destroy_wc;
+  rnb.destroy_changes = destroy_changes;
   rnb.not_present_rev = not_present_revision;
+  rnb.not_present_status = not_present_status;
   rnb.not_present_kind = not_present_kind;
+  rnb.conflict = conflict;
+  rnb.work_items = work_items;
+  rnb.cancel_func = cancel_func;
+  rnb.cancel_baton = cancel_baton;
 
   SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, remove_node_txn,
                               &rnb, scratch_pool));
@@ -6635,6 +6848,9 @@ svn_wc__db_op_remove_node(svn_wc__db_t *
   SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_infinity,
                         scratch_pool));
 
+  if (left_changes)
+    *left_changes = rnb.left_changes;
+
   return SVN_NO_ERROR;
 }
 
@@ -6842,6 +7058,7 @@ struct op_delete_baton_t {
   const char *moved_to_relpath; /* NULL if delete is not part of a move */
   svn_skel_t *conflict;
   svn_skel_t *work_items;
+  svn_boolean_t delete_dir_externals;
   svn_boolean_t notify;
 };
 
@@ -7193,6 +7410,18 @@ delete_node(void *baton,
         }
     }
 
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_DELETE_FILE_EXTERNALS));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    b->delete_dir_externals
+                                    ? STMT_DELETE_EXTERNAL_REGISTATIONS
+                                    : STMT_DELETE_FILE_EXTERNAL_REGISTATIONS));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+
   SVN_ERR(add_work_items(wcroot->sdb, b->work_items, scratch_pool));
   if (b->conflict)
     SVN_ERR(mark_conflict(wcroot, local_relpath, b->conflict, scratch_pool));
@@ -7215,6 +7444,8 @@ op_delete_txn(void *baton,
 
 struct op_delete_many_baton_t {
   apr_array_header_t *rel_targets;
+  svn_boolean_t delete_dir_externals;
+  const svn_skel_t *work_items;
 } op_delete_many_baton_t;
 
 static svn_error_t *
@@ -7240,11 +7471,14 @@ op_delete_many_txn(void *baton,
       odb.moved_to_relpath = NULL;
       odb.conflict = NULL;
       odb.work_items = NULL;
+      odb.delete_dir_externals = odmb->delete_dir_externals;
       odb.notify = TRUE;
       SVN_ERR(delete_node(&odb, wcroot, target_relpath, iterpool));
     }
   svn_pool_destroy(iterpool);
 
+  SVN_ERR(add_work_items(wcroot->sdb, odmb->work_items, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -7305,6 +7539,7 @@ svn_error_t *
 svn_wc__db_op_delete(svn_wc__db_t *db,
                      const char *local_abspath,
                      const char *moved_to_abspath,
+                     svn_boolean_t delete_dir_externals,
                      svn_skel_t *conflict,
                      svn_skel_t *work_items,
                      svn_cancel_func_t cancel_func,
@@ -7353,6 +7588,7 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
   odb.moved_to_relpath = moved_to_relpath;
   odb.conflict = conflict;
   odb.work_items = work_items;
+  odb.delete_dir_externals = delete_dir_externals;
 
   if (notify_func)
     {
@@ -7386,6 +7622,8 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
 svn_error_t *
 svn_wc__db_op_delete_many(svn_wc__db_t *db,
                           apr_array_header_t *targets,
+                          svn_boolean_t delete_dir_externals,
+                          const svn_skel_t *work_items,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           svn_wc_notify_func2_t notify_func,
@@ -7400,6 +7638,8 @@ svn_wc__db_op_delete_many(svn_wc__db_t *
 
   odmb.rel_targets = apr_array_make(scratch_pool, targets->nelts,
                                     sizeof(const char *));
+  odmb.work_items = work_items;
+  odmb.delete_dir_externals = delete_dir_externals;
   iterpool = svn_pool_create(scratch_pool);
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
                                                 db,
@@ -12452,7 +12692,8 @@ svn_wc__db_read_kind(svn_kind_t *kind,
         SVN_ERR(convert_to_working_status(&status, status));
 
       if (status == svn_wc__db_status_not_present
-          || status == svn_wc__db_status_excluded)
+          || status == svn_wc__db_status_excluded
+          || status == svn_wc__db_status_server_excluded)
         {
           *kind = svn_kind_none;
           SVN_ERR(svn_sqlite__reset(stmt_info));

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db.h Tue Jul 31 18:05:21 2012
@@ -1466,6 +1466,10 @@ svn_wc__db_temp_working_set_props(svn_wc
 
 /* Mark LOCAL_ABSPATH, and all children, for deletion.
  *
+ * This function removes the file externals (and if DELETE_DIR_EXTERNALS is
+ * TRUE also the directory externals) registered below LOCAL_ABSPATH.
+ * (DELETE_DIR_EXTERNALS should be true if also removing unversioned nodes)
+ *
  * If MOVED_TO_ABSPATH is not NULL, mark the deletion of LOCAL_ABSPATH
  * as the delete-half of a move from LOCAL_ABSPATH to MOVED_TO_ABSPATH.
  *
@@ -1481,6 +1485,7 @@ svn_error_t *
 svn_wc__db_op_delete(svn_wc__db_t *db,
                      const char *local_abspath,
                      const char *moved_to_abspath,
+                     svn_boolean_t delete_dir_externals,
                      svn_skel_t *conflict,
                      svn_skel_t *work_items,
                      svn_cancel_func_t cancel_func,
@@ -1498,6 +1503,10 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
  * It currently lacks support for moves (though this could be changed,
  * at which point svn_wc__db_op_delete() becomes redundant).
  *
+ * This function removes the file externals (and if DELETE_DIR_EXTERNALS is
+ * TRUE also the directory externals) registered below the targets.
+ * (DELETE_DIR_EXTERNALS should be true if also removing unversioned nodes)
+ *
  * If NOTIFY_FUNC is not NULL, then it will be called (with NOTIFY_BATON)
  * for each node deleted. While this processing occurs, if CANCEL_FUNC is
  * not NULL, then it will be called (with CANCEL_BATON) to detect cancellation
@@ -1509,6 +1518,8 @@ svn_wc__db_op_delete(svn_wc__db_t *db,
 svn_error_t *
 svn_wc__db_op_delete_many(svn_wc__db_t *db,
                           apr_array_header_t *targets,
+                          svn_boolean_t delete_dir_externals,
+                          const svn_skel_t *conflict,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           svn_wc_notify_func2_t notify_func,
@@ -2873,19 +2884,39 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
 */
 
 /* Removes all references to LOCAL_ABSPATH from DB, while optionally leaving
-   tree conflicts and/or a not present node.
+   a not present node.
 
    This operation always recursively removes all nodes at and below
    LOCAL_ABSPATH from NODES and ACTUAL.
 
    If NOT_PRESENT_REVISION specifies a valid revision, leave a not_present
-   BASE node at local_abspath. (Requires an existing BASE node before removing)
+   BASE node at local_abspath of the specified status and kind.
+   (Requires an existing BASE node before removing)
+
+   If DESTROY_WC is TRUE, this operation *installs* workqueue operations to
+   update the local filesystem after the database operation. If DESTROY_CHANGES
+   is FALSE, modified and unversioned files are left after running this
+   operation (and the WQ). If DESTROY_CHANGES and DESTROY_WC are TRUE,
+   LOCAL_ABSPATH and everything below it will be removed by the WQ.
+
+
+   Note: Unlike many similar functions it is a valid scenario for this
+   function to be called on a wcroot! In this case it will just leave the root
+   record in BASE
  */
 svn_error_t *
-svn_wc__db_op_remove_node(svn_wc__db_t *db,
+svn_wc__db_op_remove_node(svn_boolean_t *left_changes,
+                          svn_wc__db_t *db,
                           const char *local_abspath,
+                          svn_boolean_t destroy_wc,
+                          svn_boolean_t destroy_changes,
                           svn_revnum_t not_present_revision,
+                          svn_wc__db_status_t not_present_status,
                           svn_kind_t not_present_kind,
+                          const svn_skel_t *conflict,
+                          const svn_skel_t *work_items,
+                          svn_cancel_func_t cancel_func,
+                          void *cancel_baton,
                           apr_pool_t *scratch_pool);
 
 /* Sets the depth of LOCAL_ABSPATH in its working copy to DEPTH using DB.

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db_pristine.c?rev=1367697&r1=1367696&r2=1367697&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc_db_pristine.c Tue Jul 31 18:05:21 2012
@@ -855,11 +855,12 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
                         apr_pool_t *scratch_pool)
 {
   svn_sqlite__stmt_t *stmt;
+  svn_error_t *err = NULL;
 
   /* Find each unreferenced pristine in the DB and remove it. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
                                     STMT_SELECT_UNREFERENCED_PRISTINES));
-  while (1)
+  while (! err)
     {
       svn_boolean_t have_row;
       const svn_checksum_t *sha1_checksum;
@@ -870,12 +871,12 @@ pristine_cleanup_wcroot(svn_wc__db_wcroo
 
       SVN_ERR(svn_sqlite__column_checksum(&sha1_checksum, stmt, 0,
                                           scratch_pool));
-      SVN_ERR(pristine_remove_if_unreferenced(wcroot, sha1_checksum,
-                                              scratch_pool));
+      err = pristine_remove_if_unreferenced(wcroot, sha1_checksum,
+                                            scratch_pool);
     }
-  SVN_ERR(svn_sqlite__reset(stmt));
 
-  return SVN_NO_ERROR;
+  return svn_error_trace(
+      svn_error_compose_create(err, svn_sqlite__reset(stmt)));
 }
 
 svn_error_t *



Mime
View raw message