Author: rhuijben
Date: Mon May  2 17:48:59 2011
New Revision: 1098689

URL: http://svn.apache.org/viewvc?rev=1098689&view=rev
Log:
Add an experimental per op_root commit handling. After more review and testing
this could make it possible to enable depth limited commits that perform
additions.

When this feature is enabled (and post_process_commit_item is updated), all
tests pass and one test that tests for commit behavior on directories
(which is fixed by this change) XPasses.

* subversion/libsvn_client/commit.c
  (post_process_commit_item): Add comment.

* subversion/libsvn_wc/adm_ops.c
  (process_committed_leaf): Answer a question by handling this status
    explicitly and asserting that we only see valid statee.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_COMMIT_DESCENDANT_TO_BASE): New statement.

* subversion/libsvn_wc/wc_db.c
  (descendant_commit): New function; disabled via macro.
  (commit_node): When enabled call descendant_commit for op-roots.

Modified:
    subversion/trunk/subversion/libsvn_client/commit.c
    subversion/trunk/subversion/libsvn_wc/adm_ops.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c

Modified: subversion/trunk/subversion/libsvn_client/commit.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/commit.c?rev=1098689&r1=1098688&r2=1098689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/commit.c (original)
+++ subversion/trunk/subversion/libsvn_client/commit.c Mon May  2 17:48:59 2011
@@ -924,6 +924,9 @@ post_process_commit_item(svn_wc_committe
   svn_boolean_t loop_recurse = FALSE;
   svn_boolean_t remove_lock;
 
+  /* The following condition can be disabled (keeping loop_recurse FALSE), when
+     the SVN_WC__EXPERIMENTAL_DESCENDANT_COMMIT flag in libsvn_wc/wc.db is
+     enabled */
   if ((item->state_flags & SVN_CLIENT_COMMIT_ITEM_ADD)
       && (item->kind == svn_node_dir)
       && (item->copyfrom_url))

Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1098689&r1=1098688&r2=1098689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Mon May  2 17:48:59 2011
@@ -156,13 +156,26 @@ process_committed_leaf(svn_wc__db_t *db,
       return svn_error_return(
                 svn_wc__db_op_remove_node(
                                 db, local_abspath, 
-                                have_base ? new_revnum : SVN_INVALID_REVNUM,
+                                (have_base && !via_recurse)
+                                    ? new_revnum : SVN_INVALID_REVNUM,
+                                kind,
+                                scratch_pool));
+    }
+  else if (status == svn_wc__db_status_not_present)
+    {
+      /* We are committing the leaf of a copy operation.
+         It is safe to remove this leaf now */
+      return svn_error_return(
+                svn_wc__db_op_remove_node(
+                                db, local_abspath,
+                                (have_base && !via_recurse)
+                                    ? new_revnum : SVN_INVALID_REVNUM,
                                 kind,
                                 scratch_pool));
     }
 
-  if (status == svn_wc__db_status_not_present)
-    return SVN_NO_ERROR; /* Why does this get here? */
+  SVN_ERR_ASSERT(status == svn_wc__db_status_normal
+                 || status == svn_wc__db_status_added);
 
   if (kind != svn_wc__db_kind_dir)
     {

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1098689&r1=1098688&r2=1098689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon May  2 17:48:59 
2011
@@ -170,6 +170,16 @@ WHERE wc_id = ?1
   AND (op_depth < ?3
        OR (op_depth = ?3 AND presence = 'base-deleted'))
 
+-- STMT_COMMIT_DESCENDANT_TO_BASE
+UPDATE NODES SET op_depth = 0, repos_id = ?4, repos_path = ?5, revision = ?6,
+  moved_here = NULL, moved_to = NULL, dav_cache = NULL,
+  presence = CASE WHEN presence IN ('not-present', 'excluded')
+                       AND EXISTS(SELECT 1 FROM NODES WHERE wc_id = ?1 
+                                   AND local_relpath = ?2 AND op_depth > ?3)
+                  THEN 'excluded' ELSE presence END
+WHERE wc_id = ?1 AND local_relpath = ?2 and op_depth = ?3
+  AND presence IN ('normal', 'excluded', 'not-present')
+
 -- STMT_SELECT_NODE_CHILDREN
 /* Return all paths that are children of the directory (?1, ?2) in any
    op-depth, including children of any underlying, replaced directories. */

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1098689&r1=1098688&r2=1098689&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon May  2 17:48:59 2011
@@ -7134,6 +7134,57 @@ determine_repos_info(apr_int64_t *repos_
   return SVN_NO_ERROR;
 }
 
+#ifdef SVN_WC__EXPERIMENTAL_DESCENDANT_COMMIT
+/* Moves all nodes below PARENT_LOCAL_RELPATH from op-depth OP_DEPTH to
+   op-depth 0 (BASE), setting their presence to 'excluded' if their presence
+   wasn't 'normal'. */
+static svn_error_t *
+descendant_commit(svn_wc__db_wcroot_t *wcroot,
+                  const char *parent_local_relpath,
+                  apr_int64_t op_depth,
+                  apr_int64_t repos_id,
+                  const char *parent_repos_relpath,
+                  svn_revnum_t revision,
+                  apr_pool_t *scratch_pool)
+{
+  const apr_array_header_t *children;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  svn_sqlite__stmt_t *stmt;
+  int i;
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                    STMT_COMMIT_DESCENDANT_TO_BASE));
+
+  SVN_ERR(gather_repo_children(&children, wcroot, parent_local_relpath, 
+                               op_depth, scratch_pool, iterpool));
+
+  for (i = 0; i < children->nelts; i++)
+    {
+      const char *local_relpath;
+      const char *repos_relpath;
+      const char *name = APR_ARRAY_IDX(children, i, const char *);
+
+      svn_pool_clear(iterpool);
+
+      local_relpath = svn_relpath_join(parent_local_relpath, name, iterpool);
+      repos_relpath = svn_relpath_join(parent_repos_relpath, name, iterpool);
+      SVN_ERR(svn_sqlite__bindf(stmt, "isiisi",
+                                wcroot->wc_id,
+                                local_relpath,
+                                op_depth,
+                                repos_id,
+                                repos_relpath,
+                                (apr_int64_t)revision));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+
+      SVN_ERR(descendant_commit(wcroot, local_relpath, op_depth, repos_id,
+                                repos_relpath, revision, iterpool));
+    }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+#endif
 
 struct commit_baton_t {
   svn_revnum_t new_revision;
@@ -7275,6 +7326,12 @@ commit_node(void *baton,
 
           SVN_ERR(svn_sqlite__step_done(stmt));
         }
+
+#ifdef SVN_WC__EXPERIMENTAL_DESCENDANT_COMMIT
+      SVN_ERR(descendant_commit(wcroot, local_relpath, op_depth,
+                                repos_id, repos_relpath, cb->new_revision,
+                                scratch_pool));
+#endif
     }
 
   /* Update or add the BASE_NODE row with all the new information.  */


Reply via email to