You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2014/02/15 14:50:35 UTC

svn commit: r1568635 - in /subversion/trunk/subversion: include/svn_client.h include/svn_wc.h libsvn_client/deprecated.c libsvn_client/revert.c libsvn_wc/deprecated.c libsvn_wc/revert.c libsvn_wc/wc.h libsvn_wc/wc_db.c libsvn_wc/wc_db.h

Author: rhuijben
Date: Sat Feb 15 13:50:35 2014
New Revision: 1568635

URL: http://svn.apache.org/r1568635
Log:
Make it possible to clear changelists while reverting nodes by updating the
svn_client_revert2 api.

While this might look like a separate operation, revert does quite some work
to preserve existing changelists during reverts. Making this optional makes
the common revert code more efficient, while at the same time helping GUI
clients that use changelists only for marking changes.

* subversion/include/svn_client.h
  (svn_client_revert3): New function.
  (svn_client_revert2): Deprecate function.
  (svn_client_revert): Use @deprecate as we do it now.

* subversion/include/svn_wc.h
  (svn_wc_revert5): New function.
  (svn_wc_revert4): Deprecate function.

* subversion/libsvn_client/deprecated.c
  (svn_client_revert2): New function.

* subversion/libsvn_client/revert.c
  (revert_with_write_lock_baton): Add variable.
  (revert): Update caller.
  (svn_client_revert2): Rename to ...
  (svn_client_revert3): ... this. Add argument. Update caller.

* subversion/libsvn_wc/deprecated.c
  (svn_wc_revert4): New function.

* subversion/libsvn_wc/revert.c
  (svn_wc__revert_internal): Rename to...
  (revert): ... this. Make static and add argument. Update caller.
  (revert_changelist,
   revert_partial): Add argument. Update caller.
  (svn_wc_revert4): Rename to ...
  (svn_wc_revert5): ... this. Update caller.

* subversion/libsvn_wc/wc.h
  (svn_wc__revert_internal): Remove function that is only used in revert.c.

* subversion/libsvn_wc/wc_db.c
  (revert_baton_t): New struct.
  (op_revert_txn): Use new baton. Handle complete ACTUAL delete.
  (op_revert_recursive_txn): Use baton. Handle complete ACTUAL deletes.
  (svn_wc__db_op_revert): Add argument. Update caller.

* subversion/libsvn_wc/wc_db.h
  (svn_wc__db_op_revert): Add argument.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_wc.h
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/libsvn_client/revert.c
    subversion/trunk/subversion/libsvn_wc/deprecated.c
    subversion/trunk/subversion/libsvn_wc/revert.c
    subversion/trunk/subversion/libsvn_wc/wc.h
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Sat Feb 15 13:50:35 2014
@@ -4258,6 +4258,9 @@ svn_client_relocate(const char *dir,
  * changelists.  If @a changelists is empty (or altogether @c NULL),
  * no changelist filtering occurs.
  *
+ * If @a clear_changelists is TRUE, then changelist information for the
+ * paths is cleared while reverting.
+ *
  * If @a ctx->notify_func2 is non-NULL, then for each item reverted,
  * call @a ctx->notify_func2 with @a ctx->notify_baton2 and the path of
  * the reverted item.
@@ -4266,8 +4269,23 @@ svn_client_relocate(const char *dir,
  * then do not error, just invoke @a ctx->notify_func2 with @a
  * ctx->notify_baton2, using notification code #svn_wc_notify_skip.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_client_revert3(const apr_array_header_t *paths,
+                   svn_depth_t depth,
+                   const apr_array_header_t *changelists,
+                   svn_boolean_t clear_changelists,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool);
+
+/** Similar to svn_client_revert2, but with @a clear_changelists set to
+ * FALSE.
+ *
  * @since New in 1.5.
+ * @deprecated Provided for backwards compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_revert2(const apr_array_header_t *paths,
                    svn_depth_t depth,
@@ -4285,7 +4303,7 @@ svn_client_revert2(const apr_array_heade
  * @note Most APIs map @a recurse==FALSE to @a depth==svn_depth_files;
  * revert is deliberately different.
  *
- * @deprecated Provided for backwards compatibility with the 1.0 API.
+ * @deprecated Provided for backwards compatibility with the 1.4 API.
  */
 SVN_DEPRECATED
 svn_error_t *

Modified: subversion/trunk/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_wc.h?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_wc.h (original)
+++ subversion/trunk/subversion/include/svn_wc.h Sat Feb 15 13:50:35 2014
@@ -7610,6 +7610,9 @@ svn_wc_relocate(const char *path,
  * changelists.  If @a changelist_filter is empty (or altogether @c NULL),
  * no changelist filtering occurs.
  *
+ * If @a clear_changelists is TRUE, then changelist information for the
+ * paths is cleared.
+ *
  * If @a cancel_func is non-NULL, call it with @a cancel_baton at
  * various points during the reversion process.  If it returns an
  * error (typically #SVN_ERR_CANCELLED), return that error
@@ -7626,8 +7629,28 @@ svn_wc_relocate(const char *path,
  * If @a path is not under version control, return the error
  * #SVN_ERR_UNVERSIONED_RESOURCE.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_wc_revert5(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_depth_t depth,
+               svn_boolean_t use_commit_times,
+               const apr_array_header_t *changelist_filter,
+               svn_boolean_t clear_changelists,
+               svn_cancel_func_t cancel_func,
+               void *cancel_baton,
+               svn_wc_notify_func2_t notify_func,
+               void *notify_baton,
+               apr_pool_t *scratch_pool);
+
+/** Similar to svn_wc_revert5() but with @a clear_changelists always set to
+ * FALSE.
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_revert4(svn_wc_context_t *wc_ctx,
                const char *local_abspath,

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Sat Feb 15 13:50:35 2014
@@ -2810,6 +2810,21 @@ svn_client_resolved(const char *path,
 }
 /*** From revert.c ***/
 svn_error_t *
+svn_client_revert2(const apr_array_header_t *paths,
+                   svn_depth_t depth,
+                   const apr_array_header_t *changelists,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  return svn_error_trace(svn_client_revert3(paths,
+                                            depth,
+                                            changelists,
+                                            FALSE /* clear_changelists */,
+                                            ctx,
+                                            pool));
+}
+
+svn_error_t *
 svn_client_revert(const apr_array_header_t *paths,
                   svn_boolean_t recursive,
                   svn_client_ctx_t *ctx,

Modified: subversion/trunk/subversion/libsvn_client/revert.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/revert.c?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/revert.c (original)
+++ subversion/trunk/subversion/libsvn_client/revert.c Sat Feb 15 13:50:35 2014
@@ -48,6 +48,7 @@ struct revert_with_write_lock_baton {
   svn_depth_t depth;
   svn_boolean_t use_commit_times;
   const apr_array_header_t *changelists;
+  svn_boolean_t clear_changelists;
   svn_client_ctx_t *ctx;
 };
 
@@ -77,11 +78,12 @@ revert(void *baton, apr_pool_t *result_p
   struct revert_with_write_lock_baton *b = baton;
   svn_error_t *err;
 
-  err = svn_wc_revert4(b->ctx->wc_ctx,
+  err = svn_wc_revert5(b->ctx->wc_ctx,
                        b->local_abspath,
                        b->depth,
                        b->use_commit_times,
                        b->changelists,
+                       b->clear_changelists,
                        b->ctx->cancel_func, b->ctx->cancel_baton,
                        b->ctx->notify_func2, b->ctx->notify_baton2,
                        scratch_pool);
@@ -111,9 +113,10 @@ revert(void *baton, apr_pool_t *result_p
 
 
 svn_error_t *
-svn_client_revert2(const apr_array_header_t *paths,
+svn_client_revert3(const apr_array_header_t *paths,
                    svn_depth_t depth,
                    const apr_array_header_t *changelists,
+                   svn_boolean_t clear_changelists,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *pool)
 {
@@ -167,6 +170,7 @@ svn_client_revert2(const apr_array_heade
       baton.depth = depth;
       baton.use_commit_times = use_commit_times;
       baton.changelists = changelists;
+      baton.clear_changelists = clear_changelists;
       baton.ctx = ctx;
 
       err = svn_wc__is_wcroot(&wc_root, ctx->wc_ctx, local_abspath, pool);

Modified: subversion/trunk/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/deprecated.c?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_wc/deprecated.c Sat Feb 15 13:50:35 2014
@@ -1037,6 +1037,29 @@ svn_wc_add(const char *path,
                      compat_call_notify_func, &nb, pool);
 }
 
+/*** From revert.c ***/
+svn_error_t *
+svn_wc_revert4(svn_wc_context_t *wc_ctx,
+               const char *local_abspath,
+               svn_depth_t depth,
+               svn_boolean_t use_commit_times,
+               const apr_array_header_t *changelist_filter,
+               svn_cancel_func_t cancel_func,
+               void *cancel_baton,
+               svn_wc_notify_func2_t notify_func,
+               void *notify_baton,
+               apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_wc_revert5(wc_ctx, local_abspath,
+                                        depth,
+                                        use_commit_times,
+                                        changelist_filter,
+                                        FALSE /* clear_changelists*/,
+                                        cancel_func, cancel_baton,
+                                        notify_func, notify_baton,
+                                        scratch_pool));
+}
+
 svn_error_t *
 svn_wc_revert3(const char *path,
                svn_wc_adm_access_t *parent_access,

Modified: subversion/trunk/subversion/libsvn_wc/revert.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/revert.c?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/revert.c (original)
+++ subversion/trunk/subversion/libsvn_wc/revert.c Sat Feb 15 13:50:35 2014
@@ -635,17 +635,18 @@ revert_restore(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_wc__revert_internal(svn_wc__db_t *db,
-                        const char *local_abspath,
-                        svn_depth_t depth,
-                        svn_boolean_t use_commit_times,
-                        svn_cancel_func_t cancel_func,
-                        void *cancel_baton,
-                        svn_wc_notify_func2_t notify_func,
-                        void *notify_baton,
-                        apr_pool_t *scratch_pool)
+/* Revert tree LOCAL_ABSPATH to depth DEPTH and notify for all reverts. */
+static svn_error_t *
+revert(svn_wc__db_t *db,
+       const char *local_abspath,
+       svn_depth_t depth,
+       svn_boolean_t use_commit_times,
+       svn_boolean_t clear_changelists,
+       svn_cancel_func_t cancel_func,
+       void *cancel_baton,
+       svn_wc_notify_func2_t notify_func,
+       void *notify_baton,
+       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
 
@@ -667,7 +668,7 @@ svn_wc__revert_internal(svn_wc__db_t *db
     SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
   }
 
-  err = svn_wc__db_op_revert(db, local_abspath, depth,
+  err = svn_wc__db_op_revert(db, local_abspath, depth, clear_changelists,
                              scratch_pool, scratch_pool);
 
   if (!err)
@@ -694,6 +695,7 @@ revert_changelist(svn_wc__db_t *db,
                   svn_depth_t depth,
                   svn_boolean_t use_commit_times,
                   apr_hash_t *changelist_hash,
+                  svn_boolean_t clear_changelists,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
                   svn_wc_notify_func2_t notify_func,
@@ -710,11 +712,11 @@ revert_changelist(svn_wc__db_t *db,
   /* Revert this node (depth=empty) if it matches one of the changelists.  */
   if (svn_wc__internal_changelist_match(db, local_abspath, changelist_hash,
                                         scratch_pool))
-    SVN_ERR(svn_wc__revert_internal(db, local_abspath,
-                                    svn_depth_empty, use_commit_times,
-                                    cancel_func, cancel_baton,
-                                    notify_func, notify_baton,
-                                    scratch_pool));
+    SVN_ERR(revert(db, local_abspath,
+                   svn_depth_empty, use_commit_times, clear_changelists,
+                   cancel_func, cancel_baton,
+                   notify_func, notify_baton,
+                   scratch_pool));
 
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
@@ -746,6 +748,7 @@ revert_changelist(svn_wc__db_t *db,
 
       SVN_ERR(revert_changelist(db, child_abspath, depth,
                                 use_commit_times, changelist_hash,
+                                clear_changelists,
                                 cancel_func, cancel_baton,
                                 notify_func, notify_baton,
                                 iterpool));
@@ -770,6 +773,7 @@ revert_partial(svn_wc__db_t *db,
                const char *local_abspath,
                svn_depth_t depth,
                svn_boolean_t use_commit_times,
+               svn_boolean_t clear_changelists,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                svn_wc_notify_func2_t notify_func,
@@ -789,9 +793,10 @@ revert_partial(svn_wc__db_t *db,
 
   /* Revert the root node itself (depth=empty), then move on to the
      children.  */
-  SVN_ERR(svn_wc__revert_internal(db, local_abspath, svn_depth_empty,
-                                  use_commit_times, cancel_func, cancel_baton,
-                                  notify_func, notify_baton, iterpool));
+  SVN_ERR(revert(db, local_abspath, svn_depth_empty,
+                 use_commit_times, clear_changelists,
+                 cancel_func, cancel_baton,
+                 notify_func, notify_baton, iterpool));
 
   SVN_ERR(svn_wc__db_read_children_of_working_node(&children, db,
                                                    local_abspath,
@@ -822,11 +827,11 @@ revert_partial(svn_wc__db_t *db,
         }
 
       /* Revert just this node (depth=empty).  */
-      SVN_ERR(svn_wc__revert_internal(db, child_abspath,
-                                      svn_depth_empty, use_commit_times,
-                                      cancel_func, cancel_baton,
-                                      notify_func, notify_baton,
-                                      iterpool));
+      SVN_ERR(revert(db, child_abspath,
+                     svn_depth_empty, use_commit_times, clear_changelists,
+                     cancel_func, cancel_baton,
+                     notify_func, notify_baton,
+                     iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -836,11 +841,12 @@ revert_partial(svn_wc__db_t *db,
 
 
 svn_error_t *
-svn_wc_revert4(svn_wc_context_t *wc_ctx,
+svn_wc_revert5(svn_wc_context_t *wc_ctx,
                const char *local_abspath,
                svn_depth_t depth,
                svn_boolean_t use_commit_times,
                const apr_array_header_t *changelist_filter,
+               svn_boolean_t clear_changelists,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                svn_wc_notify_func2_t notify_func,
@@ -856,17 +862,18 @@ svn_wc_revert4(svn_wc_context_t *wc_ctx,
       return svn_error_trace(revert_changelist(wc_ctx->db, local_abspath,
                                                depth, use_commit_times,
                                                changelist_hash,
+                                               clear_changelists,
                                                cancel_func, cancel_baton,
                                                notify_func, notify_baton,
                                                scratch_pool));
     }
 
   if (depth == svn_depth_empty || depth == svn_depth_infinity)
-    return svn_error_trace(svn_wc__revert_internal(wc_ctx->db, local_abspath,
-                                                   depth, use_commit_times,
-                                                   cancel_func, cancel_baton,
-                                                   notify_func, notify_baton,
-                                                   scratch_pool));
+    return svn_error_trace(revert(wc_ctx->db, local_abspath,
+                                  depth, use_commit_times, clear_changelists,
+                                  cancel_func, cancel_baton,
+                                  notify_func, notify_baton,
+                                  scratch_pool));
 
   /* The user may expect svn_depth_files/svn_depth_immediates to work
      on copied dirs with one level of children.  It doesn't, the user
@@ -877,6 +884,7 @@ svn_wc_revert4(svn_wc_context_t *wc_ctx,
   if (depth == svn_depth_files || depth == svn_depth_immediates)
     return svn_error_trace(revert_partial(wc_ctx->db, local_abspath,
                                           depth, use_commit_times,
+                                          clear_changelists,
                                           cancel_func, cancel_baton,
                                           notify_func, notify_baton,
                                           scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc.h?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc.h Sat Feb 15 13:50:35 2014
@@ -782,19 +782,6 @@ svn_wc__externals_find_target_dups(apr_a
                                    apr_pool_t *pool,
                                    apr_pool_t *scratch_pool);
 
-/* Revert tree LOCAL_ABSPATH to depth DEPTH and notify for all
-   reverts. */
-svn_error_t *
-svn_wc__revert_internal(svn_wc__db_t *db,
-                        const char *local_abspath,
-                        svn_depth_t depth,
-                        svn_boolean_t use_commit_times,
-                        svn_cancel_func_t cancel_func,
-                        void *cancel_baton,
-                        svn_wc_notify_func2_t notify_func,
-                        void *notify_baton,
-                        apr_pool_t *scratch_pool);
-
 svn_error_t *
 svn_wc__node_has_local_mods(svn_boolean_t *modified,
                             svn_boolean_t *all_edits_are_deletes,

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sat Feb 15 13:50:35 2014
@@ -6443,6 +6443,13 @@ clear_moved_to(svn_wc__db_wcroot_t *wcro
   return SVN_NO_ERROR;
 }
 
+/* Baton for op_revert_txn and op_revert_recursive_txn */
+struct revert_baton_t
+{
+  svn_wc__db_t *db;
+  svn_boolean_t clear_changelists;
+};
+
 /* One of the two alternative bodies of svn_wc__db_op_revert().
  *
  * Implements svn_wc__db_txn_callback_t. */
@@ -6452,7 +6459,8 @@ op_revert_txn(void *baton,
               const char *local_relpath,
               apr_pool_t *scratch_pool)
 {
-  svn_wc__db_t *db = baton;
+  struct revert_baton_t *rvb = baton;
+  svn_wc__db_t *db = rvb->db;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   int op_depth;
@@ -6597,16 +6605,26 @@ op_revert_txn(void *baton,
         SVN_ERR(clear_moved_to(wcroot, local_relpath, scratch_pool));
     }
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                  STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
-  if (!affected_rows)
+  if (rvb->clear_changelists)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_NODE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+    }
+  else
     {
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                    STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST));
+                                  STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
       SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      if (!affected_rows)
+        {
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                  STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST));
+          SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+          SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+        }
     }
 
   return SVN_NO_ERROR;
@@ -6622,6 +6640,7 @@ op_revert_recursive_txn(void *baton,
                         const char *local_relpath,
                         apr_pool_t *scratch_pool)
 {
+  struct revert_baton_t *rvb = baton;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   int op_depth;
@@ -6703,17 +6722,28 @@ op_revert_recursive_txn(void *baton,
                             local_relpath, select_op_depth));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
-  SVN_ERR(svn_sqlite__get_statement(
-                    &stmt, wcroot->sdb,
-                    STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
-  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,
-                    STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-  SVN_ERR(svn_sqlite__step_done(stmt));
+  if (rvb->clear_changelists)
+    {
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, wcroot->sdb,
+                        STMT_DELETE_ACTUAL_NODE_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+  else
+    {
+      SVN_ERR(svn_sqlite__get_statement(
+                        &stmt, wcroot->sdb,
+                        STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
+      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,
+                        STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
 
   /* ### This removes the locks, but what about the access batons? */
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -6760,22 +6790,27 @@ svn_error_t *
 svn_wc__db_op_revert(svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_depth_t depth,
+                     svn_boolean_t clear_changelists,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
+  struct revert_baton_t rvb;
   struct with_triggers_baton_t wtb = { STMT_CREATE_REVERT_LIST,
                                        STMT_DROP_REVERT_LIST_TRIGGERS,
                                        NULL, NULL};
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  rvb.db = db;
+  rvb.clear_changelists = clear_changelists;
+  wtb.cb_baton = &rvb;
+
   switch (depth)
     {
     case svn_depth_empty:
       wtb.cb_func = op_revert_txn;
-      wtb.cb_baton = db;
       break;
     case svn_depth_infinity:
       wtb.cb_func = op_revert_recursive_txn;

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1568635&r1=1568634&r2=1568635&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Sat Feb 15 13:50:35 2014
@@ -1615,6 +1615,9 @@ svn_wc__db_op_mark_resolved(svn_wc__db_t
  *
  * At present only depth=empty and depth=infinity are supported.
  *
+ * If @a clear_changelists is FALSE then changelist information is kept,
+ * otherwise it is cleared.
+ *
  * This function populates the revert list that can be queried to
  * determine what was reverted.
  */
@@ -1622,6 +1625,7 @@ svn_error_t *
 svn_wc__db_op_revert(svn_wc__db_t *db,
                      const char *local_abspath,
                      svn_depth_t depth,
+                     svn_boolean_t clear_changelists,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool);