You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/12/04 16:35:57 UTC

svn commit: r1416996 [10/13] - in /subversion/branches/wc-collate-path: ./ build/ build/ac-macros/ build/generator/ contrib/client-side/svnmerge/ contrib/server-side/svncutter/ notes/ subversion/bindings/cxxhl/ subversion/bindings/javahl/native/ subver...

Modified: subversion/branches/wc-collate-path/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/svnrdump/dump_editor.c?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/wc-collate-path/subversion/svnrdump/dump_editor.c Tue Dec  4 15:35:13 2012
@@ -30,10 +30,10 @@
 #include "svn_subst.h"
 #include "svn_dirent_uri.h"
 
-#include "private/svn_fspath.h"
 #include "private/svn_subr_private.h"
 
 #include "svnrdump.h"
+#include <assert.h>
 
 #define ARE_VALID_COPY_ARGS(p,r) ((p) && SVN_IS_VALID_REVNUM(r))
 
@@ -50,14 +50,16 @@ struct dir_baton
   struct dump_edit_baton *eb;
   struct dir_baton *parent_dir_baton;
 
+  apr_pool_t *pool; /* Directory pool */
+
   /* is this directory a new addition to this revision? */
   svn_boolean_t added;
 
   /* has this directory been written to the output stream? */
   svn_boolean_t written_out;
 
-  /* the absolute path to this directory */
-  const char *abspath; /* an fspath */
+  /* the path to this directory */
+  const char *repos_relpath; /* a relpath */
 
   /* Copyfrom info for the node, if any. */
   const char *copyfrom_path; /* a relpath */
@@ -70,6 +72,20 @@ struct dir_baton
   apr_hash_t *deleted_entries;
 };
 
+/* A file baton used by all file-related callback functions in the dump
+ * editor */
+struct file_baton
+{
+  struct dump_edit_baton *eb;
+  struct dir_baton *parent_dir_baton;
+
+  /* the path to this file */
+  const char *repos_relpath; /* a relpath */
+
+  /* The checksum of the file the delta is being applied to */
+  const char *base_checksum;
+};
+
 /* A handler baton to be used in window_handler().  */
 struct handler_baton
 {
@@ -106,9 +122,6 @@ struct dump_edit_baton {
   const char *delta_abspath;
   apr_file_t *delta_file;
 
-  /* The checksum of the file the delta is being applied to */
-  const char *base_checksum;
-
   /* Flags to trigger dumping props and text */
   svn_boolean_t dump_text;
   svn_boolean_t dump_props;
@@ -142,16 +155,13 @@ make_dir_baton(const char *path,
   struct dump_edit_baton *eb = edit_baton;
   struct dir_baton *pb = parent_dir_baton;
   struct dir_baton *new_db = apr_pcalloc(pool, sizeof(*new_db));
-  const char *abspath;
+  const char *repos_relpath;
 
   /* Construct the full path of this node. */
-  /* ### FIXME: Not sure why we use an abspath here.  If I understand
-     ### correctly, the only place we used this path is in dump_node(),
-     ### which immediately converts it into a relpath.  -- cmpilato.  */
   if (pb)
-    abspath = svn_fspath__canonicalize(path, pool);
+    repos_relpath = svn_relpath_canonicalize(path, pool);
   else
-    abspath = "/";
+    repos_relpath = "";
 
   /* Strip leading slash from copyfrom_path so that the path is
      canonical and svn_relpath_join can be used */
@@ -160,8 +170,11 @@ make_dir_baton(const char *path,
 
   new_db->eb = eb;
   new_db->parent_dir_baton = pb;
-  new_db->abspath = abspath;
-  new_db->copyfrom_path = copyfrom_path;
+  new_db->pool = pool;
+  new_db->repos_relpath = repos_relpath;
+  new_db->copyfrom_path = copyfrom_path 
+                            ? svn_relpath_canonicalize(copyfrom_path, pool)
+                            : NULL;
   new_db->copyfrom_rev = copyfrom_rev;
   new_db->added = added;
   new_db->written_out = FALSE;
@@ -287,7 +300,7 @@ do_dump_newlines(struct dump_edit_baton 
  */
 static svn_error_t *
 dump_node(struct dump_edit_baton *eb,
-          const char *path,    /* an absolute path. */
+          const char *repos_relpath,
           svn_node_kind_t kind,
           enum svn_node_action action,
           svn_boolean_t is_copy,
@@ -295,16 +308,12 @@ dump_node(struct dump_edit_baton *eb,
           svn_revnum_t copyfrom_rev,
           apr_pool_t *pool)
 {
-  /* Remove leading slashes from path and copyfrom_path */
-  if (path)
-    path = svn_relpath_canonicalize(path, pool);
-
-  if (copyfrom_path)
-    copyfrom_path = svn_relpath_canonicalize(copyfrom_path, pool);
+  assert(svn_relpath_is_canonical(repos_relpath));
+  assert(!copyfrom_path || svn_relpath_is_canonical(copyfrom_path));
 
   /* Node-path: commons/STATUS */
   SVN_ERR(svn_stream_printf(eb->stream, pool,
-                            SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n", path));
+                            SVN_REPOS_DUMPFILE_NODE_PATH ": %s\n", repos_relpath));
 
   /* Node-kind: file */
   if (kind == svn_node_file)
@@ -347,7 +356,7 @@ dump_node(struct dump_edit_baton *eb,
                               SVN_REPOS_DUMPFILE_NODE_ACTION ": delete\n\n"));
 
       /* Recurse: Print an additional add-with-history record. */
-      SVN_ERR(dump_node(eb, path, kind, svn_node_action_add,
+      SVN_ERR(dump_node(eb, repos_relpath, kind, svn_node_action_add,
                         is_copy, copyfrom_path, copyfrom_rev, pool));
 
       /* We can leave this routine quietly now, don't need to dump any
@@ -428,6 +437,24 @@ open_root(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
+/* Dump pending items from the specified node, to allow starting the dump
+   of a child node */
+static svn_error_t *
+dump_pending(struct dir_baton *pb,
+             apr_pool_t *scratch_pool)
+{
+  /* Some pending properties to dump? */
+  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
+                        pb->eb->props, pb->eb->deleted_props,
+                        &(pb->eb->dump_props), TRUE,
+                        pb->pool, scratch_pool));
+
+  /* Some pending newlines to dump? */
+  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 delete_entry(const char *path,
              svn_revnum_t revision,
@@ -438,13 +465,7 @@ delete_entry(const char *path,
 
   LDR_DBG(("delete_entry %s\n", path));
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
-                        pb->eb->props, pb->eb->deleted_props,
-                        &(pb->eb->dump_props), TRUE, pool, pool));
-
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(pb, pool));
 
   /* Add this path to the deleted_entries of the parent directory
      baton. */
@@ -472,13 +493,7 @@ add_directory(const char *path,
   new_db = make_dir_baton(path, copyfrom_path, copyfrom_rev, pb->eb,
                           pb, TRUE, pb->eb->pool);
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
-                        pb->eb->props, pb->eb->deleted_props,
-                        &(pb->eb->dump_props), TRUE, pool, pool));
-
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(pb, pool));
 
   /* This might be a replacement -- is the path already deleted? */
   val = apr_hash_get(pb->deleted_entries, path, APR_HASH_KEY_STRING);
@@ -487,11 +502,11 @@ add_directory(const char *path,
   is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);
 
   /* Dump the node */
-  SVN_ERR(dump_node(pb->eb, path,
+  SVN_ERR(dump_node(pb->eb, new_db->repos_relpath,
                     svn_node_dir,
                     val ? svn_node_action_replace : svn_node_action_add,
                     is_copy,
-                    is_copy ? copyfrom_path : NULL,
+                    is_copy ? new_db->copyfrom_path : NULL,
                     is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
                     pool));
 
@@ -519,13 +534,7 @@ open_directory(const char *path,
 
   LDR_DBG(("open_directory %s\n", path));
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
-                        pb->eb->props, pb->eb->deleted_props,
-                        &(pb->eb->dump_props), TRUE, pool, pool));
-
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(pb, pool));
 
   /* If the parent directory has explicit comparison path and rev,
      record the same for this one. */
@@ -548,18 +557,11 @@ close_directory(void *dir_baton,
                 apr_pool_t *pool)
 {
   struct dir_baton *db = dir_baton;
-  struct dump_edit_baton *eb = db->eb;
   apr_hash_index_t *hi;
 
   LDR_DBG(("close_directory %p\n", dir_baton));
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&eb->propstring, eb->stream,
-                        eb->props, eb->deleted_props,
-                        &(eb->dump_props), TRUE, pool, pool));
-
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(eb, &(eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(db, pool));
 
   /* Dump the deleted directory entries */
   for (hi = apr_hash_first(pool, db->deleted_entries); hi;
@@ -584,18 +586,17 @@ add_file(const char *path,
          void **file_baton)
 {
   struct dir_baton *pb = parent_baton;
+  struct file_baton *fb = apr_pcalloc(pool, sizeof(*fb));
   void *val;
   svn_boolean_t is_copy;
 
-  LDR_DBG(("add_file %s\n", path));
+  fb->eb = pb->eb;
+  fb->parent_dir_baton = pb;
+  fb->repos_relpath = svn_relpath_canonicalize(path, pool);
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
-                        pb->eb->props, pb->eb->deleted_props,
-                        &(pb->eb->dump_props), TRUE, pool, pool));
+  LDR_DBG(("add_file %s\n", path));
 
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(pb, pool));
 
   /* This might be a replacement -- is the path already deleted? */
   val = apr_hash_get(pb->deleted_entries, path, APR_HASH_KEY_STRING);
@@ -604,11 +605,12 @@ add_file(const char *path,
   is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);
 
   /* Dump the node. */
-  SVN_ERR(dump_node(pb->eb, path,
+  SVN_ERR(dump_node(pb->eb, fb->repos_relpath,
                     svn_node_file,
                     val ? svn_node_action_replace : svn_node_action_add,
                     is_copy,
-                    is_copy ? copyfrom_path : NULL,
+                    is_copy ? svn_relpath_canonicalize(copyfrom_path, pool)
+                            : NULL,
                     is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
                     pool));
 
@@ -618,7 +620,7 @@ add_file(const char *path,
 
   /* Build a nice file baton to pass to change_file_prop and
      apply_textdelta */
-  *file_baton = pb->eb;
+  *file_baton = fb;
 
   return SVN_NO_ERROR;
 }
@@ -631,18 +633,17 @@ open_file(const char *path,
           void **file_baton)
 {
   struct dir_baton *pb = parent_baton;
+  struct file_baton *fb = apr_pcalloc(pool, sizeof(*fb));
   const char *copyfrom_path = NULL;
   svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
 
-  LDR_DBG(("open_file %s\n", path));
+  fb->eb = pb->eb;
+  fb->parent_dir_baton = pb;
+  fb->repos_relpath = svn_relpath_canonicalize(path, pool);
 
-  /* Some pending properties to dump? */
-  SVN_ERR(do_dump_props(&pb->eb->propstring, pb->eb->stream,
-                        pb->eb->props, pb->eb->deleted_props,
-                        &(pb->eb->dump_props), TRUE, pool, pool));
+  LDR_DBG(("open_file %s\n", path));
 
-  /* Some pending newlines to dump? */
-  SVN_ERR(do_dump_newlines(pb->eb, &(pb->eb->dump_newlines), pool));
+  SVN_ERR(dump_pending(pb, pool));
 
   /* If the parent directory has explicit copyfrom path and rev,
      record the same for this one. */
@@ -654,12 +655,13 @@ open_file(const char *path,
       copyfrom_rev = pb->copyfrom_rev;
     }
 
-  SVN_ERR(dump_node(pb->eb, path, svn_node_file, svn_node_action_change,
-                    FALSE, copyfrom_path, copyfrom_rev, pool));
+  SVN_ERR(dump_node(pb->eb, fb->repos_relpath, svn_node_file,
+                    svn_node_action_change, FALSE, copyfrom_path,
+                    copyfrom_rev, pool));
 
   /* Build a nice file baton to pass to change_file_prop and
      apply_textdelta */
-  *file_baton = pb->eb;
+  *file_baton = fb;
 
   return SVN_NO_ERROR;
 }
@@ -692,7 +694,7 @@ change_dir_prop(void *parent_baton,
          props. If it not, dump the node itself before dumping the
          props. */
 
-      SVN_ERR(dump_node(db->eb, db->abspath, svn_node_dir,
+      SVN_ERR(dump_node(db->eb, db->repos_relpath, svn_node_dir,
                         svn_node_action_change, FALSE, db->copyfrom_path,
                         db->copyfrom_rev, pool));
       db->written_out = TRUE;
@@ -712,7 +714,8 @@ change_file_prop(void *file_baton,
                  const svn_string_t *value,
                  apr_pool_t *pool)
 {
-  struct dump_edit_baton *eb = file_baton;
+  struct file_baton *fb = file_baton;
+  struct dump_edit_baton *eb = fb->eb;
 
   LDR_DBG(("change_file_prop %p\n", file_baton));
 
@@ -756,7 +759,8 @@ apply_textdelta(void *file_baton, const 
                 svn_txdelta_window_handler_t *handler,
                 void **handler_baton)
 {
-  struct dump_edit_baton *eb = file_baton;
+  struct file_baton *fb = file_baton;
+  struct dump_edit_baton *eb = fb->eb;
 
   /* Custom handler_baton allocated in a separate pool */
   struct handler_baton *hb;
@@ -775,8 +779,7 @@ apply_textdelta(void *file_baton, const 
                           SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
 
   eb->dump_text = TRUE;
-  eb->base_checksum = apr_pstrdup(eb->pool, base_checksum);
-  SVN_ERR(svn_stream_close(delta_filestream));
+  fb->base_checksum = apr_pstrdup(eb->pool, base_checksum);
 
   /* The actual writing takes place when this function has
      finished. Set handler and handler_baton now so for
@@ -792,7 +795,8 @@ close_file(void *file_baton,
            const char *text_checksum,
            apr_pool_t *pool)
 {
-  struct dump_edit_baton *eb = file_baton;
+  struct file_baton *fb = file_baton;
+  struct dump_edit_baton *eb = fb->eb;
   apr_finfo_t *info = apr_pcalloc(pool, sizeof(apr_finfo_t));
 
   LDR_DBG(("close_file %p\n", file_baton));
@@ -817,12 +821,12 @@ close_file(void *file_baton,
       if (err)
         SVN_ERR(svn_error_wrap_apr(err, NULL));
 
-      if (eb->base_checksum)
+      if (fb->base_checksum)
         /* Text-delta-base-md5: */
         SVN_ERR(svn_stream_printf(eb->stream, pool,
                                   SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_MD5
                                   ": %s\n",
-                                  eb->base_checksum));
+                                  fb->base_checksum));
 
       /* Text-content-length: 39 */
       SVN_ERR(svn_stream_printf(eb->stream, pool,

Modified: subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.c?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.c Tue Dec  4 15:35:13 2012
@@ -39,6 +39,7 @@
 #include "svnrdump.h"
 
 #include "private/svn_cmdline_private.h"
+#include "private/svn_ra_private.h"
 
 
 
@@ -248,6 +249,81 @@ replay_revend(svn_revnum_t revision,
   return SVN_NO_ERROR;
 }
 
+#ifdef USE_EV2_IMPL
+/* Print dumpstream-formatted information about REVISION.
+ * Implements the `svn_ra_replay_revstart_callback_t' interface.
+ */
+static svn_error_t *
+replay_revstart_v2(svn_revnum_t revision,
+                   void *replay_baton,
+                   svn_editor_t **editor,
+                   apr_hash_t *rev_props,
+                   apr_pool_t *pool)
+{
+  struct replay_baton *rb = replay_baton;
+  apr_hash_t *normal_props;
+  svn_stringbuf_t *propstring;
+  svn_stream_t *stdout_stream;
+  svn_stream_t *revprop_stream;
+
+  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+
+  /* Revision-number: 19 */
+  SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                            SVN_REPOS_DUMPFILE_REVISION_NUMBER
+                            ": %ld\n", revision));
+  SVN_ERR(svn_rdump__normalize_props(&normal_props, rev_props, pool));
+  propstring = svn_stringbuf_create_ensure(0, pool);
+  revprop_stream = svn_stream_from_stringbuf(propstring, pool);
+  SVN_ERR(svn_hash_write2(normal_props, revprop_stream, "PROPS-END", pool));
+  SVN_ERR(svn_stream_close(revprop_stream));
+
+  /* Prop-content-length: 13 */
+  SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                            SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH
+                            ": %" APR_SIZE_T_FMT "\n", propstring->len));
+
+  /* Content-length: 29 */
+  SVN_ERR(svn_stream_printf(stdout_stream, pool,
+                            SVN_REPOS_DUMPFILE_CONTENT_LENGTH
+                            ": %" APR_SIZE_T_FMT "\n\n", propstring->len));
+
+  /* Property data. */
+  SVN_ERR(svn_stream_write(stdout_stream, propstring->data,
+                           &(propstring->len)));
+
+  SVN_ERR(svn_stream_puts(stdout_stream, "\n"));
+  SVN_ERR(svn_stream_close(stdout_stream));
+
+  SVN_ERR(svn_rdump__get_dump_editor_v2(editor, revision,
+                                        rb->stdout_stream,
+                                        rb->extra_ra_session,
+                                        check_cancel, NULL, pool, pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Print progress information about the dump of REVISION.
+   Implements the `svn_ra_replay_revfinish_callback_t' interface. */
+static svn_error_t *
+replay_revend_v2(svn_revnum_t revision,
+                 void *replay_baton,
+                 svn_editor_t *editor,
+                 apr_hash_t *rev_props,
+                 apr_pool_t *pool)
+{
+  /* No resources left to free. */
+  struct replay_baton *rb = replay_baton;
+
+  SVN_ERR(svn_editor_complete(editor));
+
+  if (! rb->quiet)
+    SVN_ERR(svn_cmdline_fprintf(stderr, pool, "* Dumped revision %lu.\n",
+                                revision));
+  return SVN_NO_ERROR;
+}
+#endif
+
 /* Initialize the RA layer, and set *CTX to a new client context baton
  * allocated from POOL.  Use CONFIG_DIR and pass USERNAME, PASSWORD,
  * CONFIG_DIR and NO_AUTH_CACHE to initialize the authorization baton.
@@ -391,9 +467,16 @@ replay_revisions(svn_ra_session_t *sessi
 
   if (incremental)
     {
+#ifndef USE_EV2_IMPL
       SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
                                   0, TRUE, replay_revstart, replay_revend,
                                   replay_baton, pool));
+#else
+      SVN_ERR(svn_ra__replay_range_ev2(session, start_revision, end_revision,
+                                       0, TRUE, replay_revstart_v2,
+                                       replay_revend_v2, replay_baton,
+                                       NULL, NULL, NULL, NULL, pool));
+#endif
     }
   else
     {
@@ -432,9 +515,16 @@ replay_revisions(svn_ra_session_t *sessi
 
       /* Now go pick up additional revisions in the range, if any. */
       if (start_revision <= end_revision)
+#ifndef USE_EV2_IMPL
         SVN_ERR(svn_ra_replay_range(session, start_revision, end_revision,
                                     0, TRUE, replay_revstart, replay_revend,
                                     replay_baton, pool));
+#else
+      SVN_ERR(svn_ra__replay_range_ev2(session, start_revision, end_revision,
+                                       0, TRUE, replay_revstart_v2,
+                                       replay_revend_v2, replay_baton,
+                                       NULL, NULL, NULL, NULL, pool));
+#endif
     }
 
   SVN_ERR(svn_stream_close(stdout_stream));

Modified: subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.h
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.h?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.h (original)
+++ subversion/branches/wc-collate-path/subversion/svnrdump/svnrdump.h Tue Dec  4 15:35:13 2012
@@ -53,6 +53,17 @@ svn_rdump__get_dump_editor(const svn_del
                            void *cancel_baton,
                            apr_pool_t *pool);
 
+/* Same as above, only returns an Ev2 editor. */
+svn_error_t *
+svn_rdump__get_dump_editor_v2(svn_editor_t **editor,
+                              svn_revnum_t revision,
+                              svn_stream_t *stream,
+                              svn_ra_session_t *ra_session,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
+                              apr_pool_t *scratch_pool,
+                              apr_pool_t *result_pool);
+
 
 /**
  * Load the dumpstream carried in @a stream to the location described

Modified: subversion/branches/wc-collate-path/subversion/svnserve/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/svnserve/cyrus_auth.c?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/svnserve/cyrus_auth.c (original)
+++ subversion/branches/wc-collate-path/subversion/svnserve/cyrus_auth.c Tue Dec  4 15:35:13 2012
@@ -98,7 +98,7 @@ static int canonicalize_username(sasl_co
 
 static sasl_callback_t callbacks[] =
 {
-  { SASL_CB_CANON_USER, (void*)canonicalize_username, NULL },
+  { SASL_CB_CANON_USER, (int (*)(void))canonicalize_username, NULL },
   { SASL_CB_LIST_END, NULL, NULL }
 };
 

Modified: subversion/branches/wc-collate-path/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/svnserve/serve.c?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/svnserve/serve.c (original)
+++ subversion/branches/wc-collate-path/subversion/svnserve/serve.c Tue Dec  4 15:35:13 2012
@@ -1005,7 +1005,7 @@ get_props(apr_hash_t **props,
   /* Get any inherited properties the user is authorized to. */
   if (iprops)
     {
-      SVN_ERR(svn_repos_fs_get_inherited_props(iprops, root, path,
+      SVN_ERR(svn_repos_fs_get_inherited_props(iprops, root, path, NULL,
                                                authz_check_access_cb_func(b),
                                                b, pool, pool));
     }

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/autoprop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/autoprop_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/autoprop_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/autoprop_tests.py Tue Dec  4 15:35:13 2012
@@ -345,10 +345,12 @@ enable-auto-props = %s
   svntest.main.create_config_dir(config_dir, config_contents)
 
 #----------------------------------------------------------------------
-def check_inheritable_autoprops(sbox, auto_props_enabled):
+def check_inheritable_autoprops(sbox, auto_props_cfg_enabled,
+                                inheritable_auto_props_enabled):
   """Check that the autoprops added or imported by inheritable_autoprops_test
-     are as expected based on whether traditional auto props are active or
-     not, as indicated by AUTO_PROPS_ENABLED."""
+     are as expected based on whether auto props are active or
+     not, as indicated by AUTO_PROPS_CFG_ENABLED and
+     INHERITABLE_AUTO_PROPS_ENABLED."""
 
   foo_path = sbox.ospath('foo.c')
   bar_path = sbox.ospath('B/bar.c')
@@ -358,7 +360,7 @@ def check_inheritable_autoprops(sbox, au
   snk_path = sbox.ospath('D/H/snk.py')
   sir_path = sbox.ospath('D/H/sir.c')
 
-  if auto_props_enabled:
+  if auto_props_cfg_enabled:
     check_proplist(foo_path, {'svn:eol-style':'CRLF',
                               'svn:keywords':'Author Date Id Rev URL'})
     check_proplist(bar_path, {'svn:eol-style':'CR',
@@ -371,7 +373,8 @@ def check_inheritable_autoprops(sbox, au
     check_proplist(snk_path, {'svn:mime-type':'text/x-python'})
     check_proplist(sir_path, {'svn:eol-style':'CRLF',
                               'svn:keywords':'Author Date Id Rev URL'})
-  else:
+  elif inheritable_auto_props_enabled: # Config auto-props disabled,
+                                          # but not svn:auto-props.
     check_proplist(foo_path, {'svn:eol-style':'CRLF'})
     check_proplist(bar_path, {'svn:eol-style':'CR',
                               'svn:keywords':'Date'})
@@ -381,6 +384,14 @@ def check_inheritable_autoprops(sbox, au
     check_proplist(rip_path, {'svn:executable':'*'})
     check_proplist(snk_path, {'svn:mime-type':'text/x-python'})
     check_proplist(sir_path, {'svn:eol-style':'CRLF'})
+  else: # No autoprops of any kind.
+    check_proplist(foo_path, {})
+    check_proplist(bar_path, {})
+    check_proplist(baf_path, {})
+    check_proplist(qux_path, {})
+    check_proplist(rip_path, {})
+    check_proplist(snk_path, {})
+    check_proplist(sir_path, {})
 
 #----------------------------------------------------------------------
 def inheritable_autoprops_test(sbox, cmd, cfgenable, clienable, subdir,
@@ -421,14 +432,16 @@ def inheritable_autoprops_test(sbox, cmd
   create_inherited_autoprops_config(config_dir, cfgenable)
 
   # add comandline flags
+  inheritable_auto_props_enabled = 1
   if clienable == 1:
     parameters = parameters + ['--auto-props']
-    enable_flag = 1
+    auto_props_cfg_enabled = 1
   elif clienable == -1:
     parameters = parameters + ['--no-auto-props']
-    enable_flag = 0
+    auto_props_cfg_enabled = 0
+    inheritable_auto_props_enabled = 0
   else:
-    enable_flag = cfgenable
+    auto_props_cfg_enabled = cfgenable
 
   # setup subdirectory if needed
   if len(subdir) > 0:
@@ -503,7 +516,8 @@ def inheritable_autoprops_test(sbox, cmd
       svntest.main.run_svn(None, 'checkout', repos_url + '/A', files_wc_dir,
                           '--config-dir', config_dir)
 
-    check_inheritable_autoprops(sbox, enable_flag)
+    check_inheritable_autoprops(sbox, auto_props_cfg_enabled,
+                                inheritable_auto_props_enabled)
 
   return config_dir
 
@@ -608,8 +622,50 @@ def svn_prop_inheritable_autoprops_add_v
   svntest.main.run_svn(None, 'add', '.', '--force', '--config-dir',
                        config_dir)
   os.chdir(saved_wd)
+  check_inheritable_autoprops(sbox, True, True)
+
+  # Revert additions and try with --no-auto-props
+  svntest.main.run_svn(None, 'revert', '-R', sbox.wc_dir)
+
+  # When the add above sets svn:executable on D/rip.bat, subversion
+  # also sets the execute bits on the file (on systems that support
+  # that).  The revert above does not return the file to its original
+  # permissions, so we do so manually now.  Otherwise the follwing
+  # addition will notice the executable bits and set svn:executable
+  # again, which is not what we are here to test.
+  if os.name == 'posix':
+    os.chmod(os.path.join(sbox.wc_dir, 'D', 'rip.bat'), 0664)
+    
+  os.chdir(sbox.wc_dir)
+  svntest.main.run_svn(None, 'add', '.', '--force', '--no-auto-props',
+                       '--config-dir', config_dir)
+  os.chdir(saved_wd)
+  check_inheritable_autoprops(sbox, False, False)
+
+  # Create a new config with auto-props disabled.
+  #
+  # Then revert the previous additions and add again, only the
+  # svn:auto-props should be applied.
+  tmp_dir = os.path.abspath(svntest.main.temp_dir)
+  config_dir = os.path.join(tmp_dir,
+                            'autoprops_config_disabled_' + sbox.name)
+  create_inherited_autoprops_config(config_dir, False)
+
+  svntest.main.run_svn(None, 'revert', '-R', sbox.wc_dir)
+  os.chdir(sbox.wc_dir)
+  svntest.main.run_svn(None, 'add', '.', '--force',
+                       '--config-dir', config_dir)
+  os.chdir(saved_wd)
+  check_inheritable_autoprops(sbox, False, True)
 
-  check_inheritable_autoprops(sbox, True)
+  # Revert  a final time and add again with the --auto-props switch.
+  # Both the config defined and svn:auto-props should be applied.
+  svntest.main.run_svn(None, 'revert', '-R', sbox.wc_dir)
+  os.chdir(sbox.wc_dir)
+  svntest.main.run_svn(None, 'add', '.', '--force', '--auto-props',
+                       '--config-dir', config_dir)
+  os.chdir(saved_wd)
+  check_inheritable_autoprops(sbox, True, True)
 
 #----------------------------------------------------------------------
 # Can't set svn:auto-props on files.

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/copy_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/copy_tests.py Tue Dec  4 15:35:13 2012
@@ -4359,13 +4359,14 @@ def nonrecursive_commit_of_copy(sbox):
 # and then renaming the subdir, breaks history of the moved files.
 @Issue(3474)
 def copy_added_dir_with_copy(sbox):
-  """copy of new dir with copied file keeps history"""
+  """copy/mv of new dir with copied file keeps history"""
 
-  sbox.build()
+  sbox.build(read_only=True)
   wc_dir = sbox.wc_dir
 
   new_dir = sbox.ospath('NewDir');
   new_dir2 = sbox.ospath('NewDir2');
+  new_dir3 = sbox.ospath('NewDir3');
 
   # Alias for svntest.actions.run_and_verify_svn
   rav_svn = svntest.actions.run_and_verify_svn
@@ -4386,6 +4387,16 @@ def copy_added_dir_with_copy(sbox):
 
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+  # move of added dir also retains copy history of children
+  rav_svn(None, None, [], 'mv', new_dir, new_dir3)
+  expected_status.remove('NewDir', 'NewDir/mu')
+  expected_status.add(
+    {
+      'NewDir3'           : Item(status='A ', wc_rev='0'),
+      'NewDir3/mu'        : Item(status='A ', copied='+', wc_rev='-'),
+    })
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
 
 @SkipUnless(svntest.main.is_posix_os)
 @Issue(3303)
@@ -4670,7 +4681,7 @@ def changed_dir_data_should_match_checko
 def move_added_nodes(sbox):
   """move added nodes"""
 
-  sbox.build()
+  sbox.build(read_only=True)
 
   svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
                                      sbox.ospath('X'),
@@ -4784,7 +4795,7 @@ def mixed_rev_copy_del(sbox):
 def copy_delete_undo(sbox, use_revert):
   "copy, delete child, undo"
 
-  sbox.build()
+  sbox.build(read_only=True)
   wc_dir = sbox.wc_dir
 
   # Copy directory with children
@@ -4839,7 +4850,7 @@ def copy_delete_revert(sbox):
 def delete_replace_delete(sbox):
   "delete a directory scheduled for replacement"
 
-  sbox.build()
+  sbox.build(read_only=True)
   wc_dir = sbox.wc_dir
 
   # Delete directory with children

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/depth_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/depth_tests.py Tue Dec  4 15:35:13 2012
@@ -106,7 +106,7 @@ def verify_depth(msg, depth, path="."):
                                                              [], "info", path)
     for line in out:
       if line.startswith("Depth:"):
-        raise svntest.failure(msg)
+        raise svntest.Failure(msg)
   else:
     expected_stdout = svntest.verify.ExpectedOutput("Depth: %s\n" % depth,
                                                     match_all=False)
@@ -2905,6 +2905,28 @@ def revert_depth_files(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'revert', '--depth=files', sbox.ospath('A'))
 
+@Issue(4257)
+def spurious_nodes_row(sbox):
+  "update produces no spurious rows"
+
+  sbox.build(read_only = True)
+  return
+
+  val1 = svntest.wc.sqlite_stmt(sbox.wc_dir, "select count(*) from nodes")
+  expected_output = svntest.wc.State(sbox.wc_dir, { })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1)
+  svntest.actions.run_and_verify_update(sbox.wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None, None, None, False,
+                                        "--depth=empty", sbox.wc_dir)
+  val2 = svntest.wc.sqlite_stmt(sbox.wc_dir, "select count(*) from nodes")
+  if (val1 != val2):
+    # ra_neon added a spurious not-present row that does not show up in status
+    raise svntest.Failure("count changed from '%s' to '%s'" % (val1, val2))
+
 
 #----------------------------------------------------------------------
 # list all tests here, starting with None:
@@ -2955,6 +2977,7 @@ test_list = [ None,
               update_below_depth_empty,
               commit_then_immediates_update,
               revert_depth_files,
+              spurious_nodes_row,
               ]
 
 if __name__ == "__main__":

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/diff_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/diff_tests.py Tue Dec  4 15:35:13 2012
@@ -196,8 +196,14 @@ def make_diff_prop_added(pname, pval):
 
 def make_diff_prop_modified(pname, pval1, pval2):
   """Return a property diff for modification of property PNAME, old value
-     PVAL1, new value PVAL2.  PVAL is a single string with no embedded
-     newlines.  Return the result as a list of newline-terminated strings."""
+     PVAL1, new value PVAL2.
+
+     PVAL is a single string with no embedded newlines.  A newline at the
+     end is significant: without it, we add an extra line saying '\ No
+     newline at end of property'.
+
+     Return the result as a list of newline-terminated strings.
+  """
   return [
     "Modified: " + pname + "\n",
     "## -1 +1 ##\n",
@@ -4075,6 +4081,43 @@ def diff_properties_only(sbox):
                                      'diff', '--properties-only',
                                      '-r', 'PREV', 'iota')
 
+def diff_properties_no_newline(sbox):
+  "diff props; check no-newline-at-end messages"
+
+  sbox.build()
+  old_cwd = os.getcwd()
+  os.chdir(sbox.wc_dir)
+  sbox.wc_dir = ''
+
+  no_nl = "\\ No newline at end of property\n"
+  propchange_header = "Modified: p.*\n"
+
+  subtests = [
+    ('p1', 'val1',   'val2'  ),
+    ('p2', 'val1',   'val2\n'),
+    ('p3', 'val1\n', 'val2'  ),
+    ('p4', 'val1\n', 'val2\n'),
+  ]
+
+  # The "before" state.
+  for pname, old_val, new_val in subtests:
+    sbox.simple_propset(pname, old_val, 'iota')
+  sbox.simple_commit() # r2
+
+  # Test one change at a time. (Because, with multiple changes, the order
+  # may not be predictable.)
+  for pname, old_val, new_val in subtests:
+    expected_output = \
+      make_diff_header("iota", "revision 1", "working copy") + \
+      make_diff_prop_header("iota") + \
+      make_diff_prop_modified(pname, old_val, new_val)
+
+    sbox.simple_propset(pname, new_val, 'iota')
+    svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff')
+    svntest.actions.run_and_verify_svn(None, None, [], 'revert', 'iota')
+
+  os.chdir(old_cwd)
+
 ########################################################################
 #Run the tests
 
@@ -4146,6 +4189,7 @@ test_list = [ None,
               diff_deleted_url,
               diff_arbitrary_files_and_dirs,
               diff_properties_only,
+              diff_properties_no_newline,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/externals_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/externals_tests.py Tue Dec  4 15:35:13 2012
@@ -2131,7 +2131,7 @@ def copy_file_externals(sbox):
   actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
     expected_status, None, None, None, None, None, True, wc_dir)
 
-def include_externals(sbox):
+def commit_include_externals(sbox):
   "commit --include-externals"
   # svntest.factory.make(sbox, """
   #   mkdir Z
@@ -2878,6 +2878,122 @@ def url_to_wc_copy_of_externals(sbox):
     "OUTPUT", expected_stdout, [], 0, 'copy', repo_url + '/A/C',
     sbox.ospath('External-WC-to-URL-Copy'))
 
+@Issue(4227)
+def duplicate_targets(sbox):
+  "local path appears twice in one svn:external prop"
+
+  if False:
+    svntest.factory.make(sbox, r"""
+      svn ps svn:externals "^/A/B/E barf\n^/A/B/E barf" .
+      svn ps svn:externals "^/A/B/E barf\n^/A/D/G barf" .
+      svn ps svn:externals "^/A/B/E barf/.\n^/A/D/G ./barf" .
+      svn ps svn:externals "^/A/B/E ././barf\n^/A/D/G .//barf" .
+      svn pg svn:externals .
+      svn ps svn:externals "^/A/B/E ok" .
+      svn pg svn:externals .
+      """)
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  abs_wc_dir = os.path.abspath(sbox.wc_dir)
+
+  expected_stderr = verify.RegexOutput(
+    ".*Invalid svn:externals property on '" + re.escape(abs_wc_dir) +
+    "': target 'barf' appears more than once\n",
+    match_all=False)
+
+  # svn ps svn:externals "^/A/B/E barf\n^/A/B/E barf" .
+  actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+    'svn:externals', '^/A/B/E barf\n^/A/B/E barf', wc_dir)
+
+  # svn ps svn:externals "^/A/B/E barf\n^/A/D/G barf" .
+  actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+    'svn:externals', '^/A/B/E barf\n^/A/D/G barf', wc_dir)
+
+  # svn ps svn:externals "^/A/B/E barf/.\n^/A/D/G ./barf" .
+  actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+    'svn:externals', '^/A/B/E barf/.\n^/A/D/G ./barf', wc_dir)
+
+  # svn ps svn:externals "^/A/B/E ././barf\n^/A/D/G .//barf" .
+  actions.run_and_verify_svn2('OUTPUT', [], expected_stderr, 1, 'ps',
+    'svn:externals', '^/A/B/E ././barf\n^/A/D/G .//barf', wc_dir)
+
+  # svn pg svn:externals .
+  expected_stdout = []
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'pg',
+    'svn:externals', wc_dir)
+
+  # svn ps svn:externals "^/A/B/E ok" .
+  expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+    'svn:externals', '^/A/B/E ok', wc_dir)
+
+  # svn pg svn:externals .
+  expected_stdout = verify.UnorderedOutput([
+    '^/A/B/E ok\n',
+    '\n'
+  ])
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'pg',
+    'svn:externals', wc_dir)
+
+@Issue(4225)  
+def list_include_externals(sbox):
+  "list with --include-externals"
+  
+  externals_test_setup(sbox)
+
+  wc_dir         = sbox.wc_dir
+  repo_url       = sbox.repo_url
+  
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'checkout',
+                                     repo_url, wc_dir)
+
+  B_path = sbox.ospath("A/B")
+  C_path = sbox.ospath("A/C")
+
+  B_url = repo_url + "/A/B"
+  C_url = repo_url + "/A/C"
+
+  def list_external_string(path, url):
+    string = "Listing external" + " '" + path + "' " + "defined on" + " '" + \
+      url + "'" + ":"
+    return string
+
+  expected_stdout = verify.UnorderedOutput([
+    "E/" + "\n", 
+    "F/" + "\n",
+    "lambda" + "\n",
+    list_external_string("gamma", B_url ) + "\n",
+    "gamma" + "\n"])
+
+  exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+    "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', B_path)
+  
+  exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+    "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', B_url)
+
+  expected_stdout = verify.UnorderedOutput([
+    list_external_string("exdir_G", C_url)+ "\n",
+    "pi" + "\n",
+    "rho" + "\n",
+    "tau" + "\n",
+    list_external_string("exdir_H", C_url) + "\n",
+    "chi" + "\n",
+    "omega" + "\n",
+    "psi" + "\n"])
+  
+  exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+    "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', C_path)
+  
+  exit_code, stdout, stderr = svntest.actions.run_and_verify_svn2(
+    "OUTPUT", expected_stdout, [], 0, 'ls', '--include-externals', C_url)
+
+
+
 ########################################################################
 # Run the tests
 
@@ -2919,12 +3035,14 @@ test_list = [ None,
               file_externals_different_url,
               file_external_in_unversioned,
               copy_file_externals,
-              include_externals,
+              commit_include_externals,
               include_immediate_dir_externals,
               shadowing,
               remap_file_external_with_prop_del,
               dir_external_with_dash_r_only,
               url_to_wc_copy_of_externals,
+              duplicate_targets,
+              list_include_externals,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/getopt_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/getopt_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/getopt_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/getopt_tests.py Tue Dec  4 15:35:13 2012
@@ -167,33 +167,11 @@ def run_one_test(sbox, basename, *vararg
   actual_stdout = process_lines(actual_stdout)
   actual_stderr = process_lines(actual_stderr)
 
-  if exp_stdout != actual_stdout:
-    logger.warn("Standard output does not match.")
-    logger.warn("Expected standard output:")
-    logger.warn("=====")
-    for x in exp_stdout:
-      logger.warn(x)
-    logger.warn("=====")
-    logger.warn("Actual standard output:")
-    logger.warn("=====")
-    for x in actual_stdout:
-      logger.warn(x)
-    logger.warn("=====")
-    raise svntest.Failure
-
-  if exp_stderr != actual_stderr:
-    logger.warn("Standard error does not match.")
-    logger.warn("Expected standard error:")
-    logger.warn("=====")
-    for x in exp_stderr:
-      logger.warn(x)
-    logger.warn("=====")
-    logger.warn("Actual standard error:")
-    logger.warn("=====")
-    for x in actual_stderr:
-      logger.warn(x)
-    logger.warn("=====")
-    raise svntest.Failure
+  svntest.verify.compare_and_display_lines("Standard output does not match.",
+                                           "STDOUT", exp_stdout, actual_stdout)
+
+  svntest.verify.compare_and_display_lines("Standard error does not match.",
+                                           "STDERR", exp_stderr, actual_stderr)
 
 def getopt_no_args(sbox):
   "run svn with no arguments"

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/import_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/import_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/import_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/import_tests.py Tue Dec  4 15:35:13 2012
@@ -458,7 +458,7 @@ def import_inherited_ignores(sbox):
   file2_path = os.path.join('DIR3.foo', 'file2.txt')
   dir4_path  = os.path.join('DIR4.goo')
   file3_path = os.path.join('DIR4.goo', 'file3.txt')
-  file4_path = os.path.join('DIR4.goo', 'file4.txt')
+  file4_path = os.path.join('DIR4.goo', 'file4.noo')
   dir5_path  = os.path.join('DIR5.moo')
   file5_path = os.path.join('DIR5.moo', 'file5.txt')
   dir6_path  = os.path.join('DIR6')
@@ -468,7 +468,7 @@ def import_inherited_ignores(sbox):
   dir8_path  = os.path.join('DIR6', 'DIR7', 'DIR8.noo')
 
   # Import the tree to ^/A/B/E.
-  # We should never see any *.noo paths because those are blocked at the
+  # We should not see any *.noo paths because those are blocked at the
   # root of the repository by the svn:global-ignores property.  Likewise
   # *.doo paths are blocked by the svn:global-ignores on ^/A/B.  Nor
   # should we see and *.boo or *.goo paths, as those are blocked by the
@@ -517,8 +517,8 @@ def import_inherited_ignores(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'up', wc_dir)
 
   # Import the tree to ^/A/B/F with the --no-ignore option.
-  # Now only the ignores present in the svn:global-ignores property
-  # should be considered.
+  # No ignores should be considered and the whole tree should
+  # be imported.
   svntest.actions.run_and_verify_svn(None, None, [], 'import',
                                      '--config-dir', config_dir,
                                      '--no-ignore', import_tree_dir,
@@ -527,16 +527,21 @@ def import_inherited_ignores(sbox):
   F_path = os.path.join(wc_dir, 'A', 'B', 'F')
   expected_output = svntest.verify.UnorderedOutput(
     ["Updating '" + wc_dir + "':\n",
+     'A    ' + os.path.join(F_path, dir1_path)  + '\n',
+     'A    ' + os.path.join(F_path, dir2_path)  + '\n',
+     'A    ' + os.path.join(F_path, file1_path) + '\n',
      'A    ' + os.path.join(F_path, dir3_path)  + '\n',
      'A    ' + os.path.join(F_path, file2_path) + '\n',
      'A    ' + os.path.join(F_path, dir4_path)  + '\n',
      'A    ' + os.path.join(F_path, file3_path) + '\n',
+     'A    ' + os.path.join(F_path, file4_path) + '\n',
      'A    ' + os.path.join(F_path, dir5_path)  + '\n',
      'A    ' + os.path.join(F_path, file5_path) + '\n',
      'A    ' + os.path.join(F_path, dir6_path)  + '\n',
      'A    ' + os.path.join(F_path, file6_path) + '\n',
      'A    ' + os.path.join(F_path, dir7_path)  + '\n',
      'A    ' + os.path.join(F_path, file7_path) + '\n',
+     'A    ' + os.path.join(F_path, dir8_path)  + '\n',
      'Updated to revision 5.\n'])
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'up', wc_dir)
 

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/info_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/info_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/info_tests.py Tue Dec  4 15:35:13 2012
@@ -221,6 +221,7 @@ def info_on_added_file(sbox):
   expected = {'Path' : re.escape(new_file),
               'Name' : 'new_file',
               'URL' : '.*/new_file',
+              'Relative URL' : '.*/new_file',
               'Repository Root' : '.*',
               'Node Kind' : 'file',
               'Schedule' : 'add',
@@ -240,6 +241,7 @@ def info_on_added_file(sbox):
                                      'path'     : new_file,
                                      'revision' : 'Resource is not under version control.'}),
                        ('url',      {}, '.*/new_file'),
+                       ('relative-url', {}, '.*/new_file'),
                        ('root',     {}, '.*'),
                        ('uuid',     {}, uuid_regex),
                        ('depth',    {}, 'infinity'),
@@ -259,6 +261,7 @@ def info_on_mkdir(sbox):
   # check that we have a Repository Root and Repository UUID
   expected = {'Path' : re.escape(new_dir),
               'URL' : '.*/new_dir',
+              'Relative URL' : '.*/new_dir',
               'Repository Root' : '.*',
               'Node Kind' : 'directory',
               'Schedule' : 'add',
@@ -277,6 +280,7 @@ def info_on_mkdir(sbox):
                                      'path'     : new_dir,
                                      'revision' : 'Resource is not under version control.'}),
                        ('url',      {}, '.*/new_dir'),
+                       ('relative-url', {}, '.*/new_dir'),
                        ('root',     {}, '.*'),
                        ('uuid',     {}, uuid_regex),
                        ('depth',    {}, 'infinity'),
@@ -396,6 +400,7 @@ def info_repos_root_url(sbox):
         'Path'              : re.escape(os.path.basename(sbox.repo_dir)),
         'Repository Root'   : re.escape(sbox.repo_url),
         'URL'               : re.escape(sbox.repo_url),
+        'Relative URL'      : '\^/', # escape ^ -- this isn't a regexp
         'Revision'          : '1',
         'Node Kind'         : 'directory',
         'Last Changed Rev'  : '1',
@@ -405,6 +410,7 @@ def info_repos_root_url(sbox):
         'Name'              : 'iota',
         'Repository Root'   : re.escape(sbox.repo_url),
         'URL'               : re.escape(sbox.repo_url + '/iota'),
+        'Relative URL'      : '\^/iota', # escape ^ -- this isn't a regexp
         'Revision'          : '1',
         'Node Kind'         : 'file',
         'Last Changed Rev'  : '1',

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/iprop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/iprop_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/iprop_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/iprop_tests.py Tue Dec  4 15:35:13 2012
@@ -1635,6 +1635,40 @@ def iprops_with_file_externals(sbox):
     sbox.ospath('A/B/E/file-external'), expected_iprops,
     expected_explicit_props)
 
+def iprops_survive_commit(sbox):
+  "verify that iprops survive a commit"
+
+  sbox.build()
+  sbox.simple_propset('key', 'D', 'A/B',)
+  sbox.simple_commit()
+
+  svntest.main.run_svn(None, 'switch', sbox.repo_url + '/A/B/E',
+                       sbox.ospath('A/D'), '--ignore-ancestry')
+  svntest.main.run_svn(None, 'switch', sbox.repo_url + '/A/B/F',
+                       sbox.ospath('iota'), '--ignore-ancestry')
+  expected_iprops = {
+    sbox.repo_url + '/A/B' : {'key'   : 'D'},
+  }
+
+  expected_explicit_props = {}
+  svntest.actions.run_and_verify_inherited_prop_xml(sbox.ospath('A/D'),
+                                                    expected_iprops,
+                                                    expected_explicit_props)
+  svntest.actions.run_and_verify_inherited_prop_xml(sbox.ospath('iota'),
+                                                    expected_iprops,
+                                                    expected_explicit_props)
+
+  sbox.simple_propset('new', 'V', 'A/D', 'iota')
+  sbox.simple_commit()
+
+  expected_explicit_props = {'new': 'V'}
+  svntest.actions.run_and_verify_inherited_prop_xml(sbox.ospath('A/D'),
+                                                    expected_iprops,
+                                                    expected_explicit_props)
+  svntest.actions.run_and_verify_inherited_prop_xml(sbox.ospath('iota'),
+                                                    expected_iprops,
+                                                    expected_explicit_props)
+
 ########################################################################
 # Run the tests
 
@@ -1648,6 +1682,7 @@ test_list = [ None,
               iprops_shallow_operative_depths,
               iprops_with_directory_externals,
               iprops_with_file_externals,
+              iprops_survive_commit,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_automatic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_automatic_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_automatic_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_automatic_tests.py Tue Dec  4 15:35:13 2012
@@ -83,6 +83,8 @@ from merge_tests import set_up_branch
 #     B (--o--x--o-----?--x
 #
 #   Merge with cherry-picks
+#   (This set of six cases represents all of the topologically distinct
+#   scenarios involving one cherry-pick between two automatic merges.)
 #
 #     Cherry1, fwd
 #     A (--o-----o-[o]----o---
@@ -701,6 +703,7 @@ def cherry1_fwd(sbox):
 
 @SkipUnless(server_has_mergeinfo)
 @XFail()
+@Issue(4255)
 def cherry2_fwd(sbox):
   """cherry2_fwd"""
 
@@ -721,6 +724,7 @@ def cherry2_fwd(sbox):
 
 @SkipUnless(server_has_mergeinfo)
 @XFail()
+@Issue(4255)
 def cherry3_fwd(sbox):
   """cherry3_fwd"""
 
@@ -728,7 +732,7 @@ def cherry3_fwd(sbox):
   #     (          \     /     \
   #     (           \   /       \
   #   B (---o--o-[o]-x-/---------x
-  #               \__/
+  #                \__/
   #     2  34  5  6  7    8  9   0
 
   make_branches(sbox)
@@ -754,6 +758,7 @@ def cherry3_fwd(sbox):
 # Automatic merges ignore subtree mergeinfo during reintegrate.
 @SkipUnless(server_has_mergeinfo)
 @XFail()
+@Issue(4258)
 def subtree_to_and_fro(sbox):
   "reintegrate considers source subtree mergeinfo"
 

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/merge_tests.py Tue Dec  4 15:35:13 2012
@@ -526,6 +526,13 @@ def add_with_history(sbox):
 
   expected_skip = wc.State(C_path, { })
 
+  # Add some unversioned directory obstructions to the incoming
+  # additions.  This should be tolerated and *not* result in any
+  # difference between the --dry-run and actual merge.
+  # See http://svn.haxx.se/dev/archive-2012-11/0696.shtml
+  os.mkdir(sbox.ospath('A/C/Q'))
+  os.mkdir(sbox.ospath('A/C/Q2'))
+
   svntest.actions.run_and_verify_merge(C_path, '1', '2', F_url, None,
                                        expected_output,
                                        expected_mergeinfo_output,

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/patch_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/patch_tests.py Tue Dec  4 15:35:13 2012
@@ -4201,6 +4201,40 @@ def patch_git_with_index_line(sbox):
                                        1, # check-props
                                        1) # dry-run
 
+@XFail()
+def patch_change_symlink_target(sbox):
+  "patch changes symlink target"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  patch_file_path = make_patch_path(sbox)
+  svntest.main.file_write(patch_file_path, '\n'.join([
+    "Index: link",
+    "===================================================================",
+    "--- iota        (revision 1)",
+    "+++ iota        (working copy)",
+    "@@ -1 +1 @@",
+    "-link foo",
+    "\\ No newline at end of file",
+    "+link bar",
+    "\\ No newline at end of file",
+    "",
+    ]))
+  
+  # r2
+  sbox.simple_add_symlink('target', 'link')
+  sbox.simple_commit()
+
+  expected_output = [
+    'M         %s\n' % sbox.ospath('link'),
+  ]
+
+  # This currently fails.
+  # TODO: when it passes, verify that the on-disk 'link' is correct ---
+  #       symlink to 'bar' (or "link bar" on non-HAVE_SYMLINK platforms)
+  svntest.actions.run_and_verify_svn(None, "U *link", [],
+                                     'patch', patch_file_path, wc_dir)
+
 ########################################################################
 #Run the tests
 
@@ -4246,6 +4280,7 @@ test_list = [ None,
               patch_target_no_eol_at_eof,
               patch_add_and_delete,
               patch_git_with_index_line,
+              patch_change_symlink_target,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/prop_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/prop_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/prop_tests.py Tue Dec  4 15:35:13 2012
@@ -900,9 +900,9 @@ def prop_value_conversions(sbox):
                              "svn: warning: W125005.*use 'svn propdel'")
 
   # Anything else should be untouched
-  svntest.actions.set_prop('svn:some-prop', 'bar', lambda_path)
-  svntest.actions.set_prop('svn:some-prop', ' bar baz', mu_path)
-  svntest.actions.set_prop('svn:some-prop', 'bar\n', iota_path)
+  svntest.actions.set_prop('svn:some-prop', 'bar', lambda_path, force=True)
+  svntest.actions.set_prop('svn:some-prop', ' bar baz', mu_path, force=True)
+  svntest.actions.set_prop('svn:some-prop', 'bar\n', iota_path, force=True)
   svntest.actions.set_prop('some-prop', 'bar', lambda_path)
   svntest.actions.set_prop('some-prop', ' bar baz', mu_path)
   svntest.actions.set_prop('some-prop', 'bar\n', iota_path)
@@ -2670,6 +2670,37 @@ def inheritable_ignores(sbox):
                                      [], 'add', '.', '--force','--no-ignore',
                                      '--config-dir', config_dir)
 
+def almost_known_prop_names(sbox):
+  "propset with svn: prefix but unknown name"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  iota_path = sbox.ospath('iota')
+
+  # Same prefix, different prop name
+  svntest.actions.set_prop('svn:exemutable', 'x', iota_path,
+                           "svn: E195011: 'svn:exemutable' "
+                           "is not a valid svn: property name")
+  svntest.actions.set_prop('svn:exemutable', 'x', iota_path, force=True)
+
+  # Similar prefix, different prop name
+  svntest.actions.set_prop('svm:exemutable', 'x', iota_path)
+
+  # Similar prefix, same prop name
+  svntest.actions.set_prop('svm:executable', 'x', iota_path,
+                           "svn: E195011: 'svm:executable' "
+                           "is not a valid svn: property name")
+  svntest.actions.set_prop('svm:executable', 'x', iota_path, force=True)
+
+  # Different prefix, same prop name
+  svntest.actions.set_prop('tsvn:executable', 'x', iota_path)
+
+  # Property name is too different to matter
+  svntest.actions.set_prop('svn:foobar', 'x', iota_path,
+                           "svn: E195011: 'svn:foobar'"
+                           " is not a valid svn: property name;"
+                           " re-run with '--force' to set it")
+
 ########################################################################
 # Run the tests
 
@@ -2713,6 +2744,7 @@ test_list = [ None,
               file_matching_dir_prop_reject,
               pristine_props_listed,
               inheritable_ignores,
+              almost_known_prop_names,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/special_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/special_tests.py Tue Dec  4 15:35:13 2012
@@ -25,7 +25,7 @@
 ######################################################################
 
 # General modules
-import sys, os, re
+import sys, os, re, copy
 
 # Our testing module
 import svntest
@@ -49,7 +49,6 @@ Item = svntest.wc.StateItem
 
 
 #----------------------------------------------------------------------
-@SkipUnless(svntest.main.is_posix_os)
 def general_symlink(sbox):
   "general symlink handling"
 
@@ -57,11 +56,11 @@ def general_symlink(sbox):
   wc_dir = sbox.wc_dir
 
   # First try to just commit a symlink
-  newfile_path = os.path.join(wc_dir, 'newfile')
-  linktarget_path = os.path.join(wc_dir, 'linktarget')
-  svntest.main.file_append(linktarget_path, 'this is just a link target')
-  os.symlink('linktarget', newfile_path)
-  svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
+  newfile_path = sbox.ospath('newfile')
+
+  sbox.simple_append('linktarget', 'this is just a link target')
+  sbox.simple_add('linktarget')
+  sbox.simple_add_symlink('linktarget', 'newfile')
 
   expected_output = svntest.wc.State(wc_dir, {
     'newfile' : Item(verb='Adding'),
@@ -104,14 +103,18 @@ def general_symlink(sbox):
                                      'up', '-r', '2', wc_dir)
 
   # Is the symlink back?
-  new_target = os.readlink(newfile_path)
-  if new_target != 'linktarget':
-    raise svntest.Failure
+  if svntest.main.is_posix_os():
+    new_target = os.readlink(newfile_path)
+    if new_target != 'linktarget':
+      raise svntest.Failure
 
   ## Now change the target of the symlink, verify that it is shown as
   ## modified and that a commit succeeds.
   os.remove(newfile_path)
-  os.symlink('A', newfile_path)
+  if svntest.main.is_posix_os():
+    os.symlink('A', newfile_path)
+  else:
+    sbox.simple_append('newfile', 'link A', truncate = True)
 
   was_cwd = os.getcwd()
   os.chdir(wc_dir)
@@ -223,7 +226,6 @@ def import_export_symlink(sbox):
 #----------------------------------------------------------------------
 # Regression test for issue 1986
 @Issue(1986)
-@SkipUnless(svntest.main.is_posix_os)
 def copy_tree_with_symlink(sbox):
   "'svn cp dir1 dir2' which contains a symlink"
 
@@ -231,11 +233,10 @@ def copy_tree_with_symlink(sbox):
   wc_dir = sbox.wc_dir
 
   # Create a versioned symlink within directory 'A/D/H'.
-  newfile_path = os.path.join(wc_dir, 'A', 'D', 'H', 'newfile')
-  linktarget_path = os.path.join(wc_dir, 'A', 'D', 'H', 'linktarget')
-  svntest.main.file_append(linktarget_path, 'this is just a link target')
-  os.symlink('linktarget', newfile_path)
-  svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
+  newfile_path = sbox.ospath('A/D/H/newfile')
+  sbox.simple_append('A/D/H/linktarget', 'this is just a link target')
+  sbox.simple_add('A/D/H/linktarget')
+  sbox.simple_add_symlink('linktarget', 'A/D/H/newfile')
 
   expected_output = svntest.wc.State(wc_dir, {
     'A/D/H/newfile' : Item(verb='Adding'),
@@ -323,7 +324,7 @@ def replace_symlink_with_file(sbox):
     raise svntest.Failure
 
 
-@SkipUnless(svntest.main.is_posix_os)
+#----------------------------------------------------------------------
 def remove_symlink(sbox):
   "remove a symlink"
 
@@ -334,8 +335,8 @@ def remove_symlink(sbox):
   newfile_path = os.path.join(wc_dir, 'newfile')
   linktarget_path = os.path.join(wc_dir, 'linktarget')
   svntest.main.file_append(linktarget_path, 'this is just a link target')
-  os.symlink('linktarget', newfile_path)
-  svntest.main.run_svn(None, 'add', newfile_path, linktarget_path)
+  sbox.simple_add_symlink('linktarget', 'newfile')
+  sbox.simple_add('linktarget')
 
   expected_output = svntest.wc.State(wc_dir, {
     'newfile' : Item(verb='Adding'),
@@ -367,7 +368,7 @@ def remove_symlink(sbox):
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         expected_status, None, wc_dir)
 
-@SkipUnless(svntest.main.is_posix_os)
+#----------------------------------------------------------------------
 @SkipUnless(server_has_mergeinfo)
 @Issue(2530)
 def merge_symlink_into_file(sbox):
@@ -378,8 +379,8 @@ def merge_symlink_into_file(sbox):
   d_url = sbox.repo_url + '/A/D'
   dprime_url = sbox.repo_url + '/A/Dprime'
 
-  gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma')
-  gamma_prime_path = os.path.join(wc_dir, 'A', 'Dprime', 'gamma')
+  gamma_path = sbox.ospath('A/D/gamma')
+  gamma_prime_path = sbox.ospath('A/Dprime/gamma')
 
   # create a copy of the D directory to play with
   svntest.main.run_svn(None,
@@ -400,8 +401,7 @@ def merge_symlink_into_file(sbox):
   # Commit a symlink in its place
   linktarget_path = os.path.join(wc_dir, 'linktarget')
   svntest.main.file_append(linktarget_path, 'this is just a link target')
-  os.symlink('linktarget', gamma_prime_path)
-  svntest.main.run_svn(None, 'add', gamma_prime_path)
+  sbox.simple_add_symlink('linktarget', 'A/Dprime/gamma')
 
   expected_output = svntest.wc.State(wc_dir, {
     'A/Dprime/gamma' : Item(verb='Adding'),
@@ -435,7 +435,7 @@ def merge_symlink_into_file(sbox):
 
 
 
-@SkipUnless(svntest.main.is_posix_os)
+#----------------------------------------------------------------------
 def merge_file_into_symlink(sbox):
   "merge file into symlink"
 
@@ -466,8 +466,7 @@ def merge_file_into_symlink(sbox):
   # Commit a symlink in its place
   linktarget_path = os.path.join(wc_dir, 'linktarget')
   svntest.main.file_append(linktarget_path, 'this is just a link target')
-  os.symlink('linktarget', gamma_prime_path)
-  svntest.main.run_svn(None, 'add', gamma_prime_path)
+  sbox.simple_add_symlink('linktarget', 'A/Dprime/gamma')
 
   expected_output = svntest.wc.State(wc_dir, {
     'A/Dprime/gamma' : Item(verb='Adding'),
@@ -520,22 +519,19 @@ def checkout_repo_with_symlinks(sbox):
                                           expected_output,
                                           expected_wc)
 
+#----------------------------------------------------------------------
 # Issue 2716: 'svn diff' against a symlink to a directory within the wc
 @Issue(2716)
-@SkipUnless(svntest.main.is_posix_os)
 def diff_symlink_to_dir(sbox):
   "diff a symlink to a directory"
 
   sbox.build(read_only = True)
-  os.chdir(sbox.wc_dir)
 
-  # Create a symlink to A/D/.
+  # Create a symlink to A/D as link.
   d_path = os.path.join('A', 'D')
-  link_path = 'link'
-  os.symlink(d_path, link_path)
+  sbox.simple_add_symlink('A/D', 'link')
 
-  # Add the symlink.
-  svntest.main.run_svn(None, 'add', link_path)
+  os.chdir(sbox.wc_dir)
 
   # Now diff the wc itself and check the results.
   expected_output = [
@@ -544,7 +540,7 @@ def diff_symlink_to_dir(sbox):
     "--- link\t(revision 0)\n",
     "+++ link\t(working copy)\n",
     "@@ -0,0 +1 @@\n",
-    "+link " + d_path + "\n",
+    "+link A/D\n",
     "\ No newline at end of file\n",
     "\n",
     "Property changes on: link\n",
@@ -557,9 +553,9 @@ def diff_symlink_to_dir(sbox):
   svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
                                      '.')
   # We should get the same output if we the diff the symlink itself.
-  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
-                                     link_path)
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', 'link')
 
+#----------------------------------------------------------------------
 # Issue 2692 (part of): Check that the client can check out a repository
 # that contains an unknown special file type.
 @Issue(2692)
@@ -710,9 +706,8 @@ def unrelated_changed_special_status(sbo
                                      '--changelist', 'chi cl',
                                      '-m', 'psi changed special status')
 
-
+#----------------------------------------------------------------------
 @Issue(3972)
-@SkipUnless(svntest.main.is_posix_os)
 def symlink_destination_change(sbox):
   "revert a symlink destination change"
 
@@ -721,8 +716,7 @@ def symlink_destination_change(sbox):
 
   # Create a new symlink and commit it.
   newfile_path = os.path.join(wc_dir, 'newfile')
-  os.symlink('linktarget', newfile_path)
-  svntest.main.run_svn(None, 'add', newfile_path)
+  sbox.simple_add_symlink('linktarget', 'newfile')
 
   expected_output = svntest.wc.State(wc_dir, {
     'newfile' : Item(verb='Adding'),
@@ -738,7 +732,10 @@ def symlink_destination_change(sbox):
 
   # Modify the symlink to point somewhere else
   os.remove(newfile_path)
-  os.symlink('linktarget2', newfile_path)
+  if svntest.main.is_posix_os():
+    os.symlink('linktarget2', newfile_path)
+  else:
+    sbox.simple_append('newfile', 'link linktarget2', truncate = True)
 
   expected_status.tweak('newfile', status='M ')
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
@@ -758,7 +755,6 @@ def symlink_destination_change(sbox):
 # This used to lose the special status in the target working copy
 # (disk and metadata).
 @Issue(3884)
-@SkipUnless(svntest.main.is_posix_os)
 def merge_foreign_symlink(sbox):
   "merge symlink-add from foreign repos"
 
@@ -777,8 +773,7 @@ def merge_foreign_symlink(sbox):
   zeta2_path = sbox2.ospath('A/zeta')
 
   # sbox2 r2: create zeta2 in sbox2
-  os.symlink('target', zeta2_path)
-  sbox2.simple_add('A/zeta')
+  sbox2.simple_add_symlink('target', 'A/zeta')
   sbox2.simple_commit('A/zeta')
 
 
@@ -859,8 +854,8 @@ def symlink_to_wc_svnversion(sbox):
                                             symlink_path, sbox.repo_url,
                                             [ "1\n" ], [])
 
+#----------------------------------------------------------------------
 # Regression in 1.7.0: Update fails to change a symlink
-@SkipUnless(svntest.main.is_posix_os)
 def update_symlink(sbox):
   "update a symlink"
 
@@ -873,13 +868,15 @@ def update_symlink(sbox):
   symlink_path = sbox.ospath('symlink')
 
   # create a symlink to /A/mu
-  os.symlink("A/mu", symlink_path)
-  sbox.simple_add('symlink')
+  sbox.simple_add_symlink("A/mu", 'symlink')
   sbox.simple_commit()
 
   # change the symlink to /iota
   os.remove(symlink_path)
-  os.symlink("iota", symlink_path)
+  if svntest.main.is_posix_os():
+    os.symlink("iota", symlink_path)
+  else:
+    file_write(symlink_path, 'link iota')
   sbox.simple_commit()
 
   # update back to r2
@@ -896,6 +893,10 @@ def update_symlink(sbox):
   expected_status.add({
     'symlink'           : Item(status='  ', wc_rev='3'),
   })
+
+  if not svntest.main.is_posix_os():
+    expected_disk = None
+
   svntest.actions.run_and_verify_update(wc_dir,
                                         expected_output,
                                         expected_disk,
@@ -903,9 +904,8 @@ def update_symlink(sbox):
                                         None, None, None,
                                         None, None, 1)
 
-@XFail()
+#----------------------------------------------------------------------
 @Issue(4091)
-@SkipUnless(svntest.main.is_posix_os)
 def replace_symlinks(sbox):
   "replace symlinks"
   sbox.build()
@@ -922,10 +922,8 @@ def replace_symlinks(sbox):
   sbox.simple_mkdir('A/D/Y')
   sbox.simple_mkdir('Ax')
 
-  os.symlink('../Y', wc('A/D/H/Z'))
-  os.symlink('../Y', wc('A/D/Hx/Z'))
-  sbox.simple_add('A/D/H/Z',
-                  'A/D/Hx/Z')
+  sbox.simple_add_symlink('../Y', 'A/D/H/Z')
+  sbox.simple_add_symlink('../Y', 'A/D/Hx/Z')
 
   for p in ['Ax/mu',
             'A/D/Gx/pi',
@@ -946,6 +944,8 @@ def replace_symlinks(sbox):
       file_write(wc(p), '#!/bin/sh\necho "hello, svn!"\n')
       os.chmod(wc(p), 0775)
       sbox.simple_add(p)
+      if not svntest.main.is_posix_os():
+        sbox.simple_propset('svn:executable', 'X', p)
   sbox.simple_commit() # r2
   sbox.simple_update()
   expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 2)
@@ -971,19 +971,17 @@ def replace_symlinks(sbox):
     'A/mu.sh'       : Item(status='  ', wc_rev=2),
     'iota.sh'       : Item(status='  ', wc_rev=2),
     })
-  expected_status_r2 = expected_status
+  expected_status_r2 = copy.deepcopy(expected_status)
   svntest.actions.run_and_verify_status(sbox.wc_dir, expected_status_r2)
 
   # Failing git-svn test: 'new symlink is added to a file that was
   # also just made executable', i.e., in the same revision.
-  sbox.simple_propset("svn:executable", "*", 'A/B/E/alpha')
-  os.symlink('alpha', wc('A/B/E/sym-alpha'))
-  sbox.simple_add('A/B/E/sym-alpha')
+  sbox.simple_propset("svn:executable", "X", 'A/B/E/alpha')
+  sbox.simple_add_symlink('alpha', 'A/B/E/sym-alpha')
 
   # Add a symlink to a file made non-executable in the same revision.
   sbox.simple_propdel("svn:executable", 'A/B/E/beta.sh')
-  os.symlink('beta.sh', wc('A/B/E/sym-beta.sh'))
-  sbox.simple_add('A/B/E/sym-beta.sh')
+  sbox.simple_add_symlink('beta.sh', 'A/B/E/sym-beta.sh')
 
   # Replace a normal {file, exec, dir} with a symlink to the same kind
   # via Subversion replacement.
@@ -991,13 +989,9 @@ def replace_symlinks(sbox):
                  'A/D/G/rho.sh',
                  #'A/D/G/Z', # Ooops, not compatible with --bin=svn1.6.
                  )
-  os.symlink(wc('../gamma'), wc('A/D/G/pi'))
-  os.symlink(wc('../gamma.sh'), wc('A/D/G/rho.sh'))
-  #os.symlink(wc('../Y'), wc('A/D/G/Z'))
-  sbox.simple_add('A/D/G/pi',
-                  'A/D/G/rho.sh',
-                  #'A/D/G/Z',
-                  )
+  sbox.simple_add_symlink('../gamma', 'A/D/G/pi')
+  sbox.simple_add_symlink('../gamma.sh', 'A/D/G/rho.sh')
+  #sbox.simple_add_symlink('../Y', 'A/D/G/Z')
 
   # Replace a symlink to {file, exec, dir} with a normal item of the
   # same kind via Subversion replacement.
@@ -1005,30 +999,34 @@ def replace_symlinks(sbox):
                  'A/D/H/psi.sh',
                  #'A/D/H/Z',
                  )
-  os.symlink(wc('../gamma'), wc('A/D/H/chi'))
-  os.symlink(wc('../gamma.sh'), wc('A/D/H/psi.sh'))
-  #os.symlink(wc('../Y'), wc('A/D/H/Z'))
-  sbox.simple_add('A/D/H/chi',
-                  'A/D/H/psi.sh',
-                  #'A/D/H/Z',
-                  )
+  sbox.simple_add_symlink('../gamma', 'A/D/H/chi')
+  sbox.simple_add_symlink('../gamma.sh', 'A/D/H/psi.sh')
+  #sbox.simple_add_symlink('../Y', 'A/D/H/Z')
 
   # Replace a normal {file, exec} with a symlink to {exec, file} via
   # Subversion replacement.
   sbox.simple_rm('A/mu',
                  'A/mu.sh')
-  os.symlink('../iota2', wc('A/mu'))
-  os.symlink('../iota', wc('A/mu.sh'))
-  sbox.simple_add('A/mu',
-                  'A/mu.sh')
+  sbox.simple_add_symlink('../iota2', 'A/mu')
+  sbox.simple_add_symlink('../iota', 'A/mu.sh')
 
   # Ditto, without the Subversion replacement.  Failing git-svn test
   # 'executable file becomes a symlink to bar/zzz (file)'.
-  os.remove(wc('Ax/mu'))
-  os.remove(wc('Ax/mu.sh'))
-  os.symlink('../iota2', wc('Ax/mu'))
-  os.symlink('../iota', wc('Ax/mu.sh'))
-  sbox.simple_propset('svn:special', '*',
+  if svntest.main.is_posix_os():
+    os.remove(wc('Ax/mu'))
+    os.remove(wc('Ax/mu.sh'))
+    os.symlink('../iota2', wc('Ax/mu'))
+    os.symlink('../iota', wc('Ax/mu.sh'))
+  else:
+    # At least modify the file a bit
+
+    # ### Somehow this breaks the test when using multiline data?
+    # ### Is that intended behavior?
+
+    file_write(sbox.ospath('Ax/mu'), 'Link to iota2')
+    file_write(sbox.ospath('Ax/mu.sh'), 'Link to iota')
+
+  sbox.simple_propset('svn:special', 'X',
                       'Ax/mu',
                       'Ax/mu.sh')
   sbox.simple_propdel('svn:executable', 'Ax/mu.sh')
@@ -1100,20 +1098,128 @@ def externals_as_symlink_targets(sbox):
 
   sbox.simple_commit()
 
+#----------------------------------------------------------------------
 @XFail()
 @Issue(4119)
-@SkipUnless(svntest.main.is_posix_os)
 def cat_added_symlink(sbox):
   "cat added symlink"
 
   sbox.build(read_only = True)
 
   kappa_path = sbox.ospath('kappa')
-  os.symlink('iota', kappa_path)
-  sbox.simple_add('kappa')
+  sbox.simple_add_symlink('iota', 'kappa')
   svntest.actions.run_and_verify_svn(None, "link iota", [],
                                      "cat", kappa_path)
 
+#----------------------------------------------------------------------
+def incoming_symlink_changes(sbox):
+  "verify incoming symlink change behavior"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_add_symlink('iota', 's-replace')
+  sbox.simple_add_symlink('iota', 's-in-place')
+  sbox.simple_add_symlink('iota', 's-type')
+  sbox.simple_append('s-reverse', 'link iota')
+  sbox.simple_add('s-reverse')
+  sbox.simple_commit() # r2
+
+  # Replace s-replace
+  sbox.simple_rm('s-replace')
+  # Note that we don't use 'A/mu' as the length of that matches 'iota', which
+  # would make us depend on timestamp changes for detecting differences.
+  sbox.simple_add_symlink('A/D/G/pi', 's-replace')
+
+  # Change target of s-in-place
+  if svntest.main.is_posix_os():
+    os.remove(sbox.ospath('s-in-place'))
+    os.symlink('A/D/G/pi', sbox.ospath('s-in-place'))
+  else:
+    sbox.simple_append('s-in-place', 'link A/D/G/pi', truncate = True)
+
+  # r3
+  expected_output = svntest.wc.State(wc_dir, {
+    's-replace'         : Item(verb='Replacing'),
+    's-in-place'        : Item(verb='Sending'),
+  })
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output, None, None,
+                                        wc_dir)
+
+  # r4
+  svntest.main.run_svnmucc('propdel', 'svn:special',
+                           sbox.repo_url + '/s-type',
+                           '-m', 'Turn s-type into a file')
+
+  # r5
+  svntest.main.run_svnmucc('propset', 'svn:special', 'X',
+                           sbox.repo_url + '/s-reverse',
+                           '-m', 'Turn s-reverse into a symlink')
+
+  # Currently we expect to see 'U'pdates, but we would like to see
+  # replacements
+  expected_output = svntest.wc.State(wc_dir, {
+    's-reverse'         : Item(status=' U'),
+    's-type'            : Item(status=' U'),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 5)
+  expected_status.add({
+    's-type'            : Item(status='  ', wc_rev='5'),
+    's-replace'         : Item(status='  ', wc_rev='5'),
+    's-reverse'         : Item(status='  ', wc_rev='5'),
+    's-in-place'        : Item(status='  ', wc_rev='5'),
+  })
+
+  # Update to HEAD/r5 to fetch the r4 and r5 symlink changes
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        check_props=True)
+
+  # Update back to r2, to prepare some local changes
+  expected_output = svntest.wc.State(wc_dir, {
+    # s-replace is D + A
+    's-replace'         : Item(status='A '),
+    's-in-place'        : Item(status='U '),
+    's-reverse'         : Item(status=' U'),
+    's-type'            : Item(status=' U'),
+  })
+  expected_status.tweak(wc_rev=2)
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        True,
+                                        wc_dir, '-r', '2')
+
+  # Ok, now add a property on all of them to make future symlinkness changes
+  # a tree conflict
+  # ### We should also try this with a 'textual change'
+  sbox.simple_propset('x', 'y', 's-replace', 's-in-place', 's-reverse', 's-type')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    's-replace'         : Item(status='  ', treeconflict='A'),
+    's-in-place'        : Item(status='U '),
+    's-reverse'         : Item(status='  ', treeconflict='C'),
+    's-type'            : Item(status='  ', treeconflict='C'),
+  })
+  expected_status.tweak(wc_rev=5)
+  expected_status.tweak('s-replace', 's-reverse', 's-type', status='RM',
+                        copied='+', treeconflict='C', wc_rev='-')
+  expected_status.tweak('s-in-place', status=' M')
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        None,
+                                        expected_status,
+                                        None, None, None, None, None,
+                                        True)
+
 ########################################################################
 # Run the tests
 
@@ -1144,6 +1250,7 @@ test_list = [ None,
               replace_symlinks,
               externals_as_symlink_targets,
               cat_added_symlink,
+              incoming_symlink_changes,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/stat_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/stat_tests.py Tue Dec  4 15:35:13 2012
@@ -1441,8 +1441,8 @@ def status_depth_local(sbox):
 
   # make some changes to the greek tree
   change_files(wc_dir, ['A/mu', 'A/D/gamma'])
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', A_path)
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', D_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', A_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', D_path)
 
   # for all the possible types of depth, check the status
 
@@ -1501,8 +1501,8 @@ def status_depth_update(sbox):
   # add some files, change directory properties
   change_files_and_commit(wc_dir, ['A/mu', 'A/D/gamma'])
   svntest.main.run_svn(None, 'up', wc_dir)
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', A_path)
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', D_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', A_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', D_path)
   svntest.main.run_svn(None, 'ci', '-m', 'log message', wc_dir)
 
   # update to r1
@@ -1572,8 +1572,8 @@ def status_depth_update_local_modificati
   mu_path = os.path.join(A_path, 'mu')
   gamma_path = os.path.join(D_path, 'gamma')
 
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', A_path)
-  svntest.main.run_svn(None, 'propset', 'svn:test', 'value', D_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', A_path)
+  svntest.main.run_svn(None, 'propset', '--force', 'svn:test', 'value', D_path)
 
   svntest.main.file_append(mu_path, 'modified')
   svntest.main.file_append(gamma_path, 'modified')

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/svnadmin_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/svnadmin_tests.py Tue Dec  4 15:35:13 2012
@@ -79,9 +79,9 @@ def check_hotcopy_fsfs(src, dst):
       # Compare all files in this directory
       for src_file in src_files:
         # Exclude temporary files
-        if src_file == 'rev-prop-atomicsShm':
+        if src_file == 'rev-prop-atomics.shm':
           continue
-        if src_file == 'rev-prop-atomicsMutex':
+        if src_file == 'rev-prop-atomics.mutex':
           continue
 
         src_path = os.path.join(src_dirpath, src_file)

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/svnlook_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/svnlook_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/svnlook_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/svnlook_tests.py Tue Dec  4 15:35:13 2012
@@ -696,6 +696,7 @@ fp.close()"""
   # Now check the logfile
   expected_data = [ 'bogus_val\n',
                     'bogus_rev_val\n',
+                    "Properties on '/A':\n",
                     '  bogus_prop\n',
                     '  svn:log\n', '  svn:author\n',
                     '  svn:check-locks\n', # internal prop, not really expected

Modified: subversion/branches/wc-collate-path/subversion/tests/cmdline/svnmucc_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/wc-collate-path/subversion/tests/cmdline/svnmucc_tests.py?rev=1416996&r1=1416995&r2=1416996&view=diff
==============================================================================
--- subversion/branches/wc-collate-path/subversion/tests/cmdline/svnmucc_tests.py (original)
+++ subversion/branches/wc-collate-path/subversion/tests/cmdline/svnmucc_tests.py Tue Dec  4 15:35:13 2012
@@ -312,11 +312,38 @@ def basic_svnmucc(sbox):
                 'cp', '17', 'a', 'b')
 
 
+def propset_root_internal(sbox, target):
+  ## propset on ^/
+  svntest.actions.run_and_verify_svnmucc(None, None, [],
+                                         'propset', 'foo', 'bar',
+                                         target)
+  svntest.actions.run_and_verify_svn(None, 'bar', [],
+                                     'propget', '--strict', 'foo',
+                                     target)
+
+  ## propdel on ^/
+  svntest.actions.run_and_verify_svnmucc(None, None, [],
+                                         'propdel', 'foo',
+                                         target)
+  svntest.actions.run_and_verify_svn(None, [], [],
+                                     'propget', '--strict', 'foo',
+                                     target)
+
+@Issues(3663)
+def propset_root(sbox):
+  "propset/propdel on repos root"
+
+  sbox.build(create_wc=False)
+  propset_root_internal(sbox, sbox.repo_url)
+  propset_root_internal(sbox, sbox.repo_url + '/iota')
+
+
 ######################################################################
 
 test_list = [ None,
               reject_bogus_mergeinfo,
               basic_svnmucc,
+              propset_root,
             ]
 
 if __name__ == '__main__':