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 2012/05/14 16:07:47 UTC

svn commit: r1338209 [3/4] - in /subversion/branches/ev2-export: ./ build/ac-macros/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_ra_serf/ subve...

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/xml.c Mon May 14 14:07:45 2012
@@ -24,9 +24,6 @@
 
 
 #include <apr_uri.h>
-
-#include <expat.h>
-
 #include <serf.h>
 
 #include "svn_pools.h"
@@ -37,91 +34,181 @@
 #include "svn_config.h"
 #include "svn_delta.h"
 #include "svn_path.h"
+
 #include "svn_private_config.h"
+#include "private/svn_string_private.h"
 
 #include "ra_serf.h"
 
 
-void
-svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
-                       const char **attrs,
-                       apr_pool_t *pool)
+struct svn_ra_serf__xml_context_t {
+  /* Current state information.  */
+  svn_ra_serf__xml_estate_t *current;
+
+  /* If WAITING.NAMESPACE != NULL, wait for NAMESPACE:NAME element to be
+     closed before looking for transitions from CURRENT->STATE.  */
+  svn_ra_serf__dav_props_t waiting;
+
+  /* The transition table.  */
+  const svn_ra_serf__xml_transition_t *ttable;
+
+  /* The callback information.  */
+  svn_ra_serf__xml_opened_t opened_cb;
+  svn_ra_serf__xml_closed_t closed_cb;
+  void *baton;
+
+  /* Linked list of free states.  */
+  svn_ra_serf__xml_estate_t *free_states;
+
+#ifdef SVN_DEBUG
+  /* Used to verify we are not re-entering a callback, specifically to
+     ensure SCRATCH_POOL is not cleared while an outer callback is
+     trying to use it.  */
+  svn_boolean_t within_callback;
+#define START_CALLBACK(xmlctx) \
+  do {                                                    \
+    svn_ra_serf__xml_context_t *xmlctx__tmp = (xmlctx);   \
+    SVN_ERR_ASSERT(!xmlctx__tmp->within_callback);        \
+    xmlctx__tmp->within_callback = TRUE;                  \
+  } while (0)
+#define END_CALLBACK(xmlctx) ((xmlctx)->within_callback = FALSE)
+#else
+#define START_CALLBACK(xmlctx)  /* empty */
+#define END_CALLBACK(xmlctx)  /* empty */
+#endif /* SVN_DEBUG  */
+
+  apr_pool_t *scratch_pool;
+
+};
+
+struct svn_ra_serf__xml_estate_t {
+  /* The current state value.  */
+  int state;
+
+  /* The xml tag that opened this state. Waiting for the tag to close.  */
+  svn_ra_serf__dav_props_t tag;
+
+  /* Should the CLOSED_CB function be called for custom processing when
+     this tag is closed?  */
+  svn_boolean_t custom_close;
+
+  /* A pool may be constructed for this state.  */
+  apr_pool_t *state_pool;
+
+  /* The namespaces extent for this state/element. This will start with
+     the parent's NS_LIST, and we will push new namespaces into our
+     local list. The parent will be unaffected by our locally-scoped data. */
+  svn_ra_serf__ns_t *ns_list;
+
+  /* Any collected attribute values. char * -> svn_string_t *. May be NULL
+     if no attributes have been collected.  */
+  apr_hash_t *attrs;
+
+  /* Any collected cdata. May be NULL if no cdata is being collected.  */
+  svn_stringbuf_t *cdata;
+
+  /* Previous/outer state.  */
+  svn_ra_serf__xml_estate_t *prev;
+
+};
+
+
+static void
+define_namespaces(svn_ra_serf__ns_t **ns_list,
+                  const char *const *attrs,
+                  apr_pool_t *(*get_pool)(void *baton),
+                  void *baton)
 {
-  const char **tmp_attrs = attrs;
+  const char *const *tmp_attrs = attrs;
 
-  while (*tmp_attrs)
+  for (tmp_attrs = attrs; *tmp_attrs != NULL; tmp_attrs += 2)
     {
       if (strncmp(*tmp_attrs, "xmlns", 5) == 0)
         {
-          svn_ra_serf__ns_t *new_ns, *cur_ns;
-          int found = 0;
+          const svn_ra_serf__ns_t *cur_ns;
+          svn_boolean_t found = FALSE;
+          const char *prefix;
+
+          /* The empty prefix, or a named-prefix.  */
+          if (tmp_attrs[0][5] == ':')
+            prefix = &tmp_attrs[0][6];
+          else
+            prefix = "";
 
           /* Have we already defined this ns previously? */
           for (cur_ns = *ns_list; cur_ns; cur_ns = cur_ns->next)
             {
-              if (strcmp(cur_ns->namespace, tmp_attrs[0] + 6) == 0)
+              if (strcmp(cur_ns->namespace, prefix) == 0)
                 {
-                  found = 1;
+                  found = TRUE;
                   break;
                 }
             }
 
           if (!found)
             {
+              apr_pool_t *pool;
+              svn_ra_serf__ns_t *new_ns;
+
+              if (get_pool)
+                pool = get_pool(baton);
+              else
+                pool = baton;
               new_ns = apr_palloc(pool, sizeof(*new_ns));
-              new_ns->namespace = apr_pstrdup(pool, tmp_attrs[0] + 6);
+              new_ns->namespace = apr_pstrdup(pool, prefix);
               new_ns->url = apr_pstrdup(pool, tmp_attrs[1]);
 
+              /* Push into the front of NS_LIST. Parent states will point
+                 to later in the chain, so will be unaffected by
+                 shadowing/other namespaces pushed onto NS_LIST.  */
               new_ns->next = *ns_list;
-
               *ns_list = new_ns;
             }
         }
-      tmp_attrs += 2;
     }
 }
 
+
+void
+svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
+                       const char *const *attrs,
+                       apr_pool_t *result_pool)
+{
+  define_namespaces(ns_list, attrs, NULL /* get_pool */, result_pool);
+}
+
+
 /*
  * Look up NAME in the NS_LIST list for previously declared namespace
  * definitions and return a DAV_PROPS_T-tuple that has values.
  */
 void
 svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
-                       svn_ra_serf__ns_t *ns_list,
+                       const svn_ra_serf__ns_t *ns_list,
                        const char *name)
 {
   const char *colon;
-  svn_ra_serf__dav_props_t prop_name;
 
   colon = strchr(name, ':');
   if (colon)
     {
-      svn_ra_serf__ns_t *ns;
-
-      prop_name.namespace = NULL;
+      const svn_ra_serf__ns_t *ns;
 
       for (ns = ns_list; ns; ns = ns->next)
         {
           if (strncmp(ns->namespace, name, colon - name) == 0)
             {
-              prop_name.namespace = ns->url;
-              break;
+              returned_prop_name->namespace = ns->url;
+              returned_prop_name->name = colon + 1;
+              return;
             }
         }
-
-      SVN_ERR_ASSERT_NO_RETURN(prop_name.namespace);
-
-      prop_name.name = colon + 1;
-    }
-  else
-    {
-      /* use default namespace for now */
-      prop_name.namespace = "";
-      prop_name.name = name;
     }
 
-  *returned_prop_name = prop_name;
-  return;
+  /* If there is no prefix, or if the prefix is not found, then the
+     name is NOT within a namespace.  */
+  returned_prop_name->namespace = "";
+  returned_prop_name->name = name;
 }
 
 
@@ -322,3 +409,344 @@ void svn_ra_serf__xml_pop_state(svn_ra_s
   cur_state->prev = parser->free_state;
   parser->free_state = cur_state;
 }
+
+
+/* Return a pool for XES to use for self-alloc (and other specifics).  */
+static apr_pool_t *
+xes_pool(const svn_ra_serf__xml_estate_t *xes)
+{
+  /* Move up through parent states looking for one with a pool. This
+     will always terminate since the initial state has a pool.  */
+  while (xes->state_pool == NULL)
+    xes = xes->prev;
+  return xes->state_pool;
+}
+
+
+static void
+ensure_pool(svn_ra_serf__xml_estate_t *xes)
+{
+  if (xes->state_pool == NULL)
+    xes->state_pool = svn_pool_create(xes_pool(xes));
+}
+
+
+/* This callback is used by define_namespaces() to wait until a pool is
+   required before constructing it.  */
+static apr_pool_t *
+lazy_create_pool(void *baton)
+{
+  svn_ra_serf__xml_estate_t *xes = baton;
+
+  ensure_pool(xes);
+  return xes->state_pool;
+}
+
+
+svn_ra_serf__xml_context_t *
+svn_ra_serf__xml_context_create(
+  const svn_ra_serf__xml_transition_t *ttable,
+  svn_ra_serf__xml_opened_t opened_cb,
+  svn_ra_serf__xml_closed_t closed_cb,
+  void *baton,
+  apr_pool_t *result_pool)
+{
+  svn_ra_serf__xml_context_t *xmlctx;
+  svn_ra_serf__xml_estate_t *xes;
+
+  xmlctx = apr_pcalloc(result_pool, sizeof(*xmlctx));
+  xmlctx->ttable = ttable;
+  xmlctx->opened_cb = opened_cb;
+  xmlctx->closed_cb = closed_cb;
+  xmlctx->baton = baton;
+  xmlctx->scratch_pool = svn_pool_create(result_pool);
+
+  xes = apr_pcalloc(result_pool, sizeof(*xes));
+  /* XES->STATE == 0  */
+
+  /* Child states may use this pool to allocate themselves. If a child
+     needs to collect information, then it will construct a subpool and
+     will use that to allocate itself and its collected data.  */
+  xes->state_pool = result_pool;
+
+  xmlctx->current = xes;
+
+  return xmlctx;
+}
+
+
+apr_hash_t *
+svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
+                              int stop_state)
+{
+  apr_hash_t *data;
+
+  ensure_pool(xes);
+
+  data = apr_hash_make(xes->state_pool);
+
+  /* ### gather data  */
+
+  return data;
+}
+
+
+void
+svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
+                      int state,
+                      const char *name,
+                      const char *value)
+{
+  svn_ra_serf__xml_estate_t *scan;
+
+  for (scan = xes; scan != NULL && scan->state != state; scan = scan->prev)
+    /* pass */ ;
+
+  SVN_ERR_ASSERT_NO_RETURN(scan != NULL);
+
+  /* Make sure the target state has a pool.  */
+  ensure_pool(scan);
+
+  /* ... and attribute storage.  */
+  if (scan->attrs == NULL)
+    scan->attrs = apr_hash_make(scan->state_pool);
+
+  /* In all likelihood, NAME is a string constant. But we can't really
+     be sure. And it isn't like we're storing a billion of these into
+     the state pool.  */
+  apr_hash_set(scan->attrs,
+               apr_pstrdup(scan->state_pool, name), APR_HASH_KEY_STRING,
+               apr_pstrdup(scan->state_pool, value));
+}
+
+
+apr_pool_t *
+svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes)
+{
+  /* If they asked for a pool, then ensure that we have one to provide.  */
+  ensure_pool(xes);
+
+  return xes->state_pool;
+}
+
+
+svn_error_t *
+svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx,
+                          const char *raw_name,
+                          const char *const *attrs)
+{
+  svn_ra_serf__xml_estate_t *current = xmlctx->current;
+  svn_ra_serf__dav_props_t elemname;
+  const svn_ra_serf__xml_transition_t *scan;
+  apr_pool_t *new_pool;
+  svn_ra_serf__xml_estate_t *new_xes;
+
+  /* If we're waiting for an element to close, then just ignore all
+     other element-opens.  */
+  if (xmlctx->waiting.namespace != NULL)
+    return SVN_NO_ERROR;
+
+  /* Look for xmlns: attributes. Lazily create the state pool if any
+     were found.  */
+  define_namespaces(&current->ns_list, attrs, lazy_create_pool, current);
+
+  svn_ra_serf__expand_ns(&elemname, current->ns_list, raw_name);
+
+  for (scan = xmlctx->ttable; scan->ns != NULL; ++scan)
+    {
+      if (scan->from_state != current->state)
+        continue;
+
+      if (strcmp(elemname.name, scan->name) == 0
+          && strcmp(elemname.namespace, scan->ns) == 0)
+        break;
+    }
+  if (scan->ns == NULL)
+    {
+      xmlctx->waiting = elemname;
+      /* ### return?  */
+      return SVN_NO_ERROR;
+    }
+
+  /* We should not be told to collect cdata if the closed_cb will not
+     be called.  */
+  SVN_ERR_ASSERT(!scan->collect_cdata || scan->custom_close);
+
+  /* Found a transition. Make it happen.  */
+
+  /* ### todo. push state  */
+
+  /* ### how to use free states?  */
+  /* This state should be allocated in the extent pool. If we will be
+     collecting information for this state, then construct a subpool.
+
+     ### potentially optimize away the subpool if none of the
+     ### attributes are present. subpools are cheap, tho...  */
+  new_pool = xes_pool(current);
+  if (scan->collect_cdata || scan->collect_attrs[0])
+    {
+      new_pool = svn_pool_create(new_pool);
+
+      /* Prep the new state.  */
+      new_xes = apr_pcalloc(new_pool, sizeof(*new_xes));
+      new_xes->state_pool = new_pool;
+
+      /* If we're supposed to collect cdata, then set up a buffer for
+         this. The existence of this buffer will instruct our cdata
+         callback to collect the cdata.  */
+      if (scan->collect_cdata)
+        new_xes->cdata = svn_stringbuf_create_empty(new_pool);
+
+      if (scan->collect_attrs[0] != NULL)
+        {
+          const char *const *saveattr = &scan->collect_attrs[0];
+
+          new_xes->attrs = apr_hash_make(new_pool);
+          for (; *saveattr != NULL; ++saveattr)
+            {
+              const char *name;
+              const char *value;
+
+              if (**saveattr == '?')
+                {
+                  name = *saveattr + 1;
+                  value = svn_xml_get_attr_value(name, attrs);
+                }
+              else
+                {
+                  name = *saveattr;
+                  value = svn_xml_get_attr_value(name, attrs);
+                  if (value == NULL)
+                    return svn_error_createf(SVN_ERR_XML_ATTRIB_NOT_FOUND,
+                                             NULL,
+                                             _("Missing XML attribute: '%s'"),
+                                             name);
+                }
+
+              if (value)
+                apr_hash_set(new_xes->attrs, name, APR_HASH_KEY_STRING, value);
+            }
+        }
+    }
+  else
+    {
+      /* Prep the new state.  */
+      new_xes = apr_pcalloc(new_pool, sizeof(*new_xes));
+      /* STATE_POOL remains NULL.  */
+    }
+
+  /* Some basic copies to set up the new estate.  */
+  new_xes->state = scan->to_state;
+  new_xes->tag = elemname;
+  new_xes->custom_close = scan->custom_close;
+
+  /* Start with the parent's namespace set.  */
+  new_xes->ns_list = current->ns_list;
+
+  /* The new state is prepared. Make it current.  */
+  new_xes->prev = current;
+  xmlctx->current = new_xes;
+
+  if (scan->custom_open)
+    {
+      START_CALLBACK(xmlctx);
+      SVN_ERR(xmlctx->opened_cb(new_xes, xmlctx->baton,
+                                new_xes->state, xmlctx->scratch_pool));
+      END_CALLBACK(xmlctx);
+      svn_pool_clear(xmlctx->scratch_pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
+                        const char *raw_name)
+{
+  svn_ra_serf__xml_estate_t *xes = xmlctx->current;
+  svn_ra_serf__dav_props_t elemname;
+
+  svn_ra_serf__expand_ns(&elemname, xes->ns_list, raw_name);
+
+  if (xmlctx->waiting.namespace != NULL)
+    {
+      /* If this element is not the closer, then keep waiting... */
+      if (strcmp(elemname.name, xmlctx->waiting.name) != 0
+          || strcmp(elemname.namespace, xmlctx->waiting.namespace) != 0)
+        return SVN_NO_ERROR;
+
+      /* Found it. Stop waiting, and go back for more.  */
+      xmlctx->waiting.namespace = NULL;
+      return SVN_NO_ERROR;
+    }
+
+  /* We should be looking at the same tag that opened the current state.
+
+     Unknown elements are simply skipped, so we wouldn't reach this check.
+
+     Known elements push a new state for a given tag. Some other elemname
+     would imply closing an ancestor tag (where did ours go?) or a spurious
+     tag closure.  */
+  if (strcmp(elemname.name, xes->tag.name) != 0
+      || strcmp(elemname.namespace, xes->tag.namespace) != 0)
+    return svn_error_create(SVN_ERR_XML_MALFORMED, NULL,
+                            _("The response contains invalid XML"));
+
+  if (xes->custom_close)
+    {
+      const svn_string_t *cdata;
+
+      if (xes->cdata)
+        {
+          cdata = svn_stringbuf__morph_into_string(xes->cdata);
+#ifdef SVN_DEBUG
+          /* We might toss the pool holding this structure, but it could also
+             be within a parent pool. In any case, for safety's sake, disable
+             the stringbuf against future Badness.  */
+          xes->cdata->pool = NULL;
+#endif
+        }
+      else
+        cdata = NULL;
+
+      START_CALLBACK(xmlctx);
+      SVN_ERR(xmlctx->closed_cb(xes, xmlctx->baton, xes->state,
+                                cdata, xes->attrs,
+                                xmlctx->scratch_pool));
+      END_CALLBACK(xmlctx);
+      svn_pool_clear(xmlctx->scratch_pool);
+    }
+
+  /* Pop the state.  */
+  xmlctx->current = xes->prev;
+
+  /* ### not everything should go on the free state list. XES may go
+     ### away with the state pool.  */
+  xes->prev = xmlctx->free_states;
+  xmlctx->free_states = xes;
+
+  /* If there is a STATE_POOL, then toss it. This will get rid of as much
+     memory as possible. Potentially the XES (if we didn't create a pool
+     right away, then XES may be in a parent pool).  */
+  if (xes->state_pool)
+    svn_pool_destroy(xes->state_pool);
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
+                          const char *data,
+                          apr_size_t len)
+{
+  /* If we're collecting cdata, but NOT waiting for a closing tag
+     (ie. not within an unknown tag), then copy the cdata.  */
+  if (xmlctx->current->cdata != NULL
+      && xmlctx->waiting.namespace == NULL)
+    svn_stringbuf_appendbytes(xmlctx->current->cdata, data, len);
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/lock.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/lock.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/lock.c Mon May 14 14:07:45 2012
@@ -54,8 +54,7 @@ svn_lock_dup(const svn_lock_t *lock, apr
   new_l->path = apr_pstrdup(pool, new_l->path);
   new_l->token = apr_pstrdup(pool, new_l->token);
   new_l->owner = apr_pstrdup(pool, new_l->owner);
-  if (new_l->comment)
-    new_l->comment = apr_pstrdup(pool, new_l->comment);
+  new_l->comment = apr_pstrdup(pool, new_l->comment);
 
   return new_l;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/xml.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/xml.c Mon May 14 14:07:45 2012
@@ -455,7 +455,7 @@ void svn_xml_signal_bailout(svn_error_t 
 /*** Attribute walking. ***/
 
 const char *
-svn_xml_get_attr_value(const char *name, const char **atts)
+svn_xml_get_attr_value(const char *name, const char *const *atts)
 {
   while (atts && (*atts))
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/conflicts.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/conflicts.c Mon May 14 14:07:45 2012
@@ -44,6 +44,7 @@
 #include "wc.h"
 #include "wc_db.h"
 #include "conflicts.h"
+#include "workqueue.h"
 
 #include "private/svn_wc_private.h"
 #include "private/svn_skel.h"
@@ -115,40 +116,10 @@ svn_wc__conflict_skel_add_prop_conflict(
 
 /*** Resolving a conflict automatically ***/
 
-
-/* Helper for resolve_conflict_on_entry.  Delete the file FILE_ABSPATH
-   in if it exists.  Set WAS_PRESENT to TRUE if the file existed, and
-   leave it UNTOUCHED otherwise. */
-static svn_error_t *
-attempt_deletion(const char *file_abspath,
-                 svn_boolean_t *was_present,
-                 apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  if (file_abspath == NULL)
-    return SVN_NO_ERROR;
-
-  err = svn_io_remove_file2(file_abspath, FALSE, scratch_pool);
-
-  if (err == NULL || !APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      *was_present = TRUE;
-      return svn_error_trace(err);
-    }
-
-  svn_error_clear(err);
-  return SVN_NO_ERROR;
-}
-
-
 /* Conflict resolution involves removing the conflict files, if they exist,
    and clearing the conflict filenames from the entry.  The latter needs to
    be done whether or not the conflict files exist.
 
-   Tree conflicts are not resolved here, because the data stored in one
-   entry does not refer to that entry but to children of it.
-
    PATH is the path to the item to be resolved, BASE_NAME is the basename
    of PATH, and CONFLICT_DIR is the access baton for PATH.  ORIG_ENTRY is
    the entry prior to resolution. RESOLVE_TEXT and RESOLVE_PROPS are TRUE
@@ -158,24 +129,19 @@ attempt_deletion(const char *file_abspat
    else do not change *DID_RESOLVE.
 
    See svn_wc_resolved_conflict5() for how CONFLICT_CHOICE behaves.
-
-   ### FIXME: This function should be loggy, otherwise an interruption can
-   ### leave, for example, one of the conflict artifact files deleted but
-   ### the entry still referring to it and trying to use it for the next
-   ### attempt at resolving.
-
-   ### Does this still apply in the world of WC-NG?  -hkw
 */
 static svn_error_t *
-resolve_conflict_on_node(svn_wc__db_t *db,
+resolve_conflict_on_node(svn_boolean_t *did_resolve,
+                         svn_wc__db_t *db,
                          const char *local_abspath,
                          svn_boolean_t resolve_text,
                          svn_boolean_t resolve_props,
+                         svn_boolean_t resolve_tree,
                          svn_wc_conflict_choice_t conflict_choice,
-                         svn_boolean_t *did_resolve,
+                         svn_cancel_func_t cancel_func_t,
+                         void *cancel_baton,
                          apr_pool_t *pool)
 {
-  svn_boolean_t found_file;
   const char *conflict_old = NULL;
   const char *conflict_new = NULL;
   const char *conflict_working = NULL;
@@ -184,6 +150,8 @@ resolve_conflict_on_node(svn_wc__db_t *d
   int i;
   const apr_array_header_t *conflicts;
   const char *conflict_dir_abspath;
+  svn_skel_t *work_items = NULL;
+  svn_skel_t *work_item;
 
   *did_resolve = FALSE;
 
@@ -281,39 +249,101 @@ resolve_conflict_on_node(svn_wc__db_t *d
         }
 
       if (auto_resolve_src)
-        SVN_ERR(svn_io_copy_file(
-          svn_dirent_join(conflict_dir_abspath, auto_resolve_src, pool),
-          local_abspath, TRUE, pool));
+        {
+          SVN_ERR(svn_wc__wq_build_file_copy_translated(
+                    &work_item, db, local_abspath,
+                    svn_dirent_join(conflict_dir_abspath,
+                                    auto_resolve_src, pool),
+                    local_abspath, pool, pool));
+          work_items = svn_wc__wq_merge(work_items, work_item, pool);
+        }
     }
 
-  /* Records whether we found any of the conflict files.  */
-  found_file = FALSE;
-
   if (resolve_text)
     {
-      SVN_ERR(attempt_deletion(conflict_old, &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_new, &found_file, pool));
-      SVN_ERR(attempt_deletion(conflict_working, &found_file, pool));
-      resolve_text = conflict_old || conflict_new || conflict_working;
+      svn_node_kind_t node_kind;
+
+      /* Legacy behavior: Only report text conflicts as resolved when at least
+         one conflict marker file exists.
+
+         If not the UI shows the conflict as already resolved
+         (and in this case we just remove the in-db conflict) */
+
+      if (conflict_old)
+        {
+          SVN_ERR(svn_io_check_path(conflict_old, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_old,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
+
+      if (conflict_new)
+        {
+          SVN_ERR(svn_io_check_path(conflict_new, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_new,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
+
+      if (conflict_working)
+        {
+          SVN_ERR(svn_io_check_path(conflict_working, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   conflict_working,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
     }
   if (resolve_props)
     {
-      if (prop_reject_file != NULL)
-        SVN_ERR(attempt_deletion(prop_reject_file, &found_file, pool));
-      else
-        resolve_props = FALSE;
+      svn_node_kind_t node_kind;
+
+      /* Legacy behavior: Only report property conflicts as resolved when the
+         property reject file exists
+
+         If not the UI shows the conflict as already resolved
+         (and in this case we just remove the in-db conflict) */
+
+      if (prop_reject_file)
+        {
+          SVN_ERR(svn_io_check_path(prop_reject_file, &node_kind, pool));
+          if (node_kind == svn_node_file)
+            {
+              SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db,
+                                                   prop_reject_file,
+                                                   pool, pool));
+              work_items = svn_wc__wq_merge(work_items, work_item, pool);
+              *did_resolve = TRUE;
+            }
+        }
     }
+  if (resolve_tree)
+    *did_resolve = TRUE;
 
-  if (resolve_text || resolve_props)
+  if (resolve_text || resolve_props || resolve_tree)
     {
       SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
                                           resolve_text, resolve_props,
-                                          FALSE, pool));
+                                          resolve_tree, work_items, pool));
 
-      /* No feedback if no files were deleted and all we did was change the
-         entry, such a file did not appear as a conflict */
-      if (found_file)
-        *did_resolve = TRUE;
+      /* Run the work queue to remove conflict marker files. */
+      SVN_ERR(svn_wc__wq_run(db, local_abspath,
+                             cancel_func_t, cancel_baton,
+                             pool));
     }
 
   return SVN_NO_ERROR;
@@ -328,34 +358,53 @@ svn_wc__resolve_text_conflict(svn_wc__db
   svn_boolean_t ignored_result;
 
   return svn_error_trace(resolve_conflict_on_node(
+                           &ignored_result,
                            db, local_abspath,
                            TRUE /* resolve_text */,
                            FALSE /* resolve_props */,
+                           FALSE /* resolve_tree */,
                            svn_wc_conflict_choose_merged,
-                           &ignored_result,
+                           NULL, NULL, /* cancel_func */
                            scratch_pool));
 }
 
 
-/* */
+/* Baton for conflict_status_walker */
+struct conflict_status_walker_baton
+{
+  svn_wc__db_t *db;
+  svn_boolean_t resolve_text;
+  const char *resolve_prop;
+  svn_boolean_t resolve_tree;
+  svn_wc_conflict_choice_t conflict_choice;
+  svn_wc_conflict_resolver_func2_t conflict_func;
+  void *conflict_baton;
+  svn_cancel_func_t cancel_func;
+  void *cancel_baton;
+  svn_wc_notify_func2_t notify_func;
+  void *notify_baton;
+};
+
+/* Implements svn_wc_status4_t to walk all conflicts to resolve */
 static svn_error_t *
-resolve_one_conflict(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_boolean_t resolve_text,
-                     const char *resolve_prop,
-                     svn_boolean_t resolve_tree,
-                     svn_wc_conflict_choice_t conflict_choice,
-                     svn_wc_conflict_resolver_func2_t conflict_func,
-                     void *conflict_baton,
-                     svn_wc_notify_func2_t notify_func,
-                     void *notify_baton,
-                     apr_pool_t *scratch_pool)
+conflict_status_walker(void *baton,
+                       const char *local_abspath,
+                       const svn_wc_status3_t *status,
+                       apr_pool_t *scratch_pool)
 {
+  struct conflict_status_walker_baton *cswb = baton;
+  svn_wc__db_t *db = cswb->db;
+
   const apr_array_header_t *conflicts;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool;
   int i;
   svn_boolean_t resolved = FALSE;
 
+  if (!status->conflicted)
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(scratch_pool);
+
   SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
                                     scratch_pool, iterpool));
 
@@ -363,7 +412,7 @@ resolve_one_conflict(svn_wc__db_t *db,
     {
       const svn_wc_conflict_description2_t *cd;
       svn_boolean_t did_resolve;
-      svn_wc_conflict_choice_t my_choice = conflict_choice;
+      svn_wc_conflict_choice_t my_choice = cswb->conflict_choice;
 
       cd = APR_ARRAY_IDX(conflicts, i, const svn_wc_conflict_description2_t *);
 
@@ -373,13 +422,13 @@ resolve_one_conflict(svn_wc__db_t *db,
         {
           svn_wc_conflict_result_t *result;
 
-          if (conflict_func == NULL)
+          if (!cswb->conflict_func)
             return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
                                     _("No conflict-callback and no "
                                       "pre-defined conflict-choice provided"));
-                                    
-          SVN_ERR(conflict_func(&result, cd, conflict_baton, iterpool,
-                                iterpool));
+
+          SVN_ERR(cswb->conflict_func(&result, cd, cswb->conflict_baton,
+                                      iterpool, iterpool));
 
           my_choice = result->choice;
         }
@@ -391,7 +440,7 @@ resolve_one_conflict(svn_wc__db_t *db,
       switch (cd->kind)
         {
           case svn_wc_conflict_kind_tree:
-            if (!resolve_tree)
+            if (!cswb->resolve_tree)
               break;
 
             /* For now, we only clear tree conflict information and resolve
@@ -409,22 +458,33 @@ resolve_one_conflict(svn_wc__db_t *db,
                                                                 iterpool));
               }
 
-            SVN_ERR(svn_wc__db_op_set_tree_conflict(db, local_abspath, NULL,
-                                                    iterpool));
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
+                                             local_abspath,
+                                             FALSE /* resolve_text */,
+                                             FALSE /* resolve_props */,
+                                             TRUE /* resolve_tree */,
+                                             my_choice,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
+                                             iterpool));
 
             resolved = TRUE;
             break;
 
           case svn_wc_conflict_kind_text:
-            if (!resolve_text)
+            if (!cswb->resolve_text)
               break;
 
-            SVN_ERR(resolve_conflict_on_node(db,
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
                                              local_abspath,
                                              TRUE /* resolve_text */,
                                              FALSE /* resolve_props */,
+                                             FALSE /* resolve_tree */,
                                              my_choice,
-                                             &did_resolve,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
                                              iterpool));
 
             if (did_resolve)
@@ -432,25 +492,28 @@ resolve_one_conflict(svn_wc__db_t *db,
             break;
 
           case svn_wc_conflict_kind_property:
-            if (!resolve_prop)
+            if (!cswb->resolve_prop)
               break;
 
             /* ### this is bogus. resolve_conflict_on_node() does not handle
                ### individual property resolution.  */
-            if (*resolve_prop != '\0' &&
-                strcmp(resolve_prop, cd->property_name) != 0)
+            if (*cswb->resolve_prop != '\0' &&
+                strcmp(cswb->resolve_prop, cd->property_name) != 0)
               {
                 break; /* Skip this property conflict */
               }
 
 
             /* We don't have property name handling here yet :( */
-            SVN_ERR(resolve_conflict_on_node(db,
+            SVN_ERR(resolve_conflict_on_node(&did_resolve,
+                                             db,
                                              local_abspath,
                                              FALSE /* resolve_text */,
                                              TRUE /* resolve_props */,
+                                             FALSE /* resolve_tree */,
                                              my_choice,
-                                             &did_resolve,
+                                             cswb->cancel_func,
+                                             cswb->cancel_baton,
                                              iterpool));
 
             if (did_resolve)
@@ -464,159 +527,18 @@ resolve_one_conflict(svn_wc__db_t *db,
     }
 
   /* Notify */
-  if (notify_func && resolved)
-    notify_func(notify_baton,
-                svn_wc_create_notify(local_abspath, svn_wc_notify_resolved,
-                                     iterpool),
-                iterpool);
-
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-recursive_resolve_conflict(svn_wc__db_t *db,
-                           const char *local_abspath,
-                           svn_boolean_t this_is_conflicted,
-                           svn_depth_t depth,
-                           svn_boolean_t resolve_text,
-                           const char *resolve_prop,
-                           svn_boolean_t resolve_tree,
-                           svn_wc_conflict_choice_t conflict_choice,
-                           svn_wc_conflict_resolver_func2_t conflict_func,
-                           void *conflict_baton,
-                           svn_cancel_func_t cancel_func,
-                           void *cancel_baton,
-                           svn_wc_notify_func2_t notify_func,
-                           void *notify_baton,
-                           apr_pool_t *scratch_pool)
-{
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  const apr_array_header_t *children;
-  apr_hash_t *visited = apr_hash_make(scratch_pool);
-  svn_depth_t child_depth;
-  int i;
-
-  if (cancel_func)
-    SVN_ERR(cancel_func(cancel_baton));
-
-  if (this_is_conflicted)
-    {
-      SVN_ERR(resolve_one_conflict(db,
-                                   local_abspath,
-                                   resolve_text,
-                                   resolve_prop,
-                                   resolve_tree,
-                                   conflict_choice,
-                                   conflict_func, conflict_baton,
-                                   notify_func, notify_baton,
-                                   iterpool));
-    }
-
-  if (depth < svn_depth_files)
-    return SVN_NO_ERROR;
-
-  child_depth = (depth < svn_depth_infinity) ? svn_depth_empty : depth;
-
-  SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
-                                   scratch_pool, iterpool));
-
-  for (i = 0; i < children->nelts; i++)
-    {
-      const char *name = APR_ARRAY_IDX(children, i, const char *);
-      const char *child_abspath;
-      svn_wc__db_status_t status;
-      svn_kind_t kind;
-      svn_boolean_t conflicted;
-
-      svn_pool_clear(iterpool);
-
-      if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
-
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
-      SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                   &conflicted, NULL, NULL, NULL, NULL, NULL,
-                                   NULL,
-                                   db, child_abspath, iterpool, iterpool));
-
-      if (status == svn_wc__db_status_not_present
-          || status == svn_wc__db_status_excluded
-          || status == svn_wc__db_status_server_excluded)
-        continue;
-
-      apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
-      if (kind == svn_kind_dir && depth < svn_depth_immediates)
-        continue;
-
-      if (kind == svn_kind_dir)
-        SVN_ERR(recursive_resolve_conflict(db,
-                                           child_abspath,
-                                           conflicted,
-                                           child_depth,
-                                           resolve_text,
-                                           resolve_prop,
-                                           resolve_tree,
-                                           conflict_choice,
-                                           conflict_func, conflict_baton,
-                                           cancel_func, cancel_baton,
-                                           notify_func, notify_baton,
-                                           iterpool));
-      else if (conflicted)
-        SVN_ERR(resolve_one_conflict(db,
-                                     child_abspath,
-                                     resolve_text,
-                                     resolve_prop,
-                                     resolve_tree,
-                                     conflict_choice,
-                                     conflict_func, conflict_baton,
-                                     notify_func, notify_baton,
-                                     iterpool));
-    }
-
-    SVN_ERR(svn_wc__db_read_conflict_victims(&children, db, local_abspath,
-                                           scratch_pool, iterpool));
-
-  for (i = 0; i < children->nelts; i++)
-    {
-      const char *name = APR_ARRAY_IDX(children, i, const char *);
-      const char *child_abspath;
-
-      svn_pool_clear(iterpool);
-
-      if (apr_hash_get(visited, name, APR_HASH_KEY_STRING) != NULL)
-        continue; /* Already visited */
-
-      if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
-
-      child_abspath = svn_dirent_join(local_abspath, name, iterpool);
-
-      /* We only have to resolve one level of tree conflicts. All other
-         conflicts are resolved in the other loop */
-      SVN_ERR(resolve_one_conflict(db,
-                                   child_abspath,
-                                   FALSE /*resolve_text*/,
-                                   FALSE /*resolve_prop*/,
-                                   resolve_tree,
-                                   conflict_choice,
-                                   conflict_func, conflict_baton,
-                                   notify_func, notify_baton,
-                                   iterpool));
-    }
-
+  if (cswb->notify_func && resolved)
+    cswb->notify_func(cswb->notify_baton,
+                      svn_wc_create_notify(local_abspath,
+                                           svn_wc_notify_resolved,
+                                           iterpool),
+                      iterpool);
 
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
 svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx,
                           const char *local_abspath,
@@ -635,6 +557,8 @@ svn_wc__resolve_conflicts(svn_wc_context
 {
   svn_kind_t kind;
   svn_boolean_t conflicted;
+  struct conflict_status_walker_baton cswb;
+
   /* ### the underlying code does NOT support resolving individual
      ### properties. bail out if the caller tries it.  */
   if (resolve_prop != NULL && *resolve_prop != '\0')
@@ -642,6 +566,8 @@ svn_wc__resolve_conflicts(svn_wc_context
                             U_("Resolving a single property is not (yet) "
                                "supported."));
 
+  /* ### Just a versioned check? */
+  /* Conflicted is set to allow invoking on actual only nodes */
   SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, &conflicted,
@@ -656,21 +582,34 @@ svn_wc__resolve_conflicts(svn_wc_context
   else if (depth == svn_depth_unknown)
     depth = svn_depth_infinity;
 
-  return svn_error_trace(recursive_resolve_conflict(
-                           wc_ctx->db,
-                           local_abspath,
-                           conflicted,
-                           depth,
-                           resolve_text,
-                           resolve_prop,
-                           resolve_tree,
-                           conflict_choice,
-                           conflict_func, conflict_baton,
-                           cancel_func, cancel_baton,
-                           notify_func, notify_baton,
-                           scratch_pool));
-}
+  cswb.db = wc_ctx->db;
+  cswb.resolve_text = resolve_text;
+  cswb.resolve_prop = resolve_prop;
+  cswb.resolve_tree = resolve_tree;
+  cswb.conflict_choice = conflict_choice;
+
+  cswb.conflict_func = conflict_func;
+  cswb.conflict_baton = conflict_baton;
+
+  cswb.cancel_func = cancel_func;
+  cswb.cancel_baton = cancel_baton;
+
+  cswb.notify_func = notify_func;
+  cswb.notify_baton = notify_baton;
+
+  SVN_ERR(svn_wc_walk_status(wc_ctx,
+                             local_abspath,
+                             depth,
+                             FALSE /* get_all */,
+                             FALSE /* no_ignore */,
+                             TRUE /* ignore_text_mods */,
+                             NULL /* ignore_patterns */,
+                             conflict_status_walker, &cswb,
+                             cancel_func, cancel_baton,
+                             scratch_pool));
 
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/node.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/node.c Mon May 14 14:07:45 2012
@@ -909,6 +909,10 @@ svn_wc__node_get_base(svn_revnum_t *revi
     }
   SVN_ERR(err);
 
+  SVN_ERR_ASSERT(!revision || SVN_IS_VALID_REVNUM(*revision));
+  SVN_ERR_ASSERT(!repos_relpath || *repos_relpath);
+  SVN_ERR_ASSERT(!repos_root_url || *repos_root_url);
+  SVN_ERR_ASSERT(!repos_uuid || *repos_uuid);
   return SVN_NO_ERROR;
 }
 
@@ -1502,68 +1506,40 @@ svn_wc__node_get_origin(svn_boolean_t *i
 }
 
 svn_error_t *
-svn_wc__node_get_commit_status(svn_node_kind_t *kind,
-                               svn_boolean_t *added,
+svn_wc__node_get_commit_status(svn_boolean_t *added,
                                svn_boolean_t *deleted,
                                svn_boolean_t *is_replace_root,
-                               svn_boolean_t *not_present,
-                               svn_boolean_t *excluded,
                                svn_boolean_t *is_op_root,
-                               svn_boolean_t *symlink,
                                svn_revnum_t *revision,
-                               const char **repos_relpath,
                                svn_revnum_t *original_revision,
                                const char **original_repos_relpath,
-                               svn_boolean_t *conflicted,
-                               const char **changelist,
-                               svn_boolean_t *props_mod,
                                svn_boolean_t *update_root,
-                               const char **lock_token,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_kind_t db_kind;
-  svn_wc__db_lock_t *lock;
   svn_boolean_t had_props;
-  svn_boolean_t props_mod_tmp;
   svn_boolean_t have_base;
   svn_boolean_t have_more_work;
   svn_boolean_t op_root;
 
-  if (!props_mod)
-    props_mod = &props_mod_tmp;
-
   /* ### All of this should be handled inside a single read transaction */
-  SVN_ERR(svn_wc__db_read_info(&status, &db_kind, revision, repos_relpath,
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                original_repos_relpath, NULL, NULL,
-                               original_revision, &lock, NULL, NULL,
-                               changelist, conflicted,
-                               &op_root, &had_props, props_mod,
+                               original_revision, NULL, NULL, NULL,
+                               NULL, NULL,
+                               &op_root, NULL, NULL,
                                &have_base, &have_more_work, NULL,
                                wc_ctx->db, local_abspath,
                                result_pool, scratch_pool));
 
-  if (kind)
-    {
-      if (db_kind == svn_kind_file)
-        *kind = svn_node_file;
-      else if (db_kind == svn_kind_dir)
-        *kind = svn_node_dir;
-      else
-        *kind = svn_node_unknown;
-    }
   if (added)
     *added = (status == svn_wc__db_status_added);
   if (deleted)
     *deleted = (status == svn_wc__db_status_deleted);
-  if (not_present)
-    *not_present = (status == svn_wc__db_status_not_present);
-  if (excluded)
-    *excluded = (status == svn_wc__db_status_excluded);
   if (is_op_root)
     *is_op_root = op_root;
 
@@ -1579,23 +1555,6 @@ svn_wc__node_get_commit_status(svn_node_
         *is_replace_root = FALSE;
     }
 
-  if (symlink)
-    {
-      apr_hash_t *props;
-      *symlink = FALSE;
-
-      if (db_kind == svn_kind_file
-          && (had_props || *props_mod))
-        {
-          SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
-                                        scratch_pool, scratch_pool));
-
-          *symlink = ((props != NULL)
-                      && (apr_hash_get(props, SVN_PROP_SPECIAL,
-                                       APR_HASH_KEY_STRING) != NULL));
-        }
-    }
-
   /* Retrieve some information from BASE which is needed for replacing
      and/or deleting BASE nodes. (We don't need lock here) */
   if (have_base
@@ -1611,9 +1570,6 @@ svn_wc__node_get_commit_status(svn_node_
   else if (update_root)
     *update_root = FALSE;
 
-  if (lock_token)
-    *lock_token = lock ? lock->token : NULL;
-
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/questions.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/questions.c Mon May 14 14:07:45 2012
@@ -374,11 +374,9 @@ svn_error_t *
 svn_wc_text_modified_p2(svn_boolean_t *modified_p,
                         svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
-                        svn_boolean_t force_comparison,
+                        svn_boolean_t unused,
                         apr_pool_t *scratch_pool)
 {
-  /* ### We ignore FORCE_COMPARISON, but we also fixed its only
-         remaining use-case */
   return svn_wc__internal_file_modified_p(modified_p, wc_ctx->db,
                                           local_abspath, FALSE, scratch_pool);
 }
@@ -398,6 +396,8 @@ svn_wc__internal_conflicted_p(svn_boolea
   const apr_array_header_t *conflicts;
   int i;
   svn_boolean_t conflicted;
+  svn_boolean_t resolved_text = FALSE;
+  svn_boolean_t resolved_props = FALSE;
 
   if (text_conflicted_p)
     *text_conflicted_p = FALSE;
@@ -466,7 +466,12 @@ svn_wc__internal_conflicted_p(svn_boolea
                                           scratch_pool));
 
                 *text_conflicted_p = (kind == svn_node_file);
+
+                if (*text_conflicted_p)
+                  break;
               }
+
+            resolved_text = TRUE; /* Remove in-db conflict marker */
             break;
 
           case svn_wc_conflict_kind_property:
@@ -479,8 +484,11 @@ svn_wc__internal_conflicted_p(svn_boolea
                                           scratch_pool));
 
                 *prop_conflicted_p = (kind == svn_node_file);
-              }
 
+                if (*prop_conflicted_p)
+                  break;
+              }
+            resolved_props = TRUE; /* Remove in-db conflict marker */
             break;
 
           case svn_wc_conflict_kind_tree:
@@ -494,6 +502,23 @@ svn_wc__internal_conflicted_p(svn_boolea
             break;
         }
     }
+
+  if (resolved_text || resolved_props)
+    {
+      svn_boolean_t own_lock;
+
+      /* The marker files are missing, so "repair" wc.db if we can */
+      SVN_ERR(svn_wc__db_wclock_owns_lock(&own_lock, db, local_abspath, FALSE,
+                                          scratch_pool));
+      if (own_lock)
+        SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+                                            resolved_text,
+                                            resolved_props,
+                                            FALSE /* resolved_tree */,
+                                            NULL /* work_items */,
+                                            scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/status.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/status.c Mon May 14 14:07:45 2012
@@ -949,6 +949,9 @@ send_status_structure(const struct walk_
    IGNORES is a list of patterns to include; typically this will
    be the default ignores as, for example, specified in a config file.
 
+   If MAY_HAVE_PROPS is false, local_abspath is assumed to have no
+   properties.
+
    LOCAL_ABSPATH and DB control how to access the ignore information.
 
    Allocate results in RESULT_POOL, temporary stuffs in SCRATCH_POOL.
@@ -960,11 +963,13 @@ collect_ignore_patterns(apr_array_header
                         svn_wc__db_t *db,
                         const char *local_abspath,
                         const apr_array_header_t *ignores,
+                        svn_boolean_t may_have_props,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
   int i;
   const svn_string_t *value;
+  apr_hash_t *props;
 
   /* ### assert we are passed a directory? */
 
@@ -978,9 +983,18 @@ collect_ignore_patterns(apr_array_header
                                                             ignore);
     }
 
+  if (!may_have_props)
+    return SVN_NO_ERROR;
+
   /* Then add any svn:ignore globs to the PATTERNS array. */
-  SVN_ERR(svn_wc__internal_propget(&value, db, local_abspath, SVN_PROP_IGNORE,
-                                   scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_props(&props, db, local_abspath,
+                                scratch_pool, scratch_pool));
+
+  if (!props)
+    return SVN_NO_ERROR;
+
+  value = apr_hash_get(props, SVN_PROP_IGNORE, APR_HASH_KEY_STRING);
+
   if (value != NULL)
     svn_cstring_split_append(*patterns, value->data, "\n\r", FALSE,
                              result_pool);
@@ -1120,6 +1134,8 @@ get_dir_status(const struct walk_status_
  * DIR_REPOS_* should reflect LOCAL_ABSPATH's parent URL, i.e. LOCAL_ABSPATH's
  * URL treated with svn_uri_dirname(). ### TODO verify this (externals)
  *
+ * DIR_HAS_PROPS is a boolean indicating whether PARENT_ABSPATH has properties.
+ *
  * If *COLLECTED_IGNORE_PATTERNS is NULL and ignore patterns are needed in
  * this call, *COLLECTED_IGNORE_PATTERNS will be set to an apr_array_header_t*
  * containing all ignore patterns, as returned by collect_ignore_patterns() on
@@ -1140,6 +1156,7 @@ one_child_status(const struct walk_statu
                  const char *dir_repos_root_url,
                  const char *dir_repos_relpath,
                  const char *dir_repos_uuid,
+                 svn_boolean_t dir_has_props,
                  svn_boolean_t unversioned_tree_conflicted,
                  apr_array_header_t **collected_ignore_patterns,
                  const apr_array_header_t *ignore_patterns,
@@ -1227,6 +1244,7 @@ one_child_status(const struct walk_statu
   if (ignore_patterns && ! *collected_ignore_patterns)
     SVN_ERR(collect_ignore_patterns(collected_ignore_patterns, wb->db,
                                     parent_abspath, ignore_patterns,
+                                    dir_has_props,
                                     result_pool, scratch_pool));
 
   SVN_ERR(send_unversioned_item(wb,
@@ -1284,6 +1302,7 @@ get_dir_status(const struct walk_status_
   const char *dir_repos_root_url;
   const char *dir_repos_relpath;
   const char *dir_repos_uuid;
+  svn_boolean_t dir_has_props;
   apr_hash_t *dirents, *nodes, *conflicts, *all_children;
   apr_array_header_t *collected_ignore_patterns = NULL;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
@@ -1368,6 +1387,8 @@ get_dir_status(const struct walk_status_
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
 
+  dir_has_props = (dir_info->had_props || dir_info->props_mod);
+
   /* Walk all the children of this directory. */
   for (hi = apr_hash_first(subpool, all_children); hi; hi = apr_hash_next(hi))
     {
@@ -1394,6 +1415,7 @@ get_dir_status(const struct walk_status_
                                dir_repos_root_url,
                                dir_repos_relpath,
                                dir_repos_uuid,
+                               dir_has_props,
                                apr_hash_get(conflicts, key, klen) != NULL,
                                &collected_ignore_patterns,
                                ignore_patterns,
@@ -1480,6 +1502,7 @@ get_child_status(const struct walk_statu
                            dir_repos_root_url,
                            dir_repos_relpath,
                            dir_repos_uuid,
+                           (dir_info->had_props || dir_info->props_mod),
                            FALSE, /* unversioned_tree_conflicted */
                            &collected_ignore_patterns,
                            ignore_patterns,
@@ -2937,6 +2960,6 @@ svn_wc_get_ignores2(apr_array_header_t *
   SVN_ERR(svn_wc_get_default_ignores(&default_ignores, config, scratch_pool));
   return svn_error_trace(collect_ignore_patterns(patterns, wc_ctx->db,
                                                  local_abspath,
-                                                 default_ignores,
+                                                 default_ignores, TRUE,
                                                  result_pool, scratch_pool));
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.c Mon May 14 14:07:45 2012
@@ -5176,6 +5176,66 @@ svn_wc__db_op_mark_conflict(svn_wc__db_t
   NOT_IMPLEMENTED();
 }
 
+/* Baton for db_op_mark_resolved */
+struct op_mark_resolved_baton
+{
+  svn_boolean_t resolved_text;
+  svn_boolean_t resolved_props;
+  svn_boolean_t resolved_tree;
+  const svn_skel_t *work_items;
+};
+
+/* Helper for svn_wc__db_op_mark_resolved */
+static svn_error_t *
+db_op_mark_resolved(void *baton,
+                   svn_wc__db_wcroot_t *wcroot,
+                   const char *local_relpath,
+                   apr_pool_t *scratch_pool)
+{
+  struct op_mark_resolved_baton *rb = baton;
+  svn_sqlite__stmt_t *stmt;
+  int affected_rows;
+  int total_affected_rows = 0;
+
+  if (rb->resolved_text)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_TEXT_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+  if (rb->resolved_props)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_CLEAR_PROPS_CONFLICT));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+  if (rb->resolved_tree)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_UPDATE_ACTUAL_TREE_CONFLICTS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      total_affected_rows += affected_rows;
+    }
+
+  /* Now, remove the actual node if it doesn't have any more useful
+     information.  We only need to do this if we've remove data ourselves. */
+  if (total_affected_rows > 0)
+    {
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_DELETE_ACTUAL_EMPTY));
+      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+      SVN_ERR(svn_sqlite__step_done(stmt));
+    }
+
+  SVN_ERR(add_work_items(wcroot->sdb, rb->work_items, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_wc__db_op_mark_resolved(svn_wc__db_t *db,
@@ -5183,48 +5243,31 @@ svn_wc__db_op_mark_resolved(svn_wc__db_t
                             svn_boolean_t resolved_text,
                             svn_boolean_t resolved_props,
                             svn_boolean_t resolved_tree,
+                            const svn_skel_t *work_items,
                             apr_pool_t *scratch_pool)
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
+  struct op_mark_resolved_baton rb;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  /* ### we're not ready to handy RESOLVED_TREE just yet.  */
-  SVN_ERR_ASSERT(!resolved_tree);
-
   SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
                               local_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  /* ### these two statements are not transacted together. is this a
-     ### problem? I suspect a failure simply leaves the other in a
-     ### continued, unresolved state. However, that still retains
-     ### "integrity", so another re-run by the user will fix it.  */
+  rb.resolved_props = resolved_props;
+  rb.resolved_text = resolved_text;
+  rb.resolved_tree = resolved_tree;
+  rb.work_items = work_items;
 
-  if (resolved_text)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_TEXT_CONFLICT));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-  if (resolved_props)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_CLEAR_PROPS_CONFLICT));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
+  SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath, db_op_mark_resolved,
+                              &rb, scratch_pool));
 
-  /* Some entries have cached the above values. Kapow!!  */
   SVN_ERR(flush_entries(wcroot, local_abspath, svn_depth_empty, scratch_pool));
-
   return SVN_NO_ERROR;
 }
 
-
 /* */
 static svn_error_t *
 set_tc_txn(void *baton,
@@ -11439,7 +11482,7 @@ svn_wc__db_read_conflicts(const apr_arra
           if (conflict_working)
             desc->my_abspath = svn_dirent_join(wcroot->abspath,
                                                conflict_working, result_pool);
-          desc->merged_file = svn_dirent_basename(local_abspath, result_pool);
+          desc->merged_file = apr_pstrdup(result_pool, local_abspath);
 
           APR_ARRAY_PUSH(cflcts, svn_wc_conflict_description2_t*) = desc;
         }

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc_db.h Mon May 14 14:07:45 2012
@@ -1507,6 +1507,7 @@ svn_wc__db_op_mark_resolved(svn_wc__db_t
                             svn_boolean_t resolved_text,
                             svn_boolean_t resolved_props,
                             svn_boolean_t resolved_tree,
+                            const svn_skel_t *work_items,
                             apr_pool_t *scratch_pool);
 
 

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/workqueue.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/workqueue.h Mon May 14 14:07:45 2012
@@ -122,7 +122,7 @@ svn_wc__wq_build_file_remove(svn_skel_t 
                              apr_pool_t *result_pool,
                              apr_pool_t *scratch_pool);
 
-/* Set *WORK_ITEM to a new work item that describes a moves of
+/* Set *WORK_ITEM to a new work item that describes a move of
    a file or directory from SRC_ABSPATH to DST_ABSPATH, ready for
    storing in the working copy managing DST_ABSPATH.
 

Modified: subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/ev2-export/subversion/svn/conflict-callbacks.c Mon May 14 14:07:45 2012
@@ -418,17 +418,19 @@ svn_cl__conflict_handler(svn_wc_conflict
 
       if (desc->kind == svn_wc_conflict_kind_text)
         SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
-                                    _("Conflict discovered in '%s'.\n"),
-                                    svn_dirent_local_style(
-                                      desc->local_abspath, subpool)));
+                                    _("Conflict discovered in file '%s'.\n"),
+                                    svn_cl__local_style_skip_ancestor(
+                                      b->path_prefix, desc->local_abspath,
+                                      subpool)));
       else if (desc->kind == svn_wc_conflict_kind_property)
         {
           SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
                                       _("Conflict for property '%s' discovered"
                                         " on '%s'.\n"),
                                       desc->property_name,
-                                      svn_dirent_local_style(
-                                        desc->local_abspath, subpool)));
+                                      svn_cl__local_style_skip_ancestor(
+                                        b->path_prefix, desc->local_abspath,
+                                        subpool)));
 
           if ((!desc->my_abspath && desc->their_abspath)
               || (desc->my_abspath && !desc->their_abspath))
@@ -721,7 +723,9 @@ svn_cl__conflict_handler(svn_wc_conflict
                    stderr, subpool,
                    _("Conflict discovered when trying to add '%s'.\n"
                      "An object of the same name already exists.\n"),
-                   svn_dirent_local_style(desc->local_abspath, subpool)));
+                   svn_cl__local_style_skip_ancestor(b->path_prefix,
+                                                     desc->local_abspath,
+                                                     subpool)));
       prompt = _("Select: (p) postpone, (mf) mine-full, "
                  "(tf) theirs-full, (h) help:");
 

Modified: subversion/branches/ev2-export/subversion/svn/resolve-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svn/resolve-cmd.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svn/resolve-cmd.c (original)
+++ subversion/branches/ev2-export/subversion/svn/resolve-cmd.c Mon May 14 14:07:45 2012
@@ -96,7 +96,7 @@ svn_cl__resolve(apr_getopt_t *os,
 
   if (opt_state->depth == svn_depth_unknown)
     {
-      if (opt_state->accept_which == svn_wc_conflict_choose_unspecified)
+      if (opt_state->accept_which == svn_cl__accept_unspecified)
         opt_state->depth = svn_depth_infinity;
       else
         opt_state->depth = svn_depth_empty;

Modified: subversion/branches/ev2-export/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnserve/serve.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnserve/serve.c (original)
+++ subversion/branches/ev2-export/subversion/svnserve/serve.c Mon May 14 14:07:45 2012
@@ -1566,7 +1566,12 @@ static svn_error_t *get_dir(svn_ra_svn_c
           svn_node_kind_t entry_kind = svn_node_none;
           svn_filesize_t entry_size = 0;
           svn_boolean_t has_props = FALSE;
-          svn_revnum_t created_rev = 0; /* ### SVN_INVALID_REVNUM  */
+          /* If 'created rev' was not requested, send 0.  We can't use
+           * SVN_INVALID_REVNUM as the tuple field is not optional.
+           * See the email thread on dev@, 2012-03-28, subject
+           * "buildbot failure in ASF Buildbot on svn-slik-w2k3-x64-ra",
+           * <http://svn.haxx.se/dev/archive-2012-03/0655.shtml>. */
+          svn_revnum_t created_rev = 0;
           const char *cdate = NULL;
           const char *last_author = NULL;
 

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/davautocheck.sh?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/davautocheck.sh Mon May 14 14:07:45 2012
@@ -90,6 +90,7 @@ export LC_ALL
 
 stop_httpd_and_die() {
   [ -e "$HTTPD_PID" ] && kill $(cat "$HTTPD_PID")
+  echo "HTTPD stopped."
   exit 1
 }
 

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/lock_tests.py Mon May 14 14:07:45 2012
@@ -79,9 +79,8 @@ def lock_file(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_b)
 
   # lock a file as wc_author
-  fname = 'iota'
-  file_path = os.path.join(sbox.wc_dir, fname)
-  file_path_b = os.path.join(wc_b, fname)
+  file_path = sbox.ospath('iota')
+  file_path_b = sbox.ospath('iota', wc_dir=wc_b)
 
   svntest.main.file_append(file_path, "This represents a binary file\n")
   svntest.main.run_svn(None, 'commit',
@@ -133,45 +132,42 @@ def commit_file_keep_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  fname = 'A/mu'
-  file_path = os.path.join(sbox.wc_dir, fname)
-
-  # lock fname as wc_author
+  # lock 'A/mu' as wc_author
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
-                                     '-m', 'some lock comment', file_path)
+                                     '-m', 'some lock comment',
+                                     sbox.ospath('A/mu'))
 
   # make a change and commit it, holding lock
-  svntest.main.file_append(file_path, "Tweak!\n")
+  sbox.simple_append('A/mu', 'Tweak!\n')
   svntest.main.run_svn(None, 'commit', '-m', '', '--no-unlock',
-                       file_path)
+                       sbox.ospath('A/mu'))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
-  expected_status.tweak(fname, wc_rev=2)
-  expected_status.tweak(fname, writelocked='K')
+  expected_status.tweak('A/mu', wc_rev=2, writelocked='K')
 
   # Make sure the file is still locked
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+
 def commit_file_unlock(sbox):
   "commit a file and release lock"
 
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  fname = 'A/mu'
-  file_path = os.path.join(sbox.wc_dir, fname)
-
-  # lock fname as wc_author
+  # lock A/mu and iota as wc_author
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
-                                     '-m', 'some lock comment', file_path)
+                                     '-m', 'some lock comment',
+                                     sbox.ospath('A/mu'),
+                                     sbox.ospath('iota'))
 
   # make a change and commit it, allowing lock to be released
-  svntest.main.file_append(file_path, "Tweak!\n")
-  svntest.main.run_svn(None, 'commit', '-m', '',
-                       file_path)
+  sbox.simple_append('A/mu', 'Tweak!\n')
+  sbox.simple_commit()
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
-  expected_status.tweak(fname, wc_rev=2)
+  expected_status.tweak('A/mu', wc_rev=2)
+  expected_status.tweak('iota', wc_rev=2)
 
   # Make sure the file is unlocked
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -183,20 +179,17 @@ def commit_propchange(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  fname = 'A/mu'
-  file_path = os.path.join(sbox.wc_dir, fname)
-
-  # lock fname as wc_author
+  # lock A/mu as wc_author
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
-                                     '-m', 'some lock comment', file_path)
+                                     '-m', 'some lock comment',
+                                     sbox.ospath('A/mu'))
 
   # make a property change and commit it, allowing lock to be released
-  svntest.main.run_svn(None, 'propset', 'blue', 'azul', file_path)
-  svntest.main.run_svn(None, 'commit',
-                             '-m', '', file_path)
+  sbox.simple_propset('blue', 'azul', 'A/mu')
+  sbox.simple_commit('A/mu')
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
-  expected_status.tweak(fname, wc_rev=2)
+  expected_status.tweak('A/mu', wc_rev=2)
 
   # Make sure the file is unlocked
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -222,9 +215,8 @@ def break_lock(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_b)
 
   # lock a file as wc_author
-  fname = 'iota'
-  file_path = os.path.join(sbox.wc_dir, fname)
-  file_path_b = os.path.join(wc_b, fname)
+  file_path = sbox.ospath('iota')
+  file_path_b = sbox.ospath('iota', wc_dir=wc_b)
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      '-m', '', file_path)
@@ -265,9 +257,8 @@ def steal_lock(sbox):
   svntest.actions.duplicate_dir(wc_dir, wc_b)
 
   # lock a file as wc_author
-  fname = 'iota'
-  file_path = os.path.join(sbox.wc_dir, fname)
-  file_path_b = os.path.join(wc_b, fname)
+  file_path = sbox.ospath('iota')
+  file_path_b = sbox.ospath('iota', wc_dir=wc_b)
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      '-m', '', file_path)
@@ -295,14 +286,9 @@ def examine_lock(sbox):
   "examine the fields of a lockfile for correctness"
 
   sbox.build()
-  wc_dir = sbox.wc_dir
-
-  fname = 'iota'
-  comment = 'This is a lock test.'
-  file_path = os.path.join(sbox.wc_dir, fname)
 
   # lock a file as wc_author
-  svntest.actions.run_and_validate_lock(file_path,
+  svntest.actions.run_and_validate_lock(sbox.ospath('iota'),
                                         svntest.main.wc_author)
 
 #----------------------------------------------------------------------
@@ -315,21 +301,17 @@ def handle_defunct_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-
-  fname = 'iota'
-  file_path = os.path.join(sbox.wc_dir, fname)
-
   # set up our expected status
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
 
   # lock the file
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
-                                     '-m', '', file_path)
+                                     '-m', '', sbox.ospath('iota'))
 
   # Make a second copy of the working copy
   wc_b = sbox.add_wc_path('_b')
   svntest.actions.duplicate_dir(wc_dir, wc_b)
-  file_path_b = os.path.join(wc_b, fname)
+  file_path_b = sbox.ospath('iota', wc_dir=wc_b)
 
   # --- Meanwhile, in our other working copy... ---
 
@@ -339,7 +321,7 @@ def handle_defunct_lock(sbox):
 
 
   # update the 1st wc, which should clear the lock there
-  svntest.main.run_svn(None, 'update', wc_dir)
+  sbox.simple_update()
 
   # Make sure the file is unlocked
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -357,9 +339,9 @@ def enforce_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  iota_path = sbox.ospath('iota')
+  lambda_path = sbox.ospath('A/B/lambda')
+  mu_path = sbox.ospath('A/mu')
 
   # svn:needs-lock value should be forced to a '*'
   svntest.actions.set_prop('svn:needs-lock', 'foo', iota_path)
@@ -418,30 +400,22 @@ def update_while_needing_lock(sbox):
   "update handles svn:needs-lock correctly"
 
   sbox.build()
-  wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  svntest.main.run_svn(None,
-                       'propset', 'svn:needs-lock', 'foo', iota_path)
-  svntest.main.run_svn(None,
-                       'commit', '-m', 'log msg', iota_path)
-  svntest.main.run_svn(None,
-                       'up', wc_dir)
+  sbox.simple_propset('svn:needs-lock', 'foo', 'iota')
+  sbox.simple_commit('iota')
+  sbox.simple_update()
 
   # Lock, modify, commit, unlock, to create r3.
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
-                                     '-m', '', iota_path)
-  svntest.main.file_append(iota_path, "This line added in r2.\n")
-  svntest.main.run_svn(None, 'commit',
-                       '-m', '', iota_path) # auto-unlocks
+                                     '-m', '', sbox.ospath('iota'))
+  sbox.simple_append('iota', 'This line added in r2.\n')
+  sbox.simple_commit('iota') # auto-unlocks
 
   # Backdate to r2.
-  svntest.main.run_svn(None,
-                       'update', '-r2', iota_path)
+  sbox.simple_update(revision=2)
 
   # Try updating forward to r3 again.  This is where the bug happened.
-  svntest.main.run_svn(None,
-                       'update', '-r3', iota_path)
+  sbox.simple_update(revision=3)
 
 
 #----------------------------------------------------------------------
@@ -456,17 +430,16 @@ def defunct_lock(sbox):
   wc_b = sbox.add_wc_path('_b')
   svntest.actions.duplicate_dir(wc_dir, wc_b)
 
-  iota_path = os.path.join(wc_dir, 'iota')
-  iota_path_b = os.path.join(wc_b, 'iota')
+  iota_path = sbox.ospath('iota')
+  iota_path_b = sbox.ospath('iota', wc_dir=wc_b)
 
   mode = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
 
 # Set the prop in wc a
-  svntest.main.run_svn(None, 'propset', 'svn:needs-lock', 'foo', iota_path)
+  sbox.simple_propset('svn:needs-lock', 'foo', 'iota')
 
   # commit r2
-  svntest.main.run_svn(None, 'commit',
-                       '-m', '', iota_path)
+  sbox.simple_commit('iota')
 
   # update wc_b
   svntest.main.run_svn(None, 'update', wc_b)
@@ -498,14 +471,13 @@ def deleted_path_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
+  iota_path = sbox.ospath('iota')
   iota_url = sbox.repo_url + '/iota'
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      '-m', '', iota_path)
 
-  svntest.actions.run_and_verify_svn(None, None, [], 'delete', iota_path)
-
+  sbox.simple_rm('iota')
   svntest.actions.run_and_verify_svn(None, None, [], 'commit',
                                      '--no-unlock',
                                      '-m', '', iota_path)
@@ -524,9 +496,9 @@ def lock_unlock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
+  pi_path = sbox.ospath('A/D/G/pi')
+  rho_path = sbox.ospath('A/D/G/rho')
+  tau_path = sbox.ospath('A/D/G/tau')
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', writelocked='K')
@@ -551,19 +523,17 @@ def deleted_dir_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  parent_dir = os.path.join(wc_dir, 'A', 'D', 'G')
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
-  rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
-  tau_path = os.path.join(wc_dir, 'A', 'D', 'G', 'tau')
+  pi_path = sbox.ospath('A/D/G/pi')
+  rho_path = sbox.ospath('A/D/G/rho')
+  tau_path = sbox.ospath('A/D/G/tau')
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      '-m', '', pi_path, rho_path, tau_path)
 
-  svntest.actions.run_and_verify_svn(None, None, [], 'delete', parent_dir)
-
+  sbox.simple_rm('A/D/G')  # the parent directory
   svntest.actions.run_and_verify_svn(None, None, [], 'commit',
                                      '--no-unlock',
-                                     '-m', '', parent_dir)
+                                     '-m', '', sbox.ospath('A/D/G'))
 
 #----------------------------------------------------------------------
 # III.c : Lock a file and check the output of 'svn stat' from the same
@@ -581,30 +551,27 @@ def lock_status(sbox):
   fname = 'iota'
   file_path = os.path.join(sbox.wc_dir, fname)
 
-  svntest.main.file_append(file_path, "This is a spreadsheet\n")
-  svntest.main.run_svn(None, 'commit',
-                       '-m', '', file_path)
+  sbox.simple_append('iota', "This is a spreadsheet\n")
+  sbox.simple_commit('iota')
 
-  svntest.main.run_svn(None, 'lock',
-                       '-m', '', file_path)
+  svntest.main.run_svn(None, 'lock', '-m', '', sbox.ospath('iota'))
 
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
-  expected_status.tweak(fname, wc_rev=2)
-  expected_status.tweak(fname, writelocked='K')
+  expected_status.tweak('iota', wc_rev=2, writelocked='K')
 
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Verify status again after modifying the file
-  svntest.main.file_append(file_path, "check stat output after mod")
+  sbox.simple_append('iota', 'check stat output after mod')
 
-  expected_status.tweak(fname, status='M ')
+  expected_status.tweak('iota', status='M ')
 
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
   # Verify status of lock from another working copy
   svntest.main.run_svn(None, 'update', wc_b)
   expected_status = svntest.actions.get_virginal_state(wc_b, 2)
-  expected_status.tweak(fname, writelocked='O')
+  expected_status.tweak('iota', writelocked='O')
 
   svntest.actions.run_and_verify_status(wc_b, expected_status)
 
@@ -744,7 +711,7 @@ def revert_lock(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  iota_path = os.path.join(wc_dir, 'iota')
+  iota_path = sbox.ospath('iota')
 
   mode = stat.S_IWGRP | stat.S_IWOTH | stat.S_IWRITE
 
@@ -863,8 +830,8 @@ def lock_switched_files(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
+  gamma_path = sbox.ospath('A/D/gamma')
+  lambda_path = sbox.ospath('A/B/lambda')
   iota_URL = sbox.repo_url + '/iota'
   alpha_URL = sbox.repo_url + '/A/B/E/alpha'
 
@@ -910,7 +877,7 @@ def lock_uri_encoded(sbox):
 
   # lock a file as wc_author
   fname = 'amazing space'
-  file_path = os.path.join(wc_dir, fname)
+  file_path = sbox.ospath(fname)
 
   svntest.main.file_append(file_path, "This represents a binary file\n")
   svntest.actions.run_and_verify_svn(None, None, [], "add", file_path)
@@ -974,7 +941,7 @@ def lock_and_exebit1(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
 
   expected_err = ".*svn: warning: W125005: To turn off the svn:needs-lock property,.*"
   svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
@@ -1051,7 +1018,7 @@ def lock_and_exebit2(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
 
   expected_err = ".*svn: warning: W125005: To turn off the svn:needs-lock property,.*"
   svntest.actions.run_and_verify_svn2(None, None, expected_err, 0,
@@ -1180,10 +1147,10 @@ def unlock_already_unlocked_files(sbox):
   wc_dir = sbox.wc_dir
 
   # Deliberately have no direct child of A as a target
-  iota_path = os.path.join(wc_dir, 'iota')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
-  alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
+  iota_path = sbox.ospath('iota')
+  lambda_path = sbox.ospath('A/B/lambda')
+  alpha_path = sbox.ospath('A/B/E/alpha')
+  gamma_path = sbox.ospath('A/D/gamma')
 
   svntest.actions.run_and_verify_svn(None, ".*locked by user", [], 'lock',
                                      '--username', svntest.main.wc_author2,
@@ -1228,8 +1195,8 @@ def info_moved_path(sbox):
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  fname = os.path.join(wc_dir, "iota")
-  fname2 = os.path.join(wc_dir, "iota2")
+  fname = sbox.ospath("iota")
+  fname2 = sbox.ospath("iota2")
 
   # Move iota, creating r2.
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -1284,7 +1251,7 @@ def ls_url_encoded(sbox):
 
   sbox.build()
   wc_dir = sbox.wc_dir
-  dirname = os.path.join(wc_dir, "space dir")
+  dirname = sbox.ospath("space dir")
   fname = os.path.join(dirname, "f")
 
   # Create a dir with a space in its name and a file therein.
@@ -1390,7 +1357,7 @@ def unlocked_lock_of_other_user(sbox):
   wc_dir = sbox.wc_dir
 
   # lock a file with user jrandom
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
+  pi_path = sbox.ospath('A/D/G/pi')
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/G/pi', writelocked='K')
 
@@ -1438,8 +1405,8 @@ def lock_twice_in_one_wc(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  mu2_path = os.path.join(wc_dir, 'A', 'B', 'mu')
+  mu_path = sbox.ospath('A/mu')
+  mu2_path = sbox.ospath('A/B/mu')
 
   # Create a needs-lock file
   svntest.actions.set_prop('svn:needs-lock', '*', mu_path)
@@ -1453,7 +1420,7 @@ def lock_twice_in_one_wc(sbox):
   # Switch a second location for the same file in the same working copy
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'switch', sbox.repo_url + '/A',
-                                     os.path.join(wc_dir, 'A', 'B'),
+                                     sbox.ospath('A/B'),
                                      '--ignore-ancestry')
 
   # Lock location 1
@@ -1489,8 +1456,8 @@ def lock_path_not_in_head(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  D_path      = os.path.join(wc_dir, 'A', 'D')
-  lambda_path = os.path.join(wc_dir, 'A', 'B', 'lambda')
+  D_path      = sbox.ospath('A/D')
+  lambda_path = sbox.ospath('A/B/lambda')
 
   # Commit deletion of A/D and A/B/lambda as r2, then update the WC
   # back to r1.  Then attempt to lock some paths that no longer exist
@@ -1528,9 +1495,9 @@ def verify_path_escaping(sbox):
 
   # Add test paths using two characters that need escaping in a url, but
   # are within the normal ascii range
-  file1 = os.path.join(wc_dir, 'file #1')
-  file2 = os.path.join(wc_dir, 'file #2')
-  file3 = os.path.join(wc_dir, 'file #3')
+  file1 = sbox.ospath('file #1')
+  file2 = sbox.ospath('file #2')
+  file3 = sbox.ospath('file #3')
 
   svntest.main.file_write(file1, 'File 1')
   svntest.main.file_write(file2, 'File 2')
@@ -1567,9 +1534,9 @@ def replace_and_propset_locked_path(sbox
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
-  rho_path = os.path.join(G_path, 'rho')
+  mu_path = sbox.ospath('A/mu')
+  G_path = sbox.ospath('A/D/G')
+  rho_path = sbox.ospath('A/D/G/rho')
 
   # Lock mu and A/D/G/rho.
   svntest.actions.run_and_verify_svn(None, None, [],
@@ -1616,10 +1583,10 @@ def cp_isnt_ro(sbox):
   wc_dir = sbox.wc_dir
 
   mu_URL = sbox.repo_url + '/A/mu'
-  mu_path = os.path.join(wc_dir, 'A', 'mu')
-  mu2_path = os.path.join(wc_dir, 'A', 'mu2')
-  mu3_path = os.path.join(wc_dir, 'A', 'mu3')
-  kappa_path = os.path.join(wc_dir, 'kappa')
+  mu_path = sbox.ospath('A/mu')
+  mu2_path = sbox.ospath('A/mu2')
+  mu3_path = sbox.ospath('A/mu3')
+  kappa_path = sbox.ospath('kappa')
   open(kappa_path, 'w').write("This is the file 'kappa'.\n")
 
   ## added file
@@ -1713,7 +1680,7 @@ def block_unlock_if_pre_unlock_hook_fail
   svntest.actions.create_failing_hook(repo_dir, "pre-unlock", "error text")
 
   # lock a file.
-  pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
+  pi_path = sbox.ospath('A/D/G/pi')
   expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_status.tweak('A/D/G/pi', writelocked='K')
 

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/special_tests.py?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/special_tests.py Mon May 14 14:07:45 2012
@@ -608,10 +608,8 @@ def replace_symlink_with_dir(sbox):
   expected_output = svntest.wc.State(wc_dir, {
   })
 
-  if svntest.main.is_posix_os():
-    error_re_string = '.*E145001: Entry.*has unexpectedly changed special.*'
-  else:
-    error_re_string = None
+  error_re_string = 'E145001: (Entry|Node).*has.*changed (special|kind)'
+
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         None, error_re_string, wc_dir)