You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/09/09 22:26:52 UTC

svn commit: r995566 [12/16] - in /subversion/branches/atomic-revprop: ./ build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversi...

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/wc_db.h Thu Sep  9 20:26:46 2010
@@ -126,7 +126,7 @@ typedef struct svn_wc__db_t svn_wc__db_t
 
 
 /* Enumerated constants for how to open a WC datastore.  */
-typedef enum {
+typedef enum svn_wc__db_openmode_t {
   svn_wc__db_openmode_default,    /* Open in the default mode (r/w now). */
   svn_wc__db_openmode_readonly,   /* Changes will definitely NOT be made. */
   svn_wc__db_openmode_readwrite   /* Changes will definitely be made. */
@@ -148,7 +148,7 @@ typedef enum {
    ###   cannot simply be added. it would surprise too much code.
    ###   (we could probably create svn_node_kind2_t though)
 */
-typedef enum {
+typedef enum svn_wc__db_kind_t {
     /* The node is a directory. */
     svn_wc__db_kind_dir,
 
@@ -162,20 +162,11 @@ typedef enum {
        deletion, or incomplete status. */
     svn_wc__db_kind_unknown,
 
-    /* This directory node is a placeholder; the actual information is
-       held within the subdirectory.
-
-       Note: users of this API shouldn't see this kind. It will be
-       handled internally to wc_db.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_kind_subdir
-
 } svn_wc__db_kind_t;
 
 
 /* Enumerated values describing the state of a node. */
-typedef enum {
+typedef enum svn_wc__db_status_t {
     /* The node is present and has no known modifications applied to it. */
     svn_wc__db_status_normal,
 
@@ -202,32 +193,6 @@ typedef enum {
        will be present. */
     svn_wc__db_status_deleted,
 
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       This is only returned by an unshadowed BASE node. If a WORKING node
-       is present, then obstructed_delete or obstructed_add is returned as
-       appropriate.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed,
-
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       The directory has been marked for deletion.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed_delete,
-
-    /* The information for this directory node is obstructed by something
-       in the local filesystem. Full details are not available.
-
-       The directory has been marked for addition.
-
-       ### only used with per-dir .svn subdirectories.  */
-    svn_wc__db_status_obstructed_add,
-
     /* This node was named by the server, but no information was provided. */
     svn_wc__db_status_absent,
 
@@ -259,7 +224,7 @@ typedef enum {
 
 /* Lock information.  We write/read it all as one, so let's use a struct
    for convenience.  */
-typedef struct {
+typedef struct svn_wc__db_lock_t {
   /* The lock token */
   const char *token;
 
@@ -347,13 +312,17 @@ svn_wc__db_close(svn_wc__db_t *db);
    A REPOSITORY row will be constructed for the repository identified by
    REPOS_ROOT_URL and REPOS_UUID. Neither of these may be NULL.
 
-   A node will be created for the directory at REPOS_RELPATH will be added.
+   A BASE_NODE row will be created for the directory at REPOS_RELPATH at
+   revision INITIAL_REV.
    If INITIAL_REV is greater than zero, then the node will be marked as
    "incomplete" because we don't know its children. Contrary, if the
    INITIAL_REV is zero, then this directory should represent the root and
    we know it has no children, so the node is complete.
 
-   DEPTH is the initial depth of the working copy, it must be a definite
+   ### Is there any benefit to marking it 'complete' if rev==0?  Seems like
+   ### an unnecessary special case.
+
+   DEPTH is the initial depth of the working copy; it must be a definite
    depth, not svn_depth_unknown.
 
    Use SCRATCH_POOL for temporary allocations.
@@ -422,6 +391,25 @@ svn_wc__db_get_wcroot(const char **wcroo
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool);
 
+typedef svn_error_t * (*svn_wc__db_sqlite_lock_cb)(svn_wc__db_t *db,
+                                                   void *baton,
+                                                   apr_pool_t *scratch_pool);
+
+/* Obtain a sqlite lock to efficiently use the working copy database for
+   WRI_ABSPATH and call LOCK_CB with CB_BATON while this lock exist.
+
+   On returning from this function all operations will be committed, but
+   operations might have been committed before returning from this function.
+
+   ### See svn_sqlite__with_lock() for more details.
+ */
+svn_error_t *
+svn_wc__db_with_sqlite_lock(svn_wc__db_t *db,
+                            const char *wri_abspath,
+                            svn_wc__db_sqlite_lock_cb lock_cb,
+                            void *cb_baton,
+                            apr_pool_t *scratch_pool);
+
 /* @} */
 
 /* Different kinds of trees
@@ -434,11 +422,16 @@ svn_wc__db_get_wcroot(const char **wcroo
 
 /* @defgroup svn_wc__db_base  BASE tree management
 
-   BASE should be what we get from the server. The *absolute* pristine copy.
-   Nothing can change it -- it is always a reflection of the repository.
+   BASE is what we get from the server.  It is the *absolute* pristine copy.
    You need to use checkout, update, switch, or commit to alter your view of
    the repository.
 
+   In the BASE tree, each node corresponds to a particular node-rev in the
+   repository.  It can be a mixed-revision tree.  Each node holds either a
+   copy of the node-rev as it exists in the repository (if presence =
+   'normal'), or a place-holder (if presence = 'absent' or 'excluded' or
+   'not-present').
+
    @{
 */
 
@@ -1669,15 +1662,11 @@ svn_wc__db_is_wcroot(svn_boolean_t *is_r
 
    ### Assuming the future ability to copy across repositories, should we
    ### refrain from resetting the copyfrom information in this operation?
-
-   ### SINGLE_DB is a temp argument, and should be TRUE if using compressed
-   ### metadata.  When *all* metadata gets compressed, it should disappear.
 */
 svn_error_t *
 svn_wc__db_global_relocate(svn_wc__db_t *db,
                            const char *local_dir_abspath,
                            const char *repos_root_url,
-                           svn_boolean_t single_db,
                            apr_pool_t *scratch_pool);
 
 
@@ -2047,6 +2036,7 @@ svn_wc__db_upgrade_begin(svn_sqlite__db_
 
 svn_error_t *
 svn_wc__db_upgrade_apply_dav_cache(svn_sqlite__db_t *sdb,
+                                   const char *dir_relpath,
                                    apr_hash_t *cache_values,
                                    apr_pool_t *scratch_pool);
 
@@ -2209,28 +2199,6 @@ svn_wc__db_temp_forget_directory(svn_wc_
                                  apr_pool_t *scratch_pool);
 
 
-/* A temporary API similar to svn_wc__db_base_add_directory() and
-   svn_wc__db_base_add_file(), in that it adds a subdirectory to the given
-   DB.  * Arguments are the same as those to svn_wc__db_base_add_directory().
-
-   Note: Since the subdir node type is a fiction created to satisfy our
-   current backward-compat hacks, this is a temporary API expected to
-   disappear with that node type does.
-*/
-svn_error_t *
-svn_wc__db_temp_base_add_subdir(svn_wc__db_t *db,
-                                const char *local_abspath,
-                                const char *repos_relpath,
-                                const char *repos_root_url,
-                                const char *repos_uuid,
-                                svn_revnum_t revision,
-                                const apr_hash_t *props,
-                                svn_revnum_t changed_rev,
-                                apr_time_t changed_date,
-                                const char *changed_author,
-                                svn_depth_t depth,
-                                apr_pool_t *scratch_pool);
-
 svn_error_t *
 svn_wc__db_temp_is_dir_deleted(svn_boolean_t *not_present,
                                svn_revnum_t *base_revision,
@@ -2399,11 +2367,13 @@ svn_wc__db_temp_get_file_external(const 
                                   apr_pool_t *scratch_pool);
 
 
+#ifndef SVN_WC__SINGLE_DB
 /* Remove a stray "subdir" record in the BASE_NODE table.  */
 svn_error_t *
 svn_wc__db_temp_remove_subdir_record(svn_wc__db_t *db,
                                      const char *local_abspath,
                                      apr_pool_t *scratch_pool);
+#endif
 
 /* Set file external information on LOCAL_ABSPATH to REPOS_RELPATH
    at PEG_REV with revision REV*/
@@ -2433,6 +2403,7 @@ svn_wc__db_temp_op_set_property_conflict
                                                      const char *prej_basename,
                                                      apr_pool_t *scratch_pool);
 
+#ifndef SVN_WC__SINGLE_DB
 /* Ensure that the parent stub of LOCAL_ABSPATH contains a BASE_NODE record with
    a normal status and optionally remove the WORKING_NODE record for the node;
    this assumes that the parent directory is in the incomplete state, or the
@@ -2446,11 +2417,14 @@ svn_wc__db_temp_set_parent_stub_to_norma
                                           const char *local_abspath,
                                           svn_boolean_t delete_working,
                                           apr_pool_t *scratch_pool);
+#endif
 
 /* Sets a base nodes revision and/or repository relative path. If
    LOCAL_ABSPATH's rev (REV) is valid, set is revision and if SET_REPOS_RELPATH
    is TRUE set its repository relative path to REPOS_RELPATH (and make sure its
    REPOS_ROOT_URL and REPOS_ROOT_UUID are still valid).
+
+   ### TODO(SINGLE_DB): Remove the 'update_stub' argument.
  */
 svn_error_t *
 svn_wc__db_temp_op_set_rev_and_repos_relpath(svn_wc__db_t *db,
@@ -2490,17 +2464,6 @@ svn_wc__db_drop_root(svn_wc__db_t *db,
                      const char *local_abspath,
                      apr_pool_t *scratch_pool);
 
-/* Internal version of svn_wc__node_get_copyfrom_info */
-svn_error_t *
-svn_wc__internal_get_copyfrom_info(const char **copyfrom_root_url,
-                                   const char **copyfrom_repos_relpath,
-                                   const char **copyfrom_url,
-                                   svn_revnum_t *copyfrom_rev,
-                                   svn_boolean_t *is_copy_target,
-                                   svn_wc__db_t *db,
-                                   const char *local_abspath,
-                                   apr_pool_t *result_pool,
-                                   apr_pool_t *scratch_pool);
 /* @} */
 
 

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.c Thu Sep  9 20:26:46 2010
@@ -49,7 +49,6 @@
  *   (local_abspath, revnum, date, [author], [checksum],
  *    [dav_cache/wc_props], keep_changelist, [tmp_text_base_abspath]). */
 #define OP_POSTCOMMIT "postcommit"
-#define OP_INSTALL_PROPERTIES "install-properties-2"
 #define OP_FILE_INSTALL "file-install"
 #define OP_FILE_REMOVE "file-remove"
 #define OP_FILE_MOVE "file-move"
@@ -60,6 +59,7 @@
 #define OP_TMP_SET_TEXT_CONFLICT_MARKERS "tmp-set-text-conflict-markers"
 #define OP_TMP_SET_PROPERTY_CONFLICT_MARKER "tmp-set-property-conflict-marker"
 #define OP_PRISTINE_GET_TRANSLATED "pristine-get-translated"
+#define OP_POSTUPGRADE "postupgrade"
 
 /* For work queue debugging. Generates output about its operation.  */
 /* #define DEBUG_WORK_QUEUE */
@@ -184,6 +184,7 @@ run_revert(svn_wc__db_t *db,
   const char *local_abspath;
   svn_boolean_t replaced;
   svn_wc__db_kind_t kind;
+  svn_wc__db_status_t status;
   const char *parent_abspath;
   svn_boolean_t conflicted;
 
@@ -197,7 +198,7 @@ run_revert(svn_wc__db_t *db,
      (yet) allowed. If we read any conflict files, then we (obviously) have
      not removed them from the metadata (yet).  */
   SVN_ERR(svn_wc__db_read_info(
-            NULL, &kind, NULL, NULL, NULL, NULL,
+            &status, &kind, NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
             &conflicted, NULL,
@@ -349,8 +350,22 @@ run_revert(svn_wc__db_t *db,
     /* ### A working copy root can't have a working node and trying
        ### to delete it fails because the root doesn't have a stub. */
     if (!is_wc_root)
-      SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
-                                                scratch_pool));
+      {
+        const char *op_root_abspath = NULL;
+
+        /* If the node is not the operation root, we should not delete
+           the working node */
+        if (status == svn_wc__db_status_added)
+          SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
+                                           NULL, NULL, NULL, NULL, NULL,
+                                           db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+        if (!op_root_abspath
+            || (strcmp(op_root_abspath, local_abspath) == 0))
+          SVN_ERR(svn_wc__db_temp_op_remove_working(db, local_abspath,
+                                                    scratch_pool));
+      }
   }
 
   return SVN_NO_ERROR;
@@ -369,14 +384,6 @@ verify_pristine_present(svn_wc__db_t *db
 {
   const svn_checksum_t *base_checksum;
 
-  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL,
-                                   &base_checksum, NULL, NULL, NULL,
-                                   db, local_abspath,
-                                   scratch_pool, scratch_pool));
-  if (base_checksum != NULL)
-    return SVN_NO_ERROR;
-
   SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, &base_checksum,
                                NULL, NULL, NULL, NULL, NULL, NULL,
@@ -386,6 +393,14 @@ verify_pristine_present(svn_wc__db_t *db
   if (base_checksum != NULL)
     return SVN_NO_ERROR;
 
+  SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+                                   NULL, NULL, NULL, NULL, NULL,
+                                   &base_checksum, NULL, NULL, NULL,
+                                   db, local_abspath,
+                                   scratch_pool, scratch_pool));
+  if (base_checksum != NULL)
+    return SVN_NO_ERROR;
+
   /* A real file must have either a regular or a revert text-base.
      If it has neither, we could be looking at the situation described
      in issue #2101, in which case all we can do is deliver the expected
@@ -719,7 +734,9 @@ remove_base_node(svn_wc__db_t *db,
 
   if (base_status == svn_wc__db_status_normal
       && wrk_status != svn_wc__db_status_added
+#ifndef SVN_WC__SINGLE_DB
       && wrk_status != svn_wc__db_status_obstructed_add
+#endif
       && wrk_status != svn_wc__db_status_excluded)
     {
 #ifndef SVN_WC__SINGLE_DB
@@ -756,7 +773,9 @@ remove_base_node(svn_wc__db_t *db,
       SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath, scratch_pool));
     }
   else if (wrk_status == svn_wc__db_status_added
+#ifndef SVN_WC__SINGLE_DB
            || wrk_status == svn_wc__db_status_obstructed_add
+#endif
            || (have_work && wrk_status == svn_wc__db_status_excluded))
     /* ### deletes of working additions should fall in this case, but
        ### we can't express these without the 4th tree */
@@ -1279,7 +1298,10 @@ log_do_committed(svn_wc__db_t *db,
 
           /* Committing a deletion should remove the local nodes.  */
           if (child_status == svn_wc__db_status_deleted
-              || child_status == svn_wc__db_status_obstructed_delete)
+#ifndef SVN_WC__SINGLE_DB
+              || child_status == svn_wc__db_status_obstructed_delete
+#endif
+              )
             {
               SVN_ERR(svn_wc__internal_remove_from_revision_control(
                         db, child_abspath,
@@ -1321,9 +1343,6 @@ log_do_committed(svn_wc__db_t *db,
                 set_read_write = TRUE;
             }
         }
-
-      /* Install LOCAL_ABSPATHs working props as base props. */
-      SVN_ERR(svn_wc__working_props_committed(db, local_abspath, pool));
     }
 
   /* If it's a file, install the tree changes and the file's text. */
@@ -1445,9 +1464,11 @@ log_do_committed(svn_wc__db_t *db,
       return SVN_NO_ERROR;
   }
 
+#ifndef SVN_WC__SINGLE_DB
   /* Make sure we have a parent stub in a clean/unmodified state.  */
   SVN_ERR(svn_wc__db_temp_set_parent_stub_to_normal(db, local_abspath,
                                                     TRUE, scratch_pool));
+#endif
 
   return SVN_NO_ERROR;
 }
@@ -1590,118 +1611,33 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
 }
 
 /* ------------------------------------------------------------------------ */
+/* OP_POSTUPGRADE  */
 
-/* OP_INSTALL_PROPERTIES */
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-
-/* Process the OP_INSTALL_PROPERTIES work item WORK_ITEM.
- * See svn_wc__wq_add_install_properties() which generates this work item.
- * Implements (struct work_item_dispatch).func. */
 static svn_error_t *
-run_install_properties(svn_wc__db_t *db,
-                       const svn_skel_t *work_item,
-                       const char *wri_abspath,
-                       svn_cancel_func_t cancel_func,
-                       void *cancel_baton,
-                       apr_pool_t *scratch_pool)
+run_postupgrade(svn_wc__db_t *db,
+                const svn_skel_t *work_item,
+                const char *wri_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
 {
-  const svn_skel_t *arg = work_item->children->next;
-  const char *local_abspath;
-  apr_hash_t *base_props;
-  apr_hash_t *actual_props;
-
-  /* We need a NUL-terminated path, so copy it out of the skel.  */
-  local_abspath = apr_pstrmemdup(scratch_pool, arg->data, arg->len);
-
-  arg = arg->next;
-  if (arg->is_atom)
-    base_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&base_props, arg, scratch_pool));
-
-  arg = arg->next;
-  if (arg->is_atom)
-    actual_props = NULL;
-  else
-    SVN_ERR(svn_skel__parse_proplist(&actual_props, arg, scratch_pool));
-
-  if (base_props != NULL)
-    {
-        svn_boolean_t written = FALSE;
-
-          {
-            svn_error_t *err;
-
-            /* Try writing to the WORKING tree first.  */
-            err = svn_wc__db_temp_working_set_props(db, local_abspath,
-                                                    base_props,
-                                                    scratch_pool);
-            if (err)
-              {
-                if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-                  return svn_error_return(err);
-                svn_error_clear(err);
-                /* The WORKING node is not present.  */
-              }
-            else
-              {
-                /* The WORKING node is present, and we wrote the props.  */
-                written = TRUE;
-              }
-          }
-
-        if (!written)
-          SVN_ERR(svn_wc__db_temp_base_set_props(db, local_abspath,
-                                                 base_props, scratch_pool));
-    }
-
-  /* Okay. It's time to save the ACTUAL props.  */
-  SVN_ERR(svn_wc__db_op_set_props(db, local_abspath, actual_props,
-                                  NULL, NULL, scratch_pool));
+  SVN_ERR(svn_wc__wipe_postupgrade(wri_abspath, FALSE,
+                                   cancel_func, cancel_baton, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *base_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool)
+svn_wc__wq_build_postupgrade(svn_skel_t **work_item,
+                             apr_pool_t *result_pool)
 {
-  svn_skel_t *work_item = svn_skel__make_empty_list(scratch_pool);
-  svn_skel_t *props;
-
-  if (actual_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, actual_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  if (base_props != NULL)
-    {
-      SVN_ERR(svn_skel__unparse_proplist(&props, base_props, scratch_pool));
-      svn_skel__prepend(props, work_item);
-    }
-  else
-    svn_skel__prepend_str("", work_item, scratch_pool);
-
-  svn_skel__prepend_str(local_abspath, work_item, scratch_pool);
-  svn_skel__prepend_str(OP_INSTALL_PROPERTIES, work_item, scratch_pool);
+  *work_item = svn_skel__make_empty_list(result_pool);
 
-  SVN_ERR(svn_wc__db_wq_add(db, local_abspath, work_item, scratch_pool));
+  svn_skel__prepend_str(OP_POSTUPGRADE, *work_item, result_pool);
 
   return SVN_NO_ERROR;
 }
 
-#endif /* SVN__SUPPORT_BASE_MERGE  */
-
-
 /* ------------------------------------------------------------------------ */
 
 /* OP_FILE_INSTALL */
@@ -2486,16 +2422,12 @@ static const struct work_item_dispatch d
   { OP_TMP_SET_TEXT_CONFLICT_MARKERS, run_set_text_conflict_markers },
   { OP_TMP_SET_PROPERTY_CONFLICT_MARKER, run_set_property_conflict_marker },
   { OP_PRISTINE_GET_TRANSLATED, run_pristine_get_translated },
+  { OP_POSTUPGRADE, run_postupgrade },
 
 #ifndef SVN_WC__SINGLE_DB
   { OP_KILLME, run_killme },
 #endif
 
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
-  { OP_INSTALL_PROPERTIES, run_install_properties },
-#endif
-
   /* Sentinel.  */
   { NULL }
 };

Modified: subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.h?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/atomic-revprop/subversion/libsvn_wc/workqueue.h Thu Sep  9 20:26:46 2010
@@ -301,17 +301,9 @@ svn_wc__wq_add_postcommit(svn_wc__db_t *
                           svn_boolean_t no_unlock,
                           apr_pool_t *scratch_pool);
 
-
-/* See props.h  */
-#ifdef SVN__SUPPORT_BASE_MERGE
 svn_error_t *
-svn_wc__wq_add_install_properties(svn_wc__db_t *db,
-                                  const char *local_abspath,
-                                  apr_hash_t *pristine_props,
-                                  apr_hash_t *actual_props,
-                                  apr_pool_t *scratch_pool);
-#endif
-
+svn_wc__wq_build_postupgrade(svn_skel_t **work_item,
+                             apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/dav_svn.h Thu Sep  9 20:26:46 2010
@@ -37,6 +37,7 @@
 #include "svn_path.h"
 #include "svn_xml.h"
 #include "private/svn_dav_protocol.h"
+#include "private/svn_skel.h"
 #include "mod_authz_svn.h"
 
 #ifdef __cplusplus
@@ -419,7 +420,7 @@ dav_svn__store_activity(const dav_svn_re
                         const char *txn_name);
 
 
-/* HTTP protocol v2:  client does POST against 'me' resource. */
+/* POST request handler.  (Used by HTTP protocol v2 clients only.)  */
 int dav_svn__method_post(request_rec *r);
 
 
@@ -640,6 +641,23 @@ dav_svn__get_deleted_rev_report(const da
                                 const apr_xml_doc *doc,
                                 ap_filter_t *output);
 
+
+/*** posts/ ***/
+
+/* The list of Subversion's custom POSTs. */
+/* ### should move these report names to a public header to share with
+   ### the client (and third parties). */
+static const char * dav_svn__posts_list[] = {
+  "create-txn",
+  NULL
+};
+
+/* The various POST handlers, defined in posts/, and used by repos.c.  */
+dav_error *
+dav_svn__post_create_txn(const dav_resource *resource,
+                         svn_skel_t *request_skel,
+                         ap_filter_t *output);
+
 /*** authz.c ***/
 
 /* A baton needed by dav_svn__authz_read_func(). */
@@ -890,6 +908,13 @@ dav_svn__final_flush_or_error(request_re
  */
 int dav_svn__error_response_tag(request_rec *r, dav_error *err);
 
+
+/* Set *SKEL to a parsed skel read from the body of request R, and
+ * allocated in POOL.
+ */
+int dav_svn__parse_request_skel(svn_skel_t **skel, request_rec *r,
+                                apr_pool_t *pool);
+
 /*** mirror.c ***/
 
 /* Perform the fixup hook for the R request.  */

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/deadprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/deadprops.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/deadprops.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/deadprops.c Thu Sep  9 20:26:46 2010
@@ -392,7 +392,7 @@ db_output_value(dav_db *db,
           const svn_string_t *enc_propval
             = svn_base64_encode_string2(propval, TRUE, pool);
           xml_safe = enc_propval->data;
-          encoding = apr_pstrcat(pool, " V:encoding=\"base64\"", NULL);
+          encoding = " V:encoding=\"base64\"";
         }
       else
         {

Propchange: subversion/branches/atomic-revprop/subversion/mod_dav_svn/posts/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Sep  9 20:26:46 2010
@@ -0,0 +1 @@
+.libs

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/log.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/log.c Thu Sep  9 20:26:46 2010
@@ -311,7 +311,17 @@ dav_svn__log_report(const dav_resource *
       else if (strcmp(child->name, "end-revision") == 0)
         end = SVN_STR_TO_REV(dav_xml_get_cdata(child, resource->pool, 1));
       else if (strcmp(child->name, "limit") == 0)
-        limit = atoi(dav_xml_get_cdata(child, resource->pool, 1));
+        {
+          serr = svn_cstring_atoi(&limit,
+                                  dav_xml_get_cdata(child, resource->pool, 1));
+          if (serr)
+            {
+              derr = dav_svn__convert_err(serr, HTTP_BAD_REQUEST,
+                                          "Malformed CDATA in element "
+                                          "\"limit\"", resource->pool);
+              goto cleanup;
+            }
+        }
       else if (strcmp(child->name, "discover-changed-paths") == 0)
         discover_changed_paths = TRUE; /* presence indicates positivity */
       else if (strcmp(child->name, "strict-node-history") == 0)

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/replay.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/replay.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/reports/replay.c Thu Sep  9 20:26:46 2010
@@ -466,10 +466,18 @@ dav_svn__replay_report(const dav_resourc
             }
           else if (strcmp(child->name, "send-deltas") == 0)
             {
+              apr_int64_t parsed_val;
+
               cdata = dav_xml_get_cdata(child, resource->pool, 1);
               if (! cdata)
                 return malformed_element_error("send-deltas", resource->pool);
-              send_deltas = atoi(cdata);
+              err = svn_cstring_strtoi64(&parsed_val, cdata, 0, 1, 10);
+              if (err)
+                {
+                  svn_error_clear(err);
+                  return malformed_element_error("send-deltas", resource->pool);
+                }
+              send_deltas = parsed_val ? TRUE : FALSE;
             }
         }
     }

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/repos.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/repos.c Thu Sep  9 20:26:46 2010
@@ -44,6 +44,7 @@
 #include "svn_sorts.h"
 #include "svn_version.h"
 #include "svn_props.h"
+#include "svn_ctype.h"
 #include "mod_dav_svn.h"
 #include "svn_ra.h"  /* for SVN_RA_CAPABILITY_* */
 #include "svn_dirent_uri.h"
@@ -1519,7 +1520,7 @@ static const char *get_entry(apr_pool_t 
 
         /* Look for 'var = value' --- and make sure the var is in lcase. */
 
-        for (cp = parm; (*cp && !apr_isspace(*cp) && *cp != '='); ++cp)
+        for (cp = parm; (*cp && !svn_ctype_isspace(*cp) && *cp != '='); ++cp)
           {
             *cp = apr_tolower(*cp);
           }
@@ -1530,7 +1531,7 @@ static const char *get_entry(apr_pool_t 
           }
 
         *cp++ = '\0';           /* Delimit var */
-        while (*cp && (apr_isspace(*cp) || *cp == '='))
+        while (*cp && (svn_ctype_isspace(*cp) || *cp == '='))
           {
             ++cp;
           }
@@ -1544,7 +1545,7 @@ static const char *get_entry(apr_pool_t 
           }
         else
           {
-            for (end = cp; (*end && !apr_isspace(*end)); end++);
+            for (end = cp; (*end && !svn_ctype_isspace(*end)); end++);
           }
         if (*end)
           {
@@ -4263,58 +4264,73 @@ dav_svn__create_version_resource(dav_res
 }
 
 
-/* POST handler for HTTP protocol v2.
- 
-   Currently we allow POSTs only against the "me resource", which may
-   in the future act as a dispatcher of sorts for handling potentially
-   many different kinds of operations as specified by the body of the
-   POST request itself.
-
-   ### TODO: Define what the format of those POST bodies might be.  If
-   ### XML, we have access to Apache's streamy XML parsing code, but
-   ### ... it's XML.  Meh.  If skels, we get skels!  But we need to
-   ### write our own streamy skel parsing routine around a brigade
-   ### read loop.  Ewww...
-   ###
-   ### Today we only support transaction creation requests, but we
-   ### could conceivable support the likes of a multi-path lock
-   ### and/or unlock request, or some other thing for which stock
-   ### WebDAV doesn't work or doesn't work well enough.
-   ###
-   ### Fortunately, today we don't use the POST body at all, and we'll
-   ### be able to get away with not defining the body format in the
-   ### future thanks to the following:
-
-   As a special consideration, an empty POST body is interpreted as a
-   simple request to create a new commit transaction based on the HEAD
-   revision.  The new transaction name will be returned via a custom
-   response header SVN_DAV_TXN_NAME_HEADER.
-*/
+
+static dav_error *
+handle_post_request(request_rec *r,
+                    dav_resource *resource,
+                    ap_filter_t *output)
+{
+  svn_skel_t *request_skel;
+  int status;
+  apr_pool_t *pool = resource->pool;
+
+  /* Make sure our skel-based request parses okay, has an initial atom
+     that identifies what kind of action is expected, and that that
+     action is something we understand.  */
+  status = dav_svn__parse_request_skel(&request_skel, r, pool);
+
+  if (status != OK)
+    return dav_new_error(pool, status, 0,
+                         "Error parsing skel POST request body.");
+
+  if (svn_skel__list_length(request_skel) < 1)
+    return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+                         "Unable to identify skel POST request flavor.");
+
+  if (svn_skel__matches_atom(request_skel->children, "create-txn"))
+    {
+      return dav_svn__post_create_txn(resource, request_skel, output);
+    }
+  else
+    {
+      return dav_new_error(pool, HTTP_BAD_REQUEST, 0,
+                           "Unsupported skel POST request flavor.");
+    }
+  /* NOTREACHED */
+}
+
 int dav_svn__method_post(request_rec *r)
 {
   dav_resource *resource;
   dav_error *derr;
-  const char *txn_name;
+  const char *content_type;
 
+  /* We only allow POSTs against the "me resource" right now. */
   derr = get_resource(r, dav_svn__get_root_dir(r),
                       "ignored", 0, &resource);
   if (derr != NULL)
     return derr->status;
-
   if (resource->info->restype != DAV_SVN_RESTYPE_ME)
     return HTTP_BAD_REQUEST;
 
-  /* Create a Subversion repository transaction based on HEAD. */
-  derr = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
+  /* Pass skel-type POST request handling off to a dispatcher; any
+     other type of request is considered bogus. */
+  content_type = apr_table_get(r->headers_in, "content-type");
+  if (content_type && (strcmp(content_type, SVN_SKEL_MIME_TYPE) == 0))
+    {
+      derr = handle_post_request(r, resource, r->output_filters);
+    }
+  else
+    {
+      derr = dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
+                           "Unsupported POST request type.");
+    }
+
+  /* If something went wrong above, we'll generate a response back to
+     the client with (hopefully) some helpful information. */
   if (derr)
     return dav_svn__error_response_tag(r, derr);
-
-  /* Build a "201 Created" response with header that tells the client
-     our new transaction's name. */
-  apr_table_set(resource->info->r->headers_out, SVN_DAV_TXN_NAME_HEADER,
-                txn_name);
-  r->status = HTTP_CREATED;
-
+    
   return OK;
 }
 

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/util.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/util.c Thu Sep  9 20:26:46 2010
@@ -28,6 +28,7 @@
 
 #include <mod_dav.h>
 #include <http_protocol.h>
+#include <http_core.h>
 
 #include "svn_error.h"
 #include "svn_fs.h"
@@ -611,3 +612,140 @@ dav_svn__error_response_tag(request_rec 
    */
   return DONE;
 }
+
+
+/* Set *REQUEST_STR to a string containing the contents of the body of
+   request R, allocated from POOL.
+
+   NOTE: This was shamelessly stolen and modified from Apache's
+   ap_xml_parse_input().  */
+static int
+request_body_to_string(svn_string_t **request_str,
+                       request_rec *r,
+                       apr_pool_t *pool)
+{
+  apr_bucket_brigade *brigade;
+  int seen_eos;
+  apr_status_t status;
+  apr_off_t total_read = 0;
+  apr_off_t limit_req_body = ap_get_limit_req_body(r);
+  int result = HTTP_BAD_REQUEST;
+  const char *content_length_str;
+  char *endp;
+  apr_off_t content_length;
+  svn_stringbuf_t *buf;
+
+  *request_str = NULL;
+
+  content_length_str = apr_table_get(r->headers_in, "Content-Length");
+  if (content_length_str)
+    {
+      if (apr_strtoff(&content_length, content_length_str, &endp, 10)
+          || endp == content_length_str || *endp || content_length < 0)
+        {
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Invalid Content-Length");
+          return HTTP_REQUEST_ENTITY_TOO_LARGE;
+        }
+    }
+  else
+    content_length = 0;
+
+  if (limit_req_body && (limit_req_body < content_length))
+    {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                    "Requested content-length of %" APR_OFF_T_FMT " is larger "
+                    "than the configured limit of %" APR_OFF_T_FMT,
+                    content_length, limit_req_body);
+      return HTTP_REQUEST_ENTITY_TOO_LARGE;
+    }
+
+  if (content_length)
+    {
+      buf = svn_stringbuf_create_ensure(content_length, pool);
+    }
+  else
+    {
+      buf = svn_stringbuf_create("", pool);
+    }
+
+  brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+  seen_eos = 0;
+  total_read = 0;
+
+  do
+    {
+      apr_bucket *bucket;
+
+      status = ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES,
+                              APR_BLOCK_READ, 2048);
+      if (status != APR_SUCCESS)
+        goto cleanup;
+
+      for (bucket = APR_BRIGADE_FIRST(brigade);
+           bucket != APR_BRIGADE_SENTINEL(brigade);
+           bucket = APR_BUCKET_NEXT(bucket))
+        {
+          const char *data;
+          apr_size_t len;
+          
+          if (APR_BUCKET_IS_EOS(bucket))
+            {
+              seen_eos = 1;
+              break;
+            }
+          
+          if (APR_BUCKET_IS_METADATA(bucket))
+            continue;
+          
+          status = apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
+          if (status != APR_SUCCESS)
+            goto cleanup;
+          
+          total_read += len;
+          if (limit_req_body && total_read > limit_req_body)
+            {
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                            "Request body is larger than the configured "
+                            "limit of %lu", (unsigned long)limit_req_body);
+              result = HTTP_REQUEST_ENTITY_TOO_LARGE;
+              goto cleanup;
+            }
+          
+          svn_stringbuf_appendbytes(buf, data, len);
+        }
+      
+      apr_brigade_cleanup(brigade);
+    }
+  while (!seen_eos);
+
+  apr_brigade_destroy(brigade);
+
+  /* Make an svn_string_t from our svn_stringbuf_t. */
+  *request_str = svn_string_create("", pool);
+  (*request_str)->data = buf->data;
+  (*request_str)->len = buf->len;
+  return OK;
+
+ cleanup:
+  apr_brigade_destroy(brigade);
+  
+  /* Apache will supply a default error, plus the error log above. */
+  return result;
+}
+
+int
+dav_svn__parse_request_skel(svn_skel_t **skel,
+                            request_rec *r,
+                            apr_pool_t *pool)
+{
+  svn_string_t *skel_str;
+  int status;
+
+  *skel = NULL;
+  status = request_body_to_string(&skel_str, r, pool);
+  if (status != OK)
+    return OK;
+
+  *skel = svn_skel__parse(skel_str->data, skel_str->len, pool);
+  return OK;
+}

Modified: subversion/branches/atomic-revprop/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/atomic-revprop/subversion/mod_dav_svn/version.c?rev=995566&r1=995565&r2=995566&view=diff
==============================================================================
--- subversion/branches/atomic-revprop/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/atomic-revprop/subversion/mod_dav_svn/version.c Thu Sep  9 20:26:46 2010
@@ -41,6 +41,7 @@
 #include "private/svn_log.h"
 
 #include "dav_svn.h"
+#include "mod_dav_svn.h"
 
 
 svn_error_t *
@@ -1015,6 +1016,22 @@ deliver_report(request_rec *r,
 
   if (doc->root->ns == ns)
     {
+      const char *cleaned_uri, *relative_path, *repos_path;
+      int trailing_slash;
+      /* During SVNPathAuthz short_circuit
+       * resource->info->repos->repo_name becomes NULL.*/
+      if (resource->info->repos->repo_name == NULL)
+        {
+          dav_error *err;
+          err = dav_svn_split_uri(r, r->uri, dav_svn__get_root_dir(r),
+                                  &cleaned_uri, &trailing_slash,
+                                  &(resource->info->repos->repo_name), 
+                                  &relative_path, &repos_path);
+          if (err)
+            {
+              return err;
+            }
+        }
       /* ### note that these report names should have symbols... */
 
       if (strcmp(doc->root->name, "update-report") == 0)