You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2013/01/12 21:24:15 UTC

svn commit: r1432504 [3/6] - in /subversion/branches/ev2-export: ./ contrib/client-side/emacs/ notes/http-and-webdav/ subversion/bindings/javahl/native/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_delta/ ...

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_pristine.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_pristine.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_pristine.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_pristine.c Sat Jan 12 20:24:12 2013
@@ -25,6 +25,7 @@
 
 #define SVN_WC__I_AM_WC_DB
 
+#include "svn_pools.h"
 #include "svn_dirent_uri.h"
 
 #include "wc.h"
@@ -500,118 +501,84 @@ svn_wc__db_pristine_get_sha1(const svn_c
   return svn_error_trace(svn_sqlite__reset(stmt));
 }
 
-/* Transaction implementation of svn_wc__db_pristine_transfer().
-   We have a lock on DST_WCROOT and a lock on SRC_WCROOT.
-
-   Outputs:
-   *TEMPFILE_ABSPATH is the path to the source file that is to be moved
-   into place.
-   *PRISTINE_ABSPATH is the target path for the file (within the pristine
-   store).
-   *SHA1_CHECKSUM is the pristine text's SHA-1 checksum.
-   *MD5_CHECKSUM is the pristine text's MD-5 checksum.
-
-   If there is nothing to transfer (it is not found in the source, or is
-   already in the destination), then set *TEMPFILE_ABSPATH_P to NULL.
- */
+/* Handle the moving of a pristine from SRC_WCROOT to DST_WCROOT. The existing
+   pristine in SRC_WCROOT is described by CHECKSUM, MD5_CHECKSUM and SIZE */
 static svn_error_t *
-pristine_transfer_txn2(const char **tempfile_abspath,
-                       const char **pristine_abspath,
-                       const svn_checksum_t **sha1_checksum,
-                       const svn_checksum_t **md5_checksum,
-                       svn_wc__db_wcroot_t *src_wcroot,
-                       svn_wc__db_wcroot_t *dst_wcroot,
-                       const char *src_relpath,
-                       svn_cancel_func_t cancel_func,
-                       void *cancel_baton,
-                       apr_pool_t *scratch_pool)
+maybe_transfer_one_pristine(svn_wc__db_wcroot_t *src_wcroot,
+                            svn_wc__db_wcroot_t *dst_wcroot,
+                            const svn_checksum_t *checksum,
+                            const svn_checksum_t *md5_checksum,
+                            apr_int64_t size,
+                            svn_cancel_func_t cancel_func,
+                            void *cancel_baton,
+                            apr_pool_t *scratch_pool)
 {
+  const char *pristine_abspath;
   svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
+  svn_stream_t *src_stream;
+  svn_stream_t *dst_stream;
+  const char *tmp_abspath;
+  const char *src_abspath;
+  int affected_rows;
+  svn_error_t *err;
 
-  *tempfile_abspath = NULL;
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
+                                    STMT_INSERT_OR_IGNORE_PRISTINE));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__bind_int64(stmt, 3, size));
 
-  /* Get the SHA1 checksum */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                                    STMT_SELECT_NODE_INFO));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is",
-                            src_wcroot->wc_id, src_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (have_row)
-    SVN_ERR(svn_sqlite__column_checksum(sha1_checksum, stmt, 6,
-                                        scratch_pool));
-  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-  if (! *sha1_checksum)
-    return SVN_NO_ERROR; /* Nothing to transfer */
+  if (affected_rows == 0)
+    return SVN_NO_ERROR;
 
-  /* Check if we have the pristine in the destination wcroot */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
-                                    STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, *sha1_checksum,
-                                    scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath,
+                                 pristine_get_tempdir(dst_wcroot,
+                                                      scratch_pool,
+                                                      scratch_pool),
+                                 svn_io_file_del_on_pool_cleanup,
+                                 scratch_pool, scratch_pool));
 
-  /* Destination repository already has this pristine. We're done */
-  if (have_row)
-    return SVN_NO_ERROR;
+  SVN_ERR(get_pristine_fname(&src_abspath, src_wcroot->abspath, checksum,
+                             scratch_pool, scratch_pool));
 
-  /* Verify if the pristine actually exists and get the MD5 in one query */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                                    STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, *sha1_checksum,
-                                    scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath,
+                                   scratch_pool, scratch_pool));
 
-  if (!have_row)
+  /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */
+  SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
+                           cancel_func, cancel_baton,
+                           scratch_pool));
+
+  SVN_ERR(get_pristine_fname(&pristine_abspath, dst_wcroot->abspath, checksum,
+                             scratch_pool, scratch_pool));
+
+  /* Move the file to its target location.  (If it is already there, it is
+   * an orphan file and it doesn't matter if we overwrite it.) */
+  err = svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool);
+
+  /* Maybe the directory doesn't exist yet? */
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
     {
-      return svn_error_createf(SVN_ERR_WC_DB_ERROR, svn_sqlite__reset(stmt),
-                               _("The pristine text with checksum '%s' was "
-                                 "not found"),
-                               svn_checksum_to_cstring_display(
-                                        *sha1_checksum, scratch_pool));
-    }
-  SVN_ERR(svn_sqlite__column_checksum(md5_checksum, stmt, 0,
-                                      scratch_pool));
-  SVN_ERR(svn_sqlite__reset(stmt));
+      svn_error_t *err2;
 
-  /* We have read locks in both working copies, so we can safely copy the
-     file to the temp location of the destination working copy */
-  {
-    svn_stream_t *src_stream;
-    svn_stream_t *dst_stream;
-    const char *tmp_abspath;
-    const char *src_abspath;
-
-    SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath,
-                                   pristine_get_tempdir(dst_wcroot,
-                                                        scratch_pool,
-                                                        scratch_pool),
-                                   svn_io_file_del_on_pool_cleanup,
-                                   scratch_pool, scratch_pool));
+      err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath,
+                                                scratch_pool),
+                             APR_OS_DEFAULT, scratch_pool);
+
+      if (err2)
+        /* Creating directory didn't work: Return all errors */
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        /* We could create a directory: retry install */
+        svn_error_clear(err);
+
+      SVN_ERR(svn_io_file_rename(tmp_abspath, pristine_abspath, scratch_pool));
+    }
+  else
+    SVN_ERR(err);
 
-    SVN_ERR(get_pristine_fname(&src_abspath, src_wcroot->abspath,
-                               *sha1_checksum,
-                               scratch_pool, scratch_pool));
-
-    SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath,
-                                     scratch_pool, scratch_pool));
-
-    /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */
-    SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
-                             cancel_func, cancel_baton,
-                             scratch_pool));
-
-    /* And now set the right information to install once we leave the
-       src transaction */
-
-    SVN_ERR(get_pristine_fname(pristine_abspath,
-                               dst_wcroot->abspath,
-                               *sha1_checksum,
-                               scratch_pool, scratch_pool));
-    *tempfile_abspath = tmp_abspath;
-  }
   return SVN_NO_ERROR;
 }
 
@@ -619,32 +586,53 @@ pristine_transfer_txn2(const char **temp
    We have a lock on DST_WCROOT.
  */
 static svn_error_t *
-pristine_transfer_txn1(svn_wc__db_wcroot_t *src_wcroot,
+pristine_transfer_txn(svn_wc__db_wcroot_t *src_wcroot,
                        svn_wc__db_wcroot_t *dst_wcroot,
                        const char *src_relpath,
                        svn_cancel_func_t cancel_func,
                        void *cancel_baton,
                        apr_pool_t *scratch_pool)
 {
-  const char *tempfile_abspath;
-  const char *pristine_abspath;
-  const svn_checksum_t *sha1_checksum;
-  const svn_checksum_t *md5_checksum;
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t got_row;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+                                    STMT_SELECT_COPY_PRISTINES));
+  SVN_ERR(svn_sqlite__bindf(stmt, "is", src_wcroot->wc_id, src_relpath));
+
+  /* This obtains an sqlite read lock on src_wcroot */
+  SVN_ERR(svn_sqlite__step(&got_row, stmt));
+
+  while (got_row)
+    {
+      const svn_checksum_t *checksum;
+      const svn_checksum_t *md5_checksum;
+      apr_int64_t size;
+      svn_error_t *err;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_sqlite__column_checksum(&checksum, stmt, 0, iterpool));
+      SVN_ERR(svn_sqlite__column_checksum(&md5_checksum, stmt, 1, iterpool));
+      size = svn_sqlite__column_int64(stmt, 2);
+
+      err = maybe_transfer_one_pristine(src_wcroot, dst_wcroot,
+                                        checksum, md5_checksum, size,
+                                        cancel_func, cancel_baton,
+                                        iterpool);
+
+      if (err)
+        return svn_error_trace(svn_error_compose_create(
+                                    err,
+                                    svn_sqlite__reset(stmt)));
+
+      SVN_ERR(svn_sqlite__step(&got_row, stmt));
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  svn_pool_destroy(iterpool);
 
-  /* Get all the info within a src wcroot lock */
-  SVN_WC__DB_WITH_TXN(
-    pristine_transfer_txn2(&tempfile_abspath, &pristine_abspath,
-                           &sha1_checksum, &md5_checksum,
-                           src_wcroot, dst_wcroot, src_relpath,
-                           cancel_func, cancel_baton, scratch_pool),
-    src_wcroot);
-
-  /* And do the final install, while we still have the dst lock */
-  if (tempfile_abspath)
-    SVN_ERR(pristine_install_txn(dst_wcroot->sdb,
-                                 tempfile_abspath, pristine_abspath,
-                                 sha1_checksum, md5_checksum,
-                                 scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -675,8 +663,8 @@ svn_wc__db_pristine_transfer(svn_wc__db_
     }
 
   SVN_WC__DB_WITH_TXN(
-    pristine_transfer_txn1(src_wcroot, dst_wcroot, src_relpath,
-                           cancel_func, cancel_baton, scratch_pool),
+    pristine_transfer_txn(src_wcroot, dst_wcroot, src_relpath,
+                          cancel_func, cancel_baton, scratch_pool),
     dst_wcroot);
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_private.h?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_private.h Sat Jan 12 20:24:12 2013
@@ -367,4 +367,14 @@ svn_wc__db_retract_parent_delete(svn_wc_
                                  int op_depth,
                                  apr_pool_t *scratch_pool);
 
+/* Do a post-drive revision bump for the moved-away destination for
+   any move sources under LOCAL_RELPATH.  This is called from within
+   the revision bump transaction after the tree at LOCAL_RELPATH has
+   been bumped. */
+svn_error_t *
+svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot,
+                           const char *local_relpath,
+                           svn_depth_t depth,
+                           apr_pool_t *scratch_pool);
+
 #endif /* WC_DB_PRIVATE_H */

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_update_move.c Sat Jan 12 20:24:12 2013
@@ -90,6 +90,7 @@
 #include "wc-queries.h"
 #include "conflicts.h"
 #include "workqueue.h"
+#include "token-map.h"
 
 /*
  * Receiver code.
@@ -109,6 +110,11 @@ struct tc_editor_baton {
   svn_wc__db_t *db;
   svn_wc__db_wcroot_t *wcroot;
   const char *move_root_dst_relpath;
+
+  /* The most recent conflict raised during this drive.  We rely on the
+     non-Ev2, depth-first, drive for this to make sense. */
+  const char *conflict_root_relpath;
+
   svn_wc_conflict_version_t *old_version;
   svn_wc_conflict_version_t *new_version;
   svn_wc_notify_func2_t notify_func;
@@ -116,13 +122,73 @@ struct tc_editor_baton {
   apr_pool_t *result_pool;
 };
 
-/* If LOCAL_RELPATH is shadowed then raise a tree-conflict on the root
-   of the obstruction if such a tree-conflict does not already exist.
+static svn_error_t *
+mark_tree_conflict(struct tc_editor_baton *b,
+                   const char *local_relpath,
+                   svn_node_kind_t old_kind,
+                   svn_node_kind_t new_kind,
+                   svn_wc_conflict_reason_t reason,
+                   svn_wc_conflict_action_t action,
+                   apr_pool_t *scratch_pool)
+{
+  const char *repos_relpath;
+  svn_skel_t *conflict = svn_wc__conflict_skel_create(scratch_pool);
+  svn_wc_conflict_version_t *old_version, *new_version;
 
-   KIND is the node kind of ... ### what?
+  b->conflict_root_relpath = apr_pstrdup(b->result_pool, local_relpath);
 
-   Set *IS_CONFLICTED ... ### if/iff what?
- */
+  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+                     conflict, NULL,
+                     svn_dirent_join(b->wcroot->abspath, local_relpath,
+                                     scratch_pool),
+                     reason,
+                     action,
+                     scratch_pool,
+                     scratch_pool));
+
+  if (reason != svn_wc_conflict_reason_unversioned)
+    {
+      repos_relpath = svn_relpath_join(b->old_version->path_in_repos,
+                           svn_relpath_skip_ancestor(b->move_root_dst_relpath,
+                                                     local_relpath),
+                                       scratch_pool);
+      old_version = svn_wc_conflict_version_create2(b->old_version->repos_url,
+                                                    b->old_version->repos_uuid,
+                                                    repos_relpath,
+                                                    b->old_version->peg_rev,
+                                                    old_kind,
+                                                    scratch_pool);
+    }
+  else
+    old_version = NULL;
+
+  repos_relpath = svn_relpath_join(b->new_version->path_in_repos,
+                           svn_relpath_skip_ancestor(b->move_root_dst_relpath,
+                                                     local_relpath),
+                                   scratch_pool);
+  new_version = svn_wc_conflict_version_create2(b->new_version->repos_url,
+                                                b->new_version->repos_uuid,
+                                                repos_relpath,
+                                                b->new_version->peg_rev,
+                                                new_kind,
+                                                scratch_pool);
+
+  /* What about switch? */
+  SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict,
+                                              old_version, new_version,
+                                              scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, local_relpath,
+                                            conflict, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* If LOCAL_RELPATH is a child of the most recently raised
+   tree-conflict or is shadowed then set *IS_CONFLICTED to TRUE and
+   raise a tree-conflict on the root of the obstruction if such a
+   tree-conflict does not already exist.  KIND is the kind of the
+   incoming LOCAL_RELPATH. This relies on the non-Ev2, depth-first,
+   drive. */
 static svn_error_t *
 check_tree_conflict(svn_boolean_t *is_conflicted,
                     struct tc_editor_baton *b,
@@ -134,10 +200,20 @@ check_tree_conflict(svn_boolean_t *is_co
   svn_boolean_t have_row;
   int dst_op_depth = relpath_depth(b->move_root_dst_relpath);
   int op_depth;
+  svn_node_kind_t old_kind;
   const char *conflict_root_relpath = local_relpath;
   const char *moved_to_relpath;
   svn_skel_t *conflict;
-  svn_wc_conflict_version_t *version;
+
+  if (b->conflict_root_relpath)
+    {
+      if (svn_relpath_skip_ancestor(b->conflict_root_relpath, local_relpath))
+        {
+          *is_conflicted = TRUE;
+          return SVN_NO_ERROR;
+        }
+      b->conflict_root_relpath = NULL;
+    }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, b->wcroot->sdb,
                                     STMT_SELECT_LOWEST_WORKING_NODE));
@@ -145,7 +221,11 @@ check_tree_conflict(svn_boolean_t *is_co
                             dst_op_depth));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   if (have_row)
-    op_depth = svn_sqlite__column_int(stmt, 0);
+    {
+      op_depth = svn_sqlite__column_int(stmt, 0);
+      old_kind = svn__node_kind_from_kind(svn_sqlite__column_token(stmt, 2,
+                                                                   kind_map));
+    }
   SVN_ERR(svn_sqlite__reset(stmt));
 
   if (!have_row)
@@ -157,8 +237,11 @@ check_tree_conflict(svn_boolean_t *is_co
   *is_conflicted = TRUE;
 
   while (relpath_depth(conflict_root_relpath) > op_depth)
-    conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
-                                                scratch_pool);
+    {
+      conflict_root_relpath = svn_relpath_dirname(conflict_root_relpath,
+                                                  scratch_pool);
+      old_kind = svn_node_dir;
+    }
 
   SVN_ERR(svn_wc__db_read_conflict_internal(&conflict, b->wcroot,
                                             conflict_root_relpath,
@@ -173,67 +256,12 @@ check_tree_conflict(svn_boolean_t *is_co
                                             b->wcroot, conflict_root_relpath,
                                             scratch_pool, scratch_pool));
 
-  conflict = svn_wc__conflict_skel_create(scratch_pool);
-  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
-                     conflict, NULL,
-                     svn_dirent_join(b->wcroot->abspath, conflict_root_relpath,
-                                     scratch_pool),
-                     (moved_to_relpath
-                      ? svn_wc_conflict_reason_moved_away
-                      : svn_wc_conflict_reason_deleted),
-                     svn_wc_conflict_action_edit,
-                     scratch_pool,
-                     scratch_pool));
-
-  version = svn_wc_conflict_version_create2(b->old_version->repos_url,
-                                            b->old_version->repos_uuid,
-                                            local_relpath /* ### need *repos* relpath */,
-                                            b->old_version->peg_rev,
-                                            kind /* ### need *old* kind for this node */,
-                                            scratch_pool);
-
-  /* What about switch? */
-  SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict, version, NULL /* ### derive from b->new_version & new kind? */,
-                                              scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, conflict_root_relpath,
-                                            conflict, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-/* Mark a unversioned-add tree-conflict on RELPATH. */
-static svn_error_t *
-mark_unversioned_add_conflict(struct tc_editor_baton *b,
-                              const char *relpath,
-                              svn_node_kind_t kind,
-                              apr_pool_t *scratch_pool)
-{
-  svn_skel_t *conflict = svn_wc__conflict_skel_create(scratch_pool);
-  svn_wc_conflict_version_t *version;
-
-  SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
-                     conflict, NULL,
-                     svn_dirent_join(b->wcroot->abspath, relpath,
-                                     scratch_pool),
-                     svn_wc_conflict_reason_unversioned,
-                     svn_wc_conflict_action_add,
-                     scratch_pool,
-                     scratch_pool));
-
-  version = svn_wc_conflict_version_create2(b->old_version->repos_url,
-                                            b->old_version->repos_uuid,
-                                            relpath /* ### need *repos* relpath */,
-                                            b->old_version->peg_rev,
-                                            kind /* ### need *old* kind for this node */,
-                                            scratch_pool);
-
-  /* ### How about switch? */
-  SVN_ERR(svn_wc__conflict_skel_set_op_update(conflict, version,
-                                              NULL /* ### derive from b->new_version & new kind? */,
-                                              scratch_pool, scratch_pool));
-  SVN_ERR(svn_wc__db_mark_conflict_internal(b->wcroot, relpath,
-                                            conflict, scratch_pool));
-
+  SVN_ERR(mark_tree_conflict(b, conflict_root_relpath, old_kind, kind,
+                             (moved_to_relpath
+                              ? svn_wc_conflict_reason_moved_away
+                              : svn_wc_conflict_reason_deleted),
+                             svn_wc_conflict_action_edit,
+                             scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -271,8 +299,10 @@ tc_editor_add_directory(void *baton,
     {
     case svn_node_file:
     default:
-      SVN_ERR(mark_unversioned_add_conflict(b, relpath, svn_node_dir,
-                                            scratch_pool));
+      SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_dir,
+                                 svn_wc_conflict_reason_unversioned,
+                                 svn_wc_conflict_action_add,
+                                 scratch_pool));
       break;
 
     case svn_node_none:
@@ -322,8 +352,10 @@ tc_editor_add_file(void *baton,
 
   if (kind != svn_node_none)
     {
-      SVN_ERR(mark_unversioned_add_conflict(b, relpath, svn_node_file,
-                                            scratch_pool));
+      SVN_ERR(mark_tree_conflict(b, relpath, kind, svn_node_file,
+                                 svn_wc_conflict_reason_unversioned,
+                                 svn_wc_conflict_action_add,
+                                 scratch_pool));
       return SVN_NO_ERROR;
     }
 
@@ -718,8 +750,6 @@ tc_editor_alter_file(void *baton,
   new_version.checksum = new_checksum ? new_checksum : old_version.checksum;
   new_version.props = new_props ? new_props : old_version.props;
 
-  /* ### TODO update revision etc. in NODES table */
-
   /* Update file and prop contents if the update has changed them. */
   if (!svn_checksum_match(new_checksum, old_version.checksum)
       /* ### || props have changed */)
@@ -1004,6 +1034,8 @@ update_moved_away_dir(svn_editor_t *tc_e
   SVN_ERR(svn_wc__db_read_pristine_props(&new_props, db, src_abspath,
                                          scratch_pool, scratch_pool));
 
+  /* This is a non-Ev2, depth-first, drive that calls add/alter on all
+     directories. */
   if (add)
     SVN_ERR(svn_editor_add_directory(tc_editor, dst_relpath,
                                      new_children, new_props,
@@ -1108,7 +1140,6 @@ update_moved_away_subtree(svn_editor_t *
       svn_pool_clear(iterpool);
       child_dst_relpath = svn_relpath_join(dst_relpath, dst_name, iterpool);
 
-      /* FIXME: editor API violation: missing svn_editor_alter_directory. */
       SVN_ERR(svn_editor_delete(tc_editor, child_dst_relpath,
                                 move_root_dst_revision));
     }
@@ -1359,3 +1390,93 @@ svn_wc__db_update_moved_away_conflict_vi
 
   return SVN_NO_ERROR;
 }
+
+static svn_error_t *
+bump_moved_away(svn_wc__db_wcroot_t *wcroot,
+                const char *local_relpath,
+                svn_depth_t depth,
+                int op_depth,
+                apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_pool_t *iterpool;
+
+  iterpool = svn_pool_create(scratch_pool);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_SELECT_MOVED_PAIR3));
+  SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+                            op_depth));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while(have_row)
+    {
+      svn_sqlite__stmt_t *stmt2;
+      const char *src_relpath, *dst_relpath;
+      int src_op_depth = svn_sqlite__column_int(stmt, 2);
+      svn_error_t *err;
+      svn_skel_t *conflict;
+
+      svn_pool_clear(iterpool);
+
+      src_relpath = svn_sqlite__column_text(stmt, 0, iterpool);
+      dst_relpath = svn_sqlite__column_text(stmt, 1, iterpool);
+
+      err = svn_sqlite__get_statement(&stmt2, wcroot->sdb,
+                                      STMT_HAS_LAYER_BETWEEN);
+      if (!err)
+       err = svn_sqlite__bindf(stmt2, "isdd", wcroot->wc_id, local_relpath,
+                               op_depth, src_op_depth);
+      if (!err)
+        err = svn_sqlite__step(&have_row, stmt2);
+      if (!err)
+        err = svn_sqlite__reset(stmt2);
+      if (!err && !have_row)
+        {
+          const char *src_root_relpath = src_relpath;
+
+          while (relpath_depth(src_root_relpath) > src_op_depth)
+            src_root_relpath = svn_relpath_dirname(src_root_relpath, iterpool);
+
+          err = svn_wc__db_read_conflict_internal(&conflict, wcroot,
+                                                  src_root_relpath,
+                                                  iterpool, iterpool);
+          /* ### TODO: check this is the right sort of tree-conflict? */
+          if (!err && !conflict)
+            {
+              /* ### TODO: verify moved_here? */
+              err = replace_moved_layer(src_relpath, dst_relpath, op_depth,
+                                        wcroot, iterpool);
+
+              if (!err)
+                err = bump_moved_away(wcroot, dst_relpath, depth,
+                                      relpath_depth(dst_relpath), iterpool);
+            }
+        }
+
+      if (err)
+        return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__db_bump_moved_away(svn_wc__db_wcroot_t *wcroot,
+                           const char *local_relpath,
+                           svn_depth_t depth,
+                           apr_pool_t *scratch_pool)
+{
+  /* ### TODO: raise tree-conflicts? */
+  if (depth != svn_depth_infinity)
+    return SVN_NO_ERROR;
+
+  SVN_ERR(bump_moved_away(wcroot, local_relpath, depth, 0, scratch_pool));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_util.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db_util.c Sat Jan 12 20:24:12 2013
@@ -136,6 +136,22 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
                                  svn_dirent_local_style(sdb_abspath,
                                                         scratch_pool));
     }
+#ifndef WIN32
+  else
+    {
+      apr_file_t *f;
+
+      /* A standard SQLite build creates a DB with mode 644 ^ !umask
+         which means the file doesn't have group/world write access
+         even when umask allows it. By ensuring the file exists before
+         SQLite gets involved we give it the permissions allowed by
+         umask. */
+      SVN_ERR(svn_io_file_open(&f, sdb_abspath,
+                               (APR_READ | APR_WRITE | APR_CREATE),
+                               APR_OS_DEFAULT, scratch_pool));
+      SVN_ERR(svn_io_file_close(f, scratch_pool));
+    }
+#endif
 
   SVN_ERR(svn_sqlite__open(sdb, sdb_abspath, smode,
                            my_statements ? my_statements : statements,

Modified: subversion/branches/ev2-export/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/deadprops.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/deadprops.c Sat Jan 12 20:24:12 2013
@@ -136,7 +136,7 @@ get_value(dav_db *db, const dav_prop_nam
                                propname, db->p);
       else
         serr = svn_repos_fs_revision_prop(pvalue,
-                                          db->resource->info-> repos->repos,
+                                          db->resource->info->repos->repos,
                                           db->resource->info->root.rev,
                                           propname, db->authz_read_func,
                                           db->authz_read_baton, db->p);

Modified: subversion/branches/ev2-export/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/reports/replay.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/reports/replay.c Sat Jan 12 20:24:12 2013
@@ -418,11 +418,11 @@ dav_svn__replay_report(const dav_resourc
 {
   dav_error *derr = NULL;
   svn_revnum_t low_water_mark = SVN_INVALID_REVNUM;
-  svn_revnum_t rev = SVN_INVALID_REVNUM;
+  svn_revnum_t rev;
   const svn_delta_editor_t *editor;
   svn_boolean_t send_deltas = TRUE;
   dav_svn__authz_read_baton arb;
-  const char *base_dir = resource->info->repos_path;
+  const char *base_dir;
   apr_bucket_brigade *bb;
   apr_xml_elem *child;
   svn_fs_root_t *root;
@@ -430,10 +430,27 @@ dav_svn__replay_report(const dav_resourc
   void *edit_baton;
   int ns;
 
-  /* The request won't have a repos_path if it's for the root. */
-  if (! base_dir)
-    base_dir = "";
-
+  /* In Subversion 1.8, we allowed this REPORT to be issue against a
+     revision resource.  Doing so means the REV is part of the request
+     URL, and BASE_DIR is embedded in the request body.
+
+     The old-school (and incorrect, see issue #4287 --
+     http://subversion.tigris.org/issues/show_bug.cgi?id=4287) way was
+     to REPORT on the public URL of the BASE_DIR and embed the REV in
+     the report body.
+  */
+  if (resource->baselined
+      && (resource->type == DAV_RESOURCE_TYPE_VERSION))
+    {
+      rev = resource->info->root.rev;
+      base_dir = NULL;
+    }
+  else
+    {
+      rev = SVN_INVALID_REVNUM;
+      base_dir = resource->info->repos_path;
+    }
+  
   arb.r = resource->info->r;
   arb.repos = resource->info->repos;
 
@@ -455,9 +472,17 @@ dav_svn__replay_report(const dav_resourc
 
           if (strcmp(child->name, "revision") == 0)
             {
+              if (SVN_IS_VALID_REVNUM(rev))
+                {
+                  /* Uh... we already have a revision to use, either
+                     because this tag is non-unique or because the
+                     request was submitted against a revision-bearing
+                     resource URL.  Either way, something's not
+                     right.  */
+                  return malformed_element_error("revision", resource->pool);
+                }
+
               cdata = dav_xml_get_cdata(child, resource->pool, 1);
-              if (! cdata)
-                return malformed_element_error("revision", resource->pool);
               rev = SVN_STR_TO_REV(cdata);
             }
           else if (strcmp(child->name, "low-water-mark") == 0)
@@ -481,7 +506,16 @@ dav_svn__replay_report(const dav_resourc
                   svn_error_clear(err);
                   return malformed_element_error("send-deltas", resource->pool);
                 }
-              send_deltas = parsed_val ? TRUE : FALSE;
+              send_deltas = parsed_val != 0;
+            }
+          else if (strcmp(child->name, "include-path") == 0)
+            {
+              cdata = dav_xml_get_cdata(child, resource->pool, 1);
+              if ((derr = dav_svn__test_canonical(cdata, resource->pool)))
+                return derr;
+
+              /* Force BASE_DIR to be a relative path, not an fspath. */
+              base_dir = svn_relpath_canonicalize(cdata, resource->pool);
             }
         }
     }
@@ -498,6 +532,9 @@ dav_svn__replay_report(const dav_resourc
               "Request was missing the low-water-mark argument.",
               SVN_DAV_ERROR_NAMESPACE, SVN_DAV_ERROR_TAG);
 
+  if (! base_dir)
+    base_dir = "";
+
   bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
 
   if ((err = svn_fs_revision_root(&root, resource->info->repos->fs, rev,

Modified: subversion/branches/ev2-export/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/version.c?rev=1432504&r1=1432503&r2=1432504&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/version.c Sat Jan 12 20:24:12 2013
@@ -266,6 +266,14 @@ get_option(const dav_resource *resource,
         { "create-txn-with-props",  { 1, 8, 0, "" } },
       };
 
+      /* Add the header which indicates that this server can handle
+         replay REPORTs submitted against an HTTP v2 revision resource. */
+      apr_table_addn(r->headers_out, "DAV",
+                     SVN_DAV_NS_DAV_SVN_REPLAY_REV_RESOURCE);
+
+      /* Add a bunch of HTTP v2 headers which carry resource and
+         resource stub URLs that the client can use to naively build
+         addressable resources. */
       apr_table_set(r->headers_out, SVN_DAV_ROOT_URI_HEADER, repos_root_uri);
       apr_table_set(r->headers_out, SVN_DAV_ME_RESOURCE_HEADER,
                     apr_pstrcat(resource->pool, repos_root_uri, "/",