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 2010/08/10 22:56:05 UTC

svn commit: r984206 [31/35] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...

Modified: subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnadmin/main.c Tue Aug 10 20:55:56 2010
@@ -230,7 +230,8 @@ enum
     svnadmin__wait,
     svnadmin__pre_1_4_compatible,
     svnadmin__pre_1_5_compatible,
-    svnadmin__pre_1_6_compatible
+    svnadmin__pre_1_6_compatible,
+    svnadmin__pre_1_7_compatible
   };
 
 /* Option codes and descriptions.
@@ -316,6 +317,10 @@ static const apr_getopt_option_t options
      N_("use format compatible with Subversion versions\n"
         "                             earlier than 1.6")},
 
+    {"pre-1.7-compatible",     svnadmin__pre_1_7_compatible, 0,
+     N_("use format compatible with Subversion versions\n"
+        "                             earlier than 1.7")},
+
     {NULL}
   };
 
@@ -336,7 +341,8 @@ static const svn_opt_subcommand_desc2_t 
     "Create a new, empty repository at REPOS_PATH.\n"),
    {svnadmin__bdb_txn_nosync, svnadmin__bdb_log_keep,
     svnadmin__config_dir, svnadmin__fs_type, svnadmin__pre_1_4_compatible,
-    svnadmin__pre_1_5_compatible, svnadmin__pre_1_6_compatible } },
+    svnadmin__pre_1_5_compatible, svnadmin__pre_1_6_compatible,
+    svnadmin__pre_1_7_compatible} },
 
   {"deltify", subcommand_deltify, {0}, N_
    ("usage: svnadmin deltify [-r LOWER[:UPPER]] REPOS_PATH\n\n"
@@ -488,6 +494,7 @@ struct svnadmin_opt_state
   svn_boolean_t pre_1_4_compatible;                 /* --pre-1.4-compatible */
   svn_boolean_t pre_1_5_compatible;                 /* --pre-1.5-compatible */
   svn_boolean_t pre_1_6_compatible;                 /* --pre-1.6-compatible */
+  svn_boolean_t pre_1_7_compatible;                 /* --pre-1.7-compatible */
   svn_opt_revision_t start_revision, end_revision;  /* -r X[:Y] */
   svn_boolean_t help;                               /* --help or -? */
   svn_boolean_t version;                            /* --version */
@@ -578,6 +585,11 @@ subcommand_create(apr_getopt_t *os, void
                  APR_HASH_KEY_STRING,
                  "1");
 
+  if (opt_state->pre_1_7_compatible)
+    apr_hash_set(fs_config, SVN_FS_CONFIG_PRE_1_7_COMPATIBLE,
+                 APR_HASH_KEY_STRING,
+                 "1");
+
   SVN_ERR(svn_config_get_config(&config, opt_state->config_dir, pool));
   SVN_ERR(svn_repos_create(&repos, opt_state->repository_path,
                            NULL, NULL,
@@ -638,6 +650,38 @@ subcommand_deltify(apr_getopt_t *os, voi
 }
 
 
+/* Baton for repos_progress_handler */
+struct progress_baton
+{
+  svn_boolean_t dumping;
+  svn_stream_t *progress_stream;
+};
+
+/* Implementation of svn_repos_progress_func_t to wrap the output to a
+   response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
+static svn_error_t *
+repos_progress_handler(void * baton,
+                       svn_revnum_t revision,
+                       const char *warning_text,
+                       apr_pool_t *scratch_pool)
+{
+  struct progress_baton *pb = baton;
+
+  if (warning_text != NULL)
+    {
+      apr_size_t len = strlen(warning_text);
+      return svn_error_return(svn_stream_write(pb->progress_stream,
+                                               warning_text, &len));
+    }
+
+  return svn_error_return(svn_stream_printf(pb->progress_stream, scratch_pool,
+                              pb->dumping
+                              ? _("* Dumped revision %ld.\n")
+                              : _("* Verified revision %ld.\n"),
+                              revision));
+}
+
+
 /* Baton for recode_write(). */
 struct recode_write_baton
 {
@@ -685,9 +729,10 @@ subcommand_dump(apr_getopt_t *os, void *
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
   svn_fs_t *fs;
-  svn_stream_t *stdout_stream, *stderr_stream = NULL;
+  svn_stream_t *stdout_stream;
   svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
   svn_revnum_t youngest;
+  struct progress_baton pb = { 0 };
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
@@ -719,12 +764,14 @@ subcommand_dump(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDERR, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    stderr_stream = recode_stream_create(stderr, pool);
+    pb.progress_stream = recode_stream_create(stderr, pool);
 
-  SVN_ERR(svn_repos_dump_fs2(repos, stdout_stream, stderr_stream,
-                             lower, upper, opt_state->incremental,
-                             opt_state->use_deltas, check_cancel, NULL,
-                             pool));
+  pb.dumping = TRUE;
+  SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
+                             opt_state->incremental, opt_state->use_deltas,
+                             !opt_state->quiet ? repos_progress_handler : NULL,
+                             !opt_state->quiet ? &pb : NULL,
+                             check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1173,10 +1220,10 @@ static svn_error_t *
 subcommand_verify(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   struct svnadmin_opt_state *opt_state = baton;
-  svn_stream_t *stderr_stream;
   svn_repos_t *repos;
   svn_fs_t *fs;
   svn_revnum_t youngest, lower, upper;
+  struct progress_baton pb = { 0 };
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
   fs = svn_repos_fs(repos);
@@ -1193,14 +1240,14 @@ subcommand_verify(apr_getopt_t *os, void
       upper = lower;
     }
 
-  if (opt_state->quiet)
-    stderr_stream = NULL;
-  else
-    stderr_stream = recode_stream_create(stderr, pool);
+  if (! opt_state->quiet)
+    pb.progress_stream = recode_stream_create(stderr, pool);
 
-  SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
-  return svn_repos_verify_fs(repos, stderr_stream, lower, upper,
-                             check_cancel, NULL, pool);
+  return svn_repos_verify_fs2(repos, lower, upper,
+                              !opt_state->quiet
+                                ? repos_progress_handler : NULL,
+                              !opt_state->quiet ? &pb : NULL,
+                              check_cancel, NULL, pool);
 }
 
 
@@ -1226,7 +1273,6 @@ subcommand_lslocks(apr_getopt_t *os, voi
   apr_array_header_t *targets;
   svn_repos_t *repos;
   const char *fs_path = "/";
-  svn_fs_t *fs;
   apr_hash_t *locks;
   apr_hash_index_t *hi;
 
@@ -1240,7 +1286,6 @@ subcommand_lslocks(apr_getopt_t *os, voi
     fs_path = APR_ARRAY_IDX(targets, 0, const char *);
 
   SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
-  fs = svn_repos_fs(repos);
 
   /* Fetch all locks on or below the root directory. */
   SVN_ERR(svn_repos_fs_get_locks(&locks, repos, fs_path, NULL, NULL, pool));
@@ -1443,7 +1488,7 @@ main(int argc, const char *argv[])
   apr_pool_t *pool;
 
   const svn_opt_subcommand_desc2_t *subcommand = NULL;
-  struct svnadmin_opt_state opt_state;
+  struct svnadmin_opt_state opt_state = { 0 };
   apr_getopt_t *os;
   int opt_id;
   apr_array_header_t *received_opts;
@@ -1484,7 +1529,6 @@ main(int argc, const char *argv[])
     }
 
   /* Initialize opt_state. */
-  memset(&opt_state, 0, sizeof(opt_state));
   opt_state.start_revision.kind = svn_opt_revision_unspecified;
   opt_state.end_revision.kind = svn_opt_revision_unspecified;
 
@@ -1572,6 +1616,9 @@ main(int argc, const char *argv[])
       case svnadmin__pre_1_6_compatible:
         opt_state.pre_1_6_compatible = TRUE;
         break;
+      case svnadmin__pre_1_7_compatible:
+        opt_state.pre_1_7_compatible = TRUE;
+        break;
       case svnadmin__fs_type:
         err = svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, pool);
         if (err)

Modified: subversion/branches/ignore-mergeinfo/subversion/svndumpfilter/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svndumpfilter/main.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svndumpfilter/main.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svndumpfilter/main.c Tue Aug 10 20:55:56 2010
@@ -191,6 +191,9 @@ struct parse_baton_t
   apr_hash_t *dropped_nodes;
   apr_hash_t *renumber_history;  /* svn_revnum_t -> struct revmap_t */
   svn_revnum_t last_live_revision;
+  /* The oldest original revision, greater than r0, in the input
+     stream which was not filtered. */
+  svn_revnum_t oldest_original_rev;
 };
 
 struct revision_baton_t
@@ -393,6 +396,11 @@ output_revision(struct revision_baton_t 
       SVN_ERR(svn_stream_write(rb->pb->out_stream,
                                props->data, &(props->len)));
 
+      /* Stash the oldest original rev not dropped. */
+      if (rb->rev_orig > 0
+          && !SVN_IS_VALID_REVNUM(rb->pb->oldest_original_rev))
+        rb->pb->oldest_original_rev = rb->rev_orig;
+
       if (rb->pb->do_renumber_revs)
         {
           svn_revnum_t *rr_key;
@@ -670,6 +678,25 @@ adjust_mergeinfo(svn_string_t **final_va
   apr_pool_t *subpool = svn_pool_create(pool);
 
   SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
+
+  /* Issue #3020: If we are skipping missing merge sources, then also
+     filter mergeinfo ranges as old or older than the oldest revision in the
+     dump stream.  Those older than the oldest obviously refer to history
+     outside of the dump stream.  The oldest rev itself is present in the
+     dump, but cannot be a valid merge source revision since it is the
+     start of all history.  E.g. if we dump -r100:400 then dumpfilter the
+     result with --skip-missing-merge-sources, any mergeinfo with revision
+     100 implies a change of -r99:100, but r99 is part of the history we
+     want filtered.  This is analogous to how r1 is always meaningless as
+     a merge source revision.
+
+     If the oldest rev is r0 then there is nothing to filter. */
+  if (rb->pb->skip_missing_merge_sources && rb->pb->oldest_original_rev > 0)
+    SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+      &mergeinfo, mergeinfo,
+      rb->pb->oldest_original_rev, 0,
+      FALSE, subpool, subpool));
+
   for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
     {
       const char *merge_source = svn__apr_hash_index_key(hi);
@@ -977,7 +1004,12 @@ parse_baton_initialize(struct parse_bato
                               apr_file_open_stdout, pool));
 
   baton->do_exclude = do_exclude;
-  baton->do_renumber_revs = opt_state->renumber_revs;
+
+  /* Ignore --renumber-revs if there can't possibly be
+     anything to renumber. */
+  baton->do_renumber_revs =
+    (opt_state->renumber_revs && opt_state->drop_empty_revs);
+
   baton->drop_empty_revs = opt_state->drop_empty_revs;
   baton->preserve_revprops = opt_state->preserve_revprops;
   baton->quiet = opt_state->quiet;
@@ -988,6 +1020,7 @@ parse_baton_initialize(struct parse_bato
   baton->dropped_nodes = apr_hash_make(pool);
   baton->renumber_history = apr_hash_make(pool);
   baton->last_live_revision = SVN_INVALID_REVNUM;
+  baton->oldest_original_rev = SVN_INVALID_REVNUM;
 
   /* This is non-ideal: We should pass through the version of the
    * input dumpstream.  However, our API currently doesn't allow that.

Modified: subversion/branches/ignore-mergeinfo/subversion/svnserve/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnserve/cyrus_auth.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnserve/cyrus_auth.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnserve/cyrus_auth.c Tue Aug 10 20:55:56 2010
@@ -102,7 +102,7 @@ static sasl_callback_t callbacks[] =
   { SASL_CB_LIST_END, NULL, NULL }
 };
 
-static svn_error_t *initialize(apr_pool_t *pool)
+static svn_error_t *initialize(void *baton, apr_pool_t *pool)
 {
   int result;
   apr_status_t status;
@@ -127,7 +127,8 @@ static svn_error_t *initialize(apr_pool_
 
 svn_error_t *cyrus_init(apr_pool_t *pool)
 {
-  SVN_ERR(svn_atomic__init_once(&svn_ra_svn__sasl_status, initialize, pool));
+  SVN_ERR(svn_atomic__init_once(&svn_ra_svn__sasl_status,
+                                initialize, NULL, pool));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ignore-mergeinfo/subversion/svnsync/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnsync/main.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnsync/main.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnsync/main.c Tue Aug 10 20:55:56 2010
@@ -107,27 +107,37 @@ static const svn_opt_subcommand_desc2_t 
       { SVNSYNC_OPTS_DEFAULT, 'q', svnsync_opt_allow_non_empty,
         svnsync_opt_disable_locking } },
     { "synchronize", synchronize_cmd, { "sync" },
-      N_("usage: svnsync synchronize DEST_URL\n"
+      N_("usage: svnsync synchronize DEST_URL [SOURCE_URL]\n"
          "\n"
          "Transfer all pending revisions to the destination from the source\n"
-         "with which it was initialized.\n"),
+         "with which it was initialized.\n"
+         "\n"
+         "If SOURCE_URL is provided, use that as the source repository URL,\n"
+         "ignoring what is recorded in the destination repository as the\n"
+         "source URL.  Specifying SOURCE_URL is recommended in particular\n"
+         "if untrusted users/administrators may have write access to the\n"
+         "DEST_URL repository.\n"),
       { SVNSYNC_OPTS_DEFAULT, 'q', svnsync_opt_disable_locking } },
     { "copy-revprops", copy_revprops_cmd, { 0 },
-      N_("usage: svnsync copy-revprops DEST_URL [REV[:REV2]]\n"
+      N_("usage:\n"
+         "\n"
+         "    1. svnsync copy-revprops DEST_URL [SOURCE_URL]\n"
+         "    2. svnsync copy-revprops DEST_URL REV[:REV2]\n"
          "\n"
          "Copy the revision properties in a given range of revisions to the\n"
-         "destination from the source with which it was initialized.\n"
+         "destination from the source with which it was initialized.  If the\n"
+         "revision range is not specified, it defaults to all revisions in\n"
+         "the DEST_URL repository.  Note also that the 'HEAD' revision is the\n"
+         "latest in DEST_URL, not necessarily the latest in SOURCE_URL.\n"
          "\n"
-         "If REV and REV2 are provided, copy properties for the revisions\n"
-         "specified by that range, inclusively.  If only REV is provided,\n"
-         "copy properties for that revision alone.  If REV is not provided,\n"
-         "copy properties for all revisions previously transferred to the\n"
-         "destination.\n"
+         "If SOURCE_URL is provided, use that as the source repository URL,\n"
+         "ignoring what is recorded in the destination repository as the\n"
+         "source URL.  Specifying SOURCE_URL is recommended in particular\n"
+         "if untrusted users/administrators may have write access to the\n"
+         "DEST_URL repository.\n"
          "\n"
-         "REV and REV2 must be revisions which were previously transferred\n"
-         "to the destination.  You may use \"HEAD\" for either revision to\n"
-         "mean \"the last revision transferred\".\n"),
-      { SVNSYNC_OPTS_DEFAULT, 'q', svnsync_opt_disable_locking } },
+         "Form 2 is deprecated syntax, equivalent to specifying \"-rREV[:REV2]\".\n"),
+      { SVNSYNC_OPTS_DEFAULT, 'q', 'r', svnsync_opt_disable_locking } },
     { "info", info_cmd, { 0 },
       N_("usage: svnsync info DEST_URL\n"
          "\n"
@@ -146,6 +156,14 @@ static const apr_getopt_option_t svnsync
   {
     {"quiet",          'q', 0,
                        N_("print as little as possible") },
+    {"revision",       'r', 1, 
+                       N_("operate on revision ARG (or range ARG1:ARG2)\n"
+                          "                             "
+                          "A revision argument can be one of:\n"
+                          "                             "
+                          "    NUMBER       revision number\n"
+                          "                             "
+                          "    'HEAD'       latest in repository") },
     {"allow-non-empty", svnsync_opt_allow_non_empty, 0,
                        N_("allow a non-empty destination repository") },
     {"non-interactive", svnsync_opt_non_interactive, 0,
@@ -214,6 +232,8 @@ typedef struct {
   svn_boolean_t allow_non_empty;
   svn_boolean_t version;
   svn_boolean_t help;
+  svn_opt_revision_t start_rev;
+  svn_opt_revision_t end_rev;
 } opt_baton_t;
 
 
@@ -840,10 +860,12 @@ commit_callback(const svn_commit_info_t 
 
 
 /* Set *FROM_SESSION to an RA session associated with the source
- * repository of the synchronization, as determined by reading
- * svn:sync- properties from the destination repository (associated
- * with TO_SESSION).  Set LAST_MERGED_REV to the value of the property
- * which records the most recently synchronized revision.
+ * repository of the synchronization.  If FROM_URL is non-NULL, use it
+ * as the source repository URL; otherwise, determine the source
+ * repository URL by reading svn:sync- properties from the destination
+ * repository (associated with TO_SESSION).  Set LAST_MERGED_REV to
+ * the value of the property which records the most recently
+ * synchronized revision.
  *
  * CALLBACKS is a vtable of RA callbacks to provide when creating
  * *FROM_SESSION.  CONFIG is a configuration hash.
@@ -851,28 +873,34 @@ commit_callback(const svn_commit_info_t 
 static svn_error_t *
 open_source_session(svn_ra_session_t **from_session,
                     svn_string_t **last_merged_rev,
+                    const char *from_url,
                     svn_ra_session_t *to_session,
                     svn_ra_callbacks2_t *callbacks,
                     apr_hash_t *config,
                     void *baton,
                     apr_pool_t *pool)
 {
-  svn_string_t *from_url, *from_uuid;
+  svn_string_t *from_url_str, *from_uuid_str;
 
   SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_URL,
-                          &from_url, pool));
+                          &from_url_str, pool));
   SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_FROM_UUID,
-                          &from_uuid, pool));
+                          &from_uuid_str, pool));
   SVN_ERR(svn_ra_rev_prop(to_session, 0, SVNSYNC_PROP_LAST_MERGED_REV,
                           last_merged_rev, pool));
 
-  if (! from_url || ! from_uuid || ! *last_merged_rev)
+  if (! from_url_str || ! from_uuid_str || ! *last_merged_rev)
     return svn_error_create
       (APR_EINVAL, NULL,
        _("Destination repository has not been initialized"));
 
+  /* ### TODO: Should we validate that FROM_URL_STR->data matches any
+     provided FROM_URL here?  */
+  if (! from_url)
+    from_url = from_url_str->data;
+
   /* Open the session to copy the revision data. */
-  SVN_ERR(svn_ra_open3(from_session, from_url->data, from_uuid->data,
+  SVN_ERR(svn_ra_open3(from_session, from_url, from_uuid_str->data,
                        callbacks, baton, config, pool));
 
   return SVN_NO_ERROR;
@@ -1137,8 +1165,8 @@ do_synchronize(svn_ra_session_t *to_sess
   replay_baton_t *rb;
   int normalized_rev_props_count = 0;
 
-  SVN_ERR(open_source_session(&from_session,
-                              &last_merged_rev, to_session,
+  SVN_ERR(open_source_session(&from_session, &last_merged_rev,
+                              baton->from_url, to_session,
                               &(baton->source_callbacks), baton->config,
                               baton, pool));
 
@@ -1267,7 +1295,7 @@ synchronize_cmd(apr_getopt_t *os, void *
   opt_baton_t *opt_baton = b;
   apr_array_header_t *targets;
   subcommand_baton_t *baton;
-  const char *to_url;
+  const char *to_url, *from_url;
 
   SVN_ERR(svn_opt__args_to_target_array(&targets, os,
                                         apr_array_make(pool, 0,
@@ -1275,16 +1303,27 @@ synchronize_cmd(apr_getopt_t *os, void *
                                         pool));
   if (targets->nelts < 1)
     return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
-  if (targets->nelts > 1)
+  if (targets->nelts > 2)
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
 
   to_url = APR_ARRAY_IDX(targets, 0, const char *);
-
   if (! svn_path_is_url(to_url))
     return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("Path '%s' is not a URL"), to_url);
 
-  baton = make_subcommand_baton(opt_baton, to_url, NULL, 0, 0, pool);
+  if (targets->nelts == 2)
+    {
+      from_url = APR_ARRAY_IDX(targets, 1, const char *);
+      if (! svn_path_is_url(from_url))
+        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                 _("Path '%s' is not a URL"), from_url);
+    }
+  else
+    {
+      from_url = NULL; /* we'll read it from the destination repos */
+    }
+
+  baton = make_subcommand_baton(opt_baton, to_url, from_url, 0, 0, pool);
   SVN_ERR(svn_ra_open3(&to_session, baton->to_url, NULL,
                        &(baton->sync_callbacks), baton, baton->config, pool));
   SVN_ERR(check_if_session_is_at_repos_root(to_session, baton->to_url, pool));
@@ -1315,7 +1354,7 @@ do_copy_revprops(svn_ra_session_t *to_se
   int normalized_rev_props_count = 0;
 
   SVN_ERR(open_source_session(&from_session, &last_merged_rev,
-                              to_session,
+                              baton->from_url, to_session,
                               &(baton->source_callbacks), baton->config,
                               baton, pool));
 
@@ -1355,6 +1394,78 @@ do_copy_revprops(svn_ra_session_t *to_se
 }
 
 
+/* Set *START_REVNUM to the revision number associated with
+   START_REVISION, or to SVN_INVALID_REVNUM if START_REVISION
+   represents "HEAD"; if END_REVISION is specified, set END_REVNUM to
+   the revision number associated with END_REVISION or to
+   SVN_INVALID_REVNUM if END_REVISION represents "HEAD"; otherwise set
+   END_REVNUM to the same value as START_REVNUM.
+
+   As a special case, if neither START_REVISION nor END_REVISION is
+   specified, set *START_REVNUM to 0 and set *END_REVNUM to
+   SVN_INVALID_REVNUM.
+
+   Freak out if either START_REVISION or END_REVISION represents an
+   explicit but invalid revision number. */
+static svn_error_t *
+resolve_revnums(svn_revnum_t *start_revnum,
+                svn_revnum_t *end_revnum,
+                svn_opt_revision_t start_revision,
+                svn_opt_revision_t end_revision)
+{
+  svn_revnum_t start_rev, end_rev;
+
+  /* Special case: neither revision is specified?  This is like
+     -r0:HEAD. */
+  if ((start_revision.kind == svn_opt_revision_unspecified) &&
+      (end_revision.kind == svn_opt_revision_unspecified))
+    {
+      start_rev = 0;
+      end_rev = SVN_INVALID_REVNUM;
+      return SVN_NO_ERROR;
+    }
+
+  /* Get the start revision, which must be either HEAD or a number
+     (which is required to be a valid one). */
+  if (start_revision.kind == svn_opt_revision_head)
+    {
+      start_rev = SVN_INVALID_REVNUM;
+    }
+  else
+    {
+      start_rev = start_revision.value.number;
+      if (! SVN_IS_VALID_REVNUM(start_rev))
+        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                 _("Invalid revision number (%ld)"),
+                                 start_rev);
+    }
+
+  /* Get the end revision, which must be unspecified (meaning,
+     "same as the start_rev"), HEAD, or a number (which is
+     required to be a valid one). */
+  if (end_revision.kind == svn_opt_revision_unspecified)
+    {
+      end_rev = start_rev;
+    }
+  else if (end_revision.kind == svn_opt_revision_head)
+    {
+      end_rev = SVN_INVALID_REVNUM;
+    }
+  else
+    {
+      end_rev = end_revision.value.number;
+      if (! SVN_IS_VALID_REVNUM(end_rev))
+        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                 _("Invalid revision number (%ld)"),
+                                 end_rev);
+    }
+  
+  *start_revnum = start_rev;
+  *end_revnum = end_rev;
+  return SVN_NO_ERROR;
+}
+
+
 /* SUBCOMMAND: copy-revprops */
 static svn_error_t *
 copy_revprops_cmd(apr_getopt_t *os, void *b, apr_pool_t *pool)
@@ -1363,7 +1474,8 @@ copy_revprops_cmd(apr_getopt_t *os, void
   opt_baton_t *opt_baton = b;
   apr_array_header_t *targets;
   subcommand_baton_t *baton;
-  const char *to_url;
+  const char *to_url = NULL;
+  const char *from_url;
   svn_opt_revision_t start_revision, end_revision;
   svn_revnum_t start_rev = 0, end_rev = SVN_INVALID_REVNUM;
 
@@ -1373,77 +1485,80 @@ copy_revprops_cmd(apr_getopt_t *os, void
   if (os->argc - os->ind < 1)
     return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
 
-  /* If there are two args, the last one is a revision range.  We'll
-     effectively pop it from the end of the list.  Why?  Because
-     svn_opt__args_to_target_array() does waaaaay too many useful
-     things for us not to use it.  */
+  /* If there are two args, the last one is either a revision range or
+     the source URL.  */
   if (os->argc - os->ind == 2)
     {
-      const char *rev_str = os->argv[--(os->argc)];
+      const char *arg_str = os->argv[os->argc - 1];
+      const char *utf_arg_str;
 
-      start_revision.kind = svn_opt_revision_unspecified;
-      end_revision.kind = svn_opt_revision_unspecified;
-      if ((svn_opt_parse_revision(&start_revision, &end_revision,
-                                  rev_str, pool) != 0)
-          || ((start_revision.kind != svn_opt_revision_number)
-              && (start_revision.kind != svn_opt_revision_head))
-          || ((end_revision.kind != svn_opt_revision_number)
-              && (end_revision.kind != svn_opt_revision_head)
-              && (end_revision.kind != svn_opt_revision_unspecified)))
-        return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("'%s' is not a valid revision range"),
-                                 rev_str);
+      SVN_ERR(svn_utf_cstring_to_utf8(&utf_arg_str, arg_str, pool));
 
-      /* Get the start revision, which must be either HEAD or a number
-         (which is required to be a valid one). */
-      if (start_revision.kind == svn_opt_revision_head)
+      if (! svn_path_is_url(utf_arg_str))
         {
-          start_rev = SVN_INVALID_REVNUM;
-        }
-      else
-        {
-          start_rev = start_revision.value.number;
-          if (! SVN_IS_VALID_REVNUM(start_rev))
+          /* This is the old "... TO_URL REV[:REV2]" syntax.
+             Revisions come only from this argument.  (We effectively
+             pop that last argument from the end of the argument list
+             so svn_opt__args_to_target_array() can do its thang.) */
+          os->argc--;
+
+          if ((opt_baton->start_rev.kind != svn_opt_revision_unspecified)
+              || (opt_baton->end_rev.kind != svn_opt_revision_unspecified))
+            return svn_error_create(
+                SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                _("Cannot specify revisions via both command-line arguments "
+                  "and the --revision (-r) option"));
+
+          start_revision.kind = svn_opt_revision_unspecified;
+          end_revision.kind = svn_opt_revision_unspecified;
+          if (svn_opt_parse_revision(&start_revision, &end_revision,
+                                     arg_str, pool) != 0)
             return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                     _("Invalid revision number (%ld)"),
-                                     start_rev);
-        }
+                                     _("Invalid revision range '%s' provided"),
+                                     arg_str);
 
-      /* Get the end revision, which must be unspecified (meaning,
-         "same as the start_rev"), HEAD, or a number (which is
-         required to be a valid one). */
-      if (end_revision.kind == svn_opt_revision_unspecified)
-        {
-          end_rev = start_rev;
-        }
-      else if (end_revision.kind == svn_opt_revision_head)
-        {
-          end_rev = SVN_INVALID_REVNUM;
+          SVN_ERR(resolve_revnums(&start_rev, &end_rev,
+                                  start_revision, end_revision));
+
+          SVN_ERR(svn_opt__args_to_target_array(
+                      &targets, os,
+                      apr_array_make(pool, 1, sizeof(const char *)), pool));
+          if (targets->nelts != 1)
+            return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+          to_url = APR_ARRAY_IDX(targets, 0, const char *);
+          from_url = NULL;
         }
+    }
+  
+  if (! to_url)
+    {
+      /* This is the "... TO_URL SOURCE_URL" syntax.  Revisions
+         come only from the --revision parameter.  */
+      SVN_ERR(resolve_revnums(&start_rev, &end_rev,
+                              opt_baton->start_rev, opt_baton->end_rev));
+
+      SVN_ERR(svn_opt__args_to_target_array(
+                  &targets, os,
+                  apr_array_make(pool, 2, sizeof(const char *)), pool));
+      if (targets->nelts < 1)
+        return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+      if (targets->nelts > 2)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+      to_url = APR_ARRAY_IDX(targets, 0, const char *);
+      if (targets->nelts == 2)
+        from_url = APR_ARRAY_IDX(targets, 1, const char *);
       else
-        {
-          end_rev = end_revision.value.number;
-          if (! SVN_IS_VALID_REVNUM(end_rev))
-            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                     _("Invalid revision number (%ld)"),
-                                     end_rev);
-        }
+        from_url = NULL;
     }
 
-  SVN_ERR(svn_opt__args_to_target_array(&targets, os,
-                                        apr_array_make(pool, 1,
-                                                       sizeof(const char *)),
-                                        pool));
-  if (targets->nelts != 1)
-    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
-
-  to_url = APR_ARRAY_IDX(targets, 0, const char *);
-
   if (! svn_path_is_url(to_url))
     return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                              _("Path '%s' is not a URL"), to_url);
-
-  baton = make_subcommand_baton(opt_baton, to_url, NULL,
+  if (from_url && (! svn_path_is_url(from_url)))
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("Path '%s' is not a URL"), from_url);
+      
+  baton = make_subcommand_baton(opt_baton, to_url, from_url,
                                 start_rev, end_rev, pool);
   SVN_ERR(svn_ra_open3(&to_session, baton->to_url, NULL,
                        &(baton->sync_callbacks), baton, baton->config, pool));
@@ -1572,6 +1687,7 @@ main(int argc, const char *argv[])
   const char *username = NULL, *source_username = NULL, *sync_username = NULL;
   const char *password = NULL, *source_password = NULL, *sync_password = NULL;
   apr_array_header_t *config_options = NULL;
+  apr_allocator_t *allocator;
 
   if (svn_cmdline_init("svnsync", stderr) != EXIT_SUCCESS)
     {
@@ -1582,13 +1698,25 @@ main(int argc, const char *argv[])
   if (err)
     return svn_cmdline_handle_exit_error(err, NULL, "svnsync: ");
 
-  pool = svn_pool_create(NULL);
+  /* Create our top-level pool.  Use a separate mutexless allocator,
+   * given this application is single threaded.
+   */
+  if (apr_allocator_create(&allocator))
+    return EXIT_FAILURE;
+
+  apr_allocator_max_free_set(allocator, SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
+
+  pool = svn_pool_create_ex(NULL, allocator);
+  apr_allocator_owner_set(allocator, pool);
 
   err = svn_ra_initialize(pool);
   if (err)
     return svn_cmdline_handle_exit_error(err, pool, "svnsync: ");
 
+  /* Initialize the option baton. */
   memset(&opt_baton, 0, sizeof(opt_baton));
+  opt_baton.start_rev.kind = svn_opt_revision_unspecified;
+  opt_baton.end_rev.kind = svn_opt_revision_unspecified;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
@@ -1699,6 +1827,35 @@ main(int argc, const char *argv[])
             opt_baton.quiet = TRUE;
             break;
 
+          case 'r':
+            if (svn_opt_parse_revision(&opt_baton.start_rev,
+                                       &opt_baton.end_rev,
+                                       opt_arg, pool) != 0)
+              {
+                const char *utf8_opt_arg;
+                err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
+                if (! err)
+                  err = svn_error_createf(
+                            SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                            _("Syntax error in revision argument '%s'"),
+                            utf8_opt_arg);
+                return svn_cmdline_handle_exit_error(err, pool, "svnsync: ");
+              }
+
+            /* We only allow numbers and 'HEAD'. */
+            if (((opt_baton.start_rev.kind != svn_opt_revision_number) &&
+                 (opt_baton.start_rev.kind != svn_opt_revision_head))
+                || ((opt_baton.end_rev.kind != svn_opt_revision_number) &&
+                    (opt_baton.end_rev.kind != svn_opt_revision_head) &&
+                    (opt_baton.end_rev.kind != svn_opt_revision_unspecified)))
+              {
+                err = svn_error_createf(
+                          SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                          _("Invalid revision range '%s' provided"), opt_arg);
+                return svn_cmdline_handle_exit_error(err, pool, "svnsync: ");
+              }
+            break;
+
           case '?':
           case 'h':
             opt_baton.help = TRUE;

Modified: subversion/branches/ignore-mergeinfo/subversion/svnversion/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/svnversion/main.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/svnversion/main.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/svnversion/main.c Tue Aug 10 20:55:56 2010
@@ -290,6 +290,16 @@ main(int argc, const char *argv[])
       return EXIT_FAILURE;
     }
 
+  if (! SVN_IS_VALID_REVNUM(res->min_rev))
+    {
+      /* Local uncommitted modifications, no revision info was found. */
+      SVN_INT_ERR(svn_cmdline_printf(pool, _("Uncommitted local addition, "
+                                             "copy or move%s"),
+                                             no_newline ? "" : "\n"));
+      svn_pool_destroy(pool);
+      return EXIT_SUCCESS;
+    }
+
   /* Build compact '123[:456]M?S?' string. */
   SVN_INT_ERR(svn_cmdline_printf(pool, "%ld", res->min_rev));
   if (res->min_rev != res->max_rev)

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/authz_tests.py Tue Aug 10 20:55:56 2010
@@ -903,6 +903,42 @@ def authz_access_required_at_repo_root(s
                        root_url + '/A-copy/B/E/beta',
                        root_url + '/A-copy/C')
 
+def authz_access_required_at_repo_root2(sbox):
+  "more authz issue #3242 - update to renamed file"
+
+  sbox.build(create_wc = False)
+  root_url = sbox.repo_url
+
+  # Now we get all restrictive.
+  write_authz_file(sbox, {'/': '* =',
+                          '/A': 'jrandom = rw'})
+  write_restrictive_svnserve_conf(sbox.repo_dir)
+
+  # Rename a file.
+  svntest.main.run_svn(None, 'mv',
+                       '-m', 'rename file in readable writable space',
+                       root_url + '/A/B/E/alpha',
+                       root_url + '/A/B/E/alpha-renamed')
+  
+  # Check out original greek sub tree below /A/B/E 
+  # and update it to the above rename.
+  wc_dir = sbox.add_wc_path('ABE')
+  os.mkdir(wc_dir)
+  svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/B/E', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # Rename a directory.
+  svntest.main.run_svn(None, 'mv',
+                       '-m', 'rename diretory in readable writable space',
+                       root_url + '/A/D/H',
+                       root_url + '/A/D/a g e')
+  
+  # Check out original greek sub tree below /A/D
+  # and update it to the above rename.
+  wc_dir = sbox.add_wc_path('AD')
+  os.mkdir(wc_dir)
+  svntest.main.run_svn(None, 'co', '-r', '1', root_url + '/A/D', wc_dir)
+  svntest.main.run_svn(None, 'up', wc_dir)
 
 def multiple_matches(sbox):
   "multiple lines matching a user"
@@ -962,6 +998,8 @@ test_list = [ None,
                          svntest.main.is_ra_type_file)),
               Skip(authz_access_required_at_repo_root,
                    svntest.main.is_ra_type_file),
+              Skip(authz_access_required_at_repo_root2,
+                   svntest.main.is_ra_type_file),
               Skip(multiple_matches, svntest.main.is_ra_type_file),
              ]
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/basic_tests.py Tue Aug 10 20:55:56 2010
@@ -378,9 +378,8 @@ def basic_corruption(sbox):
 
   # Modify mu's text-base, so we get a checksum failure the first time
   # we try to commit.
-  tb_dir_path = os.path.join(wc_dir, 'A',
-                             svntest.main.get_admin_name(), 'text-base')
-  mu_tb_path = os.path.join(tb_dir_path, 'mu.svn-base')
+  mu_tb_path = svntest.wc.text_base_path(mu_path)
+  tb_dir_path = os.path.dirname(mu_tb_path)
   mu_saved_tb_path = mu_tb_path + "-saved"
   tb_dir_saved_mode = os.stat(tb_dir_path)[stat.ST_MODE]
   mu_tb_saved_mode = os.stat(mu_tb_path)[stat.ST_MODE]
@@ -424,9 +423,9 @@ def basic_corruption(sbox):
 
   # Modify mu's text-base, so we get a checksum failure the first time
   # we try to update.
-  tb_dir_path = os.path.join(other_wc, 'A',
-                             svntest.main.get_admin_name(), 'text-base')
-  mu_tb_path = os.path.join(tb_dir_path, 'mu.svn-base')
+  other_mu_path = os.path.join(other_wc, 'A', 'mu')
+  mu_tb_path = svntest.wc.text_base_path(other_mu_path)
+  tb_dir_path = os.path.dirname(mu_tb_path)
   mu_saved_tb_path = mu_tb_path + "-saved"
   tb_dir_saved_mode = os.stat(tb_dir_path)[stat.ST_MODE]
   mu_tb_saved_mode = os.stat(mu_tb_path)[stat.ST_MODE]
@@ -2455,7 +2454,7 @@ def basic_add_svn_format_file(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
-  entries_path = os.path.join(wc_dir, '.svn', 'format')
+  entries_path = os.path.join(wc_dir, svntest.main.get_admin_name(), 'format')
 
   output = svntest.actions.get_virginal_state(wc_dir, 1)
 
@@ -2478,6 +2477,26 @@ def basic_mkdir_mix_targets(sbox):
   svntest.actions.run_and_verify_svn(None, None, expected_error,
                                      'mkdir', '-m', 'log_msg', Y_url, 'subdir')
 
+def delete_from_url_with_spaces(sbox):
+  "delete a directory with ' ' using its url"
+  
+  sbox.build()
+  sbox.simple_mkdir(os.path.join(sbox.wc_dir, 'Dir With Spaces'))
+  sbox.simple_mkdir(os.path.join(sbox.wc_dir, 'Dir With'))
+  sbox.simple_mkdir(os.path.join(sbox.wc_dir, 'Dir With/Spaces'))
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                      'ci', sbox.wc_dir, '-m', 'Added dir')
+  
+  # This fails on 1.6.11 with an escaping error.
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                      'rm', sbox.repo_url + '/Dir%20With%20Spaces',
+                                      '-m', 'Deleted')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                      'rm', sbox.repo_url + '/Dir%20With/Spaces',
+                                      '-m', 'Deleted')
+
 #----------------------------------------------------------------------
 
 ########################################################################
@@ -2534,6 +2553,7 @@ test_list = [ None,
               basic_auth_test,
               basic_add_svn_format_file,
               basic_mkdir_mix_targets,
+              delete_from_url_with_spaces,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/changelist_tests.py Tue Aug 10 20:55:56 2010
@@ -45,9 +45,10 @@ def mod_all_files(wc_dir, new_text):
   """Walk over working copy WC_DIR, appending NEW_TEXT to all the
   files in that tree (but not inside the .svn areas of that tree)."""
 
+  dot_svn = svntest.main.get_admin_name()
   for dirpath, dirs, files in os.walk(wc_dir):
-    if ".svn" in dirs:
-      dirs.remove(".svn")
+    if dot_svn in dirs:
+      dirs.remove(dot_svn)
     for name in files:
       svntest.main.file_append(os.path.join(dirpath, name), new_text)
 
@@ -57,9 +58,10 @@ def changelist_all_files(wc_dir, name_fu
   noting its string return value (or None, if we wish to remove the
   file from a changelist)."""
 
+  dot_svn = svntest.main.get_admin_name()
   for dirpath, dirs, files in os.walk(wc_dir):
-    if ".svn" in dirs:
-      dirs.remove(".svn")
+    if dot_svn in dirs:
+      dirs.remove(dot_svn)
     for name in files:
         full_path = os.path.join(dirpath, name)
         clname = name_func(full_path)

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/commit_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/commit_tests.py Tue Aug 10 20:55:56 2010
@@ -1126,7 +1126,7 @@ def commit_in_dir_scheduled_for_addition
   svntest.actions.run_and_verify_commit(wc_dir,
                                         None,
                                         None,
-                                        "unversioned",
+                                        "not under version control",
                                         mu_path)
 
   Q_path = os.path.join(wc_dir, 'Q')
@@ -1961,7 +1961,7 @@ def mods_in_schedule_delete(sbox):
                                         None, wc_dir)
 
   # Unversioned file still exists
-  actual_contents = svntest.main.file_read(foo_path)
+  actual_contents = open(foo_path).read()
   if actual_contents != foo_contents:
     raise svntest.Failure
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/copy_tests.py Tue Aug 10 20:55:56 2010
@@ -980,7 +980,7 @@ def repos_to_wc(sbox):
 
   expected_output = svntest.actions.get_virginal_state(wc_dir, 1)
   expected_output.add({
-    'pi' : Item(status='A ',  wc_rev='1'),
+    'pi' : Item(status='A ',  wc_rev='0', entry_rev='1'),
     })
   svntest.actions.run_and_verify_status(wc_dir, expected_output)
 
@@ -1735,7 +1735,13 @@ def mixed_wc_to_url(sbox):
 
   wc_dir = sbox.wc_dir
   Z_url = sbox.repo_url + '/A/D/Z'
+  Z2_url = sbox.repo_url + '/A/D/Z2'
   G_path = os.path.join(wc_dir, 'A', 'D', 'G')
+  B_path = os.path.join(wc_dir, 'A', 'B')
+  X_path = os.path.join(wc_dir, 'A', 'D', 'G', 'X')
+  Y_path = os.path.join(wc_dir, 'A', 'D', 'G', 'Y')
+  E_path = os.path.join(wc_dir, 'A', 'D', 'G', 'X', 'E')
+  alpha_path = os.path.join(wc_dir, 'A', 'D', 'G', 'X', 'E', 'alpha')
   pi_path = os.path.join(wc_dir, 'A', 'D', 'G', 'pi')
   rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho')
 
@@ -1752,10 +1758,46 @@ def mixed_wc_to_url(sbox):
   # Make another modification to A/D/G/rho, but don't commit it.
   svntest.main.file_append(rho_path, "Second modification to rho.\n")
 
+  # Copy into the source, delete part of the copy, add a non-copied directory
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', B_path, X_path)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'rm', alpha_path)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'mkdir', Y_path)
+
   # Now copy local A/D/G to create new directory A/D/Z the repository.
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'cp', '-m', "Make a copy.",
                                      G_path, Z_url)
+  expected_output = svntest.verify.UnorderedOutput([
+    'A + A/D/Z/\n',
+    '    (from A/D/G/:r1)\n',
+    'A + A/D/Z/X/\n',
+    '    (from A/B/:r1)\n',
+    'D   A/D/Z/X/E/alpha\n',
+    'A   A/D/Z/Y/\n',
+    'D   A/D/Z/pi\n',
+    'D   A/D/Z/rho\n',
+    'A + A/D/Z/rho\n',
+    '    (from A/D/G/rho:r3)\n',
+    ])
+  svntest.actions.run_and_verify_svnlook(None, expected_output, [],
+                                         'changed', sbox.repo_dir,
+                                         '--copy-info')
+
+  # Copy from copied source
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', '-m', "Make a copy.",
+                                     E_path, Z2_url)
+  expected_output = svntest.verify.UnorderedOutput([
+    'A + A/D/Z2/\n',
+    '    (from A/B/E/:r1)\n',
+    'D   A/D/Z2/alpha\n',
+    ])
+  svntest.actions.run_and_verify_svnlook(None, expected_output, [],
+                                         'changed', sbox.repo_dir,
+                                         '--copy-info')
 
   # Check out A/D/Z.  If it has pi, that's a bug; or if its rho does
   # not have the second local mod, that's also a bug.
@@ -1764,7 +1806,7 @@ def mixed_wc_to_url(sbox):
                                      'co', Z_url, wc_dir)
 
   if os.path.exists(os.path.join(wc_dir, 'pi')):
-    raise svntest.Failure
+    raise svntest.Failure("Path 'pi' exists but should be gone.")
 
   fp = open(os.path.join(wc_dir, 'rho'), 'r')
   found_it = 0
@@ -1772,7 +1814,7 @@ def mixed_wc_to_url(sbox):
     if re.match("^Second modification to rho.", line):
       found_it = 1
   if not found_it:
-    raise svntest.Failure
+    raise svntest.Failure("The second modification to rho didn't make it.")
 
 
 #----------------------------------------------------------------------
@@ -4389,6 +4431,36 @@ def nonrecursive_commit_of_copy(sbox):
                                         None,
                                         wc_dir, '--depth', 'immediates')
 
+def copy_added_dir_with_copy(sbox):
+  """copy of new dir with copied file keeps history"""
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  new_dir = os.path.join(wc_dir, 'NewDir');
+  new_dir2 = os.path.join(wc_dir, 'NewDir2');
+
+  # Alias for svntest.actions.run_and_verify_svn
+  rav_svn = svntest.actions.run_and_verify_svn
+
+  rav_svn(None, None, [], 'mkdir', new_dir)
+  rav_svn(None, None, [], 'cp', os.path.join(wc_dir, 'A', 'mu'), new_dir)
+  rav_svn(None, None, [], 'cp', new_dir, new_dir2)
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+
+  expected_status.add(
+    {
+      'NewDir'            : Item(status='A ', wc_rev='0'),
+      'NewDir/mu'         : Item(status='A ', copied='+', wc_rev='-'),
+      'NewDir2'           : Item(status='A ', wc_rev='0'),
+      'NewDir2/mu'        : Item(status='A ', copied='+', wc_rev='-'),
+    })
+
+  # Currently this fails because NewDir2/mu loses its history in the copy
+  # from NewDir to NewDir2
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
 
 ########################################################################
 # Run the tests
@@ -4479,6 +4551,7 @@ test_list = [ None,
               XFail(move_below_move),
               reverse_merge_move,
               XFail(nonrecursive_commit_of_copy),
+              XFail(copy_added_dir_with_copy),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/depth_tests.py Tue Aug 10 20:55:56 2010
@@ -2694,7 +2694,7 @@ test_list = [ None,
               pull_in_tree_with_depth_option,
               fold_tree_with_unversioned_modified_items,
               depth_empty_update_on_file,
-              XFail(excluded_path_update_operation),
+              excluded_path_update_operation,
               excluded_path_misc_operation,
               excluded_receive_remote_removal,
               exclude_keeps_hidden_entries,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/diff_tests.py Tue Aug 10 20:55:56 2010
@@ -698,8 +698,7 @@ def dont_diff_binary_file(sbox):
   wc_dir = sbox.wc_dir
 
   # Add a binary file to the project.
-  theta_contents = svntest.main.file_read(
-    os.path.join(sys.path[0], "theta.bin"), 'rb')
+  theta_contents = open(os.path.join(sys.path[0], "theta.bin"), 'rb').read()
   # Write PNG file data into 'A/theta'.
   theta_path = os.path.join(wc_dir, 'A', 'theta')
   svntest.main.file_write(theta_path, theta_contents, 'wb')
@@ -2604,6 +2603,9 @@ def diff_in_renamed_folder(sbox):
       'A/D/C' : Item(verb='Adding'),
       'A/D/C/kappa' : Item(verb='Adding'),
   })
+  ### right now, we cannot denote that kappa is a local-add rather than a
+  ### child of the A/D/C copy. thus, it appears in the status output as a
+  ### (M)odified child.
   svntest.actions.run_and_verify_commit(wc_dir, expected_output,
                                         None, None, wc_dir)
 
@@ -2997,7 +2999,7 @@ def diff_external_diffcmd(sbox):
     "iota\t(revision 1)\n",
     "-L\n",
     "iota\t(working copy)\n",
-    os.path.abspath(os.path.join('.svn', 'text-base', 'iota.svn-base')) + "\n",
+    os.path.abspath(svntest.wc.text_base_path("iota")) + "\n",
     os.path.abspath("iota") + "\n"])
 
   # Check that the output of diff corresponds with the expected arguments,
@@ -3229,7 +3231,7 @@ test_list = [ None,
               diff_weird_author,
               diff_ignore_whitespace,
               diff_ignore_eolstyle,
-              diff_in_renamed_folder,
+              XFail(diff_in_renamed_folder),
               diff_with_depth,
               diff_ignore_eolstyle_empty_lines,
               diff_backward_repos_wc_copy,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/externals_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/externals_tests.py Tue Aug 10 20:55:56 2010
@@ -162,27 +162,13 @@ def externals_test_setup(sbox):
   externals_desc = \
            external_url_for["A/B/gamma"] + " gamma\n"
 
-  (fd, tmp_f) = tempfile.mkstemp(dir=wc_init_dir)
-  svntest.main.file_append(tmp_f, externals_desc)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'pset',
-                                     '-F', tmp_f, 'svn:externals', B_path)
-
-  os.close(fd)
-  os.remove(tmp_f)
+  change_external(B_path, externals_desc, commit=False)
 
   externals_desc = \
            "exdir_G       " + external_url_for["A/C/exdir_G"] + "\n" + \
            external_url_for["A/C/exdir_H"] + " exdir_H\n"
 
-  (fd, tmp_f) = tempfile.mkstemp(dir=wc_init_dir)
-  svntest.main.file_append(tmp_f, externals_desc)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'pset',
-                                     '-F', tmp_f, 'svn:externals', C_path)
-
-  os.close(fd)
-  os.remove(tmp_f)
+  change_external(C_path, externals_desc, commit=False)
 
   external_url_for["A/D/exdir_A"]    = "^/../" + other_repo_basename + "/A"
   external_url_for["A/D/exdir_A/G/"] = scheme_relative_other_repo_url + \
@@ -200,11 +186,7 @@ def externals_test_setup(sbox):
            external_url_for["A/D/x/y/z/blah"] + " x/y/z/blah"    + \
            "\n"
 
-  svntest.main.file_append(tmp_f, externals_desc)
-  svntest.actions.run_and_verify_svn(None, None, [], 'pset',
-                                     '-F', tmp_f, 'svn:externals', D_path)
-
-  os.remove(tmp_f)
+  change_external(D_path, externals_desc, commit=False)
 
   # Commit the property changes.
 
@@ -224,15 +206,26 @@ def externals_test_setup(sbox):
 
   return external_url_for
 
-def change_external(path, new_val):
+def change_external(path, new_val, commit=True):
   """Change the value of the externals property on PATH to NEW_VAL,
-  and commit the change."""
+  and commit the change unless COMMIT is False."""
   (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
   svntest.main.file_append(tmp_f, new_val)
   svntest.actions.run_and_verify_svn(None, None, [], 'pset',
                                      '-F', tmp_f, 'svn:externals', path)
-  svntest.actions.run_and_verify_svn(None, None, [], 'ci',
-                                     '-m', 'log msg', '--quiet', path)
+  if commit:
+    svntest.actions.run_and_verify_svn(None, None, [], 'ci',
+                                       '-m', 'log msg', '--quiet', path)
+  os.close(fd)
+  os.remove(tmp_f)
+
+def change_external_expect_error(path, new_val, expected_err):
+  """Try to change the value of the externals property on PATH to NEW_VAL,
+  but expect to get an error message that matches EXPECTED_ERR."""
+  (fd, tmp_f) = tempfile.mkstemp(dir=svntest.main.temp_dir)
+  svntest.main.file_append(tmp_f, new_val)
+  svntest.actions.run_and_verify_svn(None, None, expected_err, 'pset',
+                                     '-F', tmp_f, 'svn:externals', path)
   os.close(fd)
   os.remove(tmp_f)
 
@@ -303,9 +296,7 @@ def checkout_with_externals(sbox):
                           "This is the file 'omega'.\n"),
                          (os.path.join(wc_dir, "A", "B", "gamma"),
                           "This is the file 'gamma'.\n")):
-    fp = open(path, 'r')
-    lines = fp.readlines()
-    if not ((len(lines) == 1) and (lines[0] == contents)):
+    if open(path).read() != contents:
       raise svntest.Failure("Unexpected contents for rev 1 of " + path)
 
 #----------------------------------------------------------------------
@@ -566,14 +557,11 @@ def update_receive_change_under_external
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
 
   external_gamma_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'D', 'gamma')
-  fp = open(external_gamma_path, 'r')
-  lines = fp.readlines()
-  if not ((len(lines) == 2)
-          and (lines[0] == "This is the file 'gamma'.\n")
-          and (lines[1] == "New text in other gamma.\n")):
+  contents = open(external_gamma_path).read()
+  if contents != ("This is the file 'gamma'.\n"
+                  "New text in other gamma.\n"):
     raise svntest.Failure("Unexpected contents for externally modified " +
                           external_gamma_path)
-  fp.close()
 
   # Commit more modifications
   other_rho_path = os.path.join(other_wc_dir, 'A', 'D', 'G', 'rho')
@@ -594,14 +582,11 @@ def update_receive_change_under_external
                                      'up', os.path.join(wc_dir, "A", "C"))
 
   external_rho_path = os.path.join(wc_dir, 'A', 'C', 'exdir_G', 'rho')
-  fp = open(external_rho_path, 'r')
-  lines = fp.readlines()
-  if not ((len(lines) == 2)
-          and (lines[0] == "This is the file 'rho'.\n")
-          and (lines[1] == "New text in other rho.\n")):
+  contents = open(external_rho_path).read()
+  if contents != ("This is the file 'rho'.\n"
+                  "New text in other rho.\n"):
     raise svntest.Failure("Unexpected contents for externally modified " +
                           external_rho_path)
-  fp.close()
 
 #----------------------------------------------------------------------
 
@@ -627,13 +612,7 @@ def modify_and_update_receive_new_extern
           "exdir_Z      " + external_url_for["A/D/exdir_A/H"] + \
           "\n"
 
-  (fd, tmp_f) = tempfile.mkstemp()
-  svntest.main.file_append(tmp_f, externals_desc)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'pset', '-F', tmp_f,
-                                     'svn:externals', B_path)
-  os.close(fd)
-  os.remove(tmp_f)
+  change_external(B_path, externals_desc, commit=False)
 
   # Now cd into A/B and try updating
   was_cwd = os.getcwd()
@@ -664,15 +643,9 @@ def disallow_dot_or_dotdot_directory_ref
 
   # Try to set illegal externals in the original WC.
   def set_externals_for_path_expect_error(path, val):
-    (fd, tmp_f) = tempfile.mkstemp()
-    svntest.main.file_append(tmp_f, val)
     expected_err = ".*Invalid svn:externals property on '.*': target " + \
                    "'.*' is an absolute path or involves '..'.*"
-    svntest.actions.run_and_verify_svn(None, None, expected_err,
-                                       'pset', '-F', tmp_f,
-                                       'svn:externals', path)
-    os.close(fd)
-    os.remove(tmp_f)
+    change_external_expect_error(path, val, expected_err)
 
   B_path = os.path.join(wc_dir, 'A', 'B')
   G_path = os.path.join(wc_dir, 'A', 'D', 'G')
@@ -745,18 +718,15 @@ def export_with_externals(sbox):
 
   # Pick some files, make sure their contents are as expected.
   exdir_G_pi_path = os.path.join(wc_dir, "A", "C", "exdir_G", "pi")
-  fp = open(exdir_G_pi_path, 'r')
-  lines = fp.readlines()
-  if not ((len(lines) == 2) \
-          and (lines[0] == "This is the file 'pi'.\n") \
-          and (lines[1] == "Added to pi in revision 3.\n")):
+  contents = open(exdir_G_pi_path).read()
+  if contents != ("This is the file 'pi'.\n"
+                  "Added to pi in revision 3.\n"):
     raise svntest.Failure("Unexpected contents for rev 1 of " +
                           exdir_G_pi_path)
 
   exdir_H_omega_path = os.path.join(wc_dir, "A", "C", "exdir_H", "omega")
-  fp = open(exdir_H_omega_path, 'r')
-  lines = fp.readlines()
-  if not ((len(lines) == 1) and (lines[0] == "This is the file 'omega'.\n")):
+  contents = open(exdir_H_omega_path).read()
+  if contents != "This is the file 'omega'.\n":
     raise svntest.Failure("Unexpected contents for rev 1 of " +
                           exdir_H_omega_path)
 
@@ -842,13 +812,10 @@ def external_with_peg_and_op_revision(sb
                                      'up', wc_dir)
 
   external_chi_path = os.path.join(wc_dir, 'A', 'D', 'exdir_A', 'H', 'chi')
-  fp = open(external_chi_path, 'r')
-  lines = fp.readlines()
-  if not ((len(lines) == 1)
-          and (lines[0] == "This is the file 'chi'.\n")):
+  contents = open(external_chi_path).read()
+  if contents != "This is the file 'chi'.\n":
     raise svntest.Failure("Unexpected contents for externally modified " +
                           external_chi_path)
-  fp.close()
 
 #----------------------------------------------------------------------
 
@@ -882,9 +849,8 @@ def new_style_externals(sbox):
 
   for dir_name in ["exdir_H", "exdir_I"]:
     exdir_X_omega_path = os.path.join(wc_dir, "A", "C", dir_name, "omega")
-    fp = open(exdir_X_omega_path, 'r')
-    lines = fp.readlines()
-    if not ((len(lines) == 1) and (lines[0] == "This is the file 'omega'.\n")):
+    contents = open(exdir_X_omega_path).read()
+    if contents != "This is the file 'omega'.\n":
       raise svntest.Failure("Unexpected contents for rev 1 of " +
                             exdir_X_omega_path)
 
@@ -917,36 +883,16 @@ def disallow_propset_invalid_formatted_e
                'arg1 -r1',
                'arg1 -r 1',
                ]:
-    (fd, tmp_f) = tempfile.mkstemp()
-    svntest.main.file_append(tmp_f, ext)
-    svntest.actions.run_and_verify_svn("No error for externals '%s'" % ext,
-                                       None,
-                                       '.*Error parsing svn:externals.*',
-                                       'propset',
-                                       '-F',
-                                       tmp_f,
-                                       'svn:externals',
-                                       A_path)
-    os.close(fd)
-    os.remove(tmp_f)
+    change_external_expect_error(A_path, ext,
+                                 '.*Error parsing svn:externals.*')
 
   for ext in [ '-r abc arg1 arg2',
                '-rabc arg1 arg2',
                'arg1 -r abc arg2',
                'arg1 -rabc arg2',
                ]:
-    (fd, tmp_f) = tempfile.mkstemp()
-    svntest.main.file_append(tmp_f, ext)
-    svntest.actions.run_and_verify_svn("No error for externals '%s'" % ext,
-                                       None,
-                                       '.*Error parsing svn:externals.*',
-                                       'propset',
-                                       '-F',
-                                       tmp_f,
-                                       'svn:externals',
-                                       A_path)
-    os.close(fd)
-    os.remove(tmp_f)
+    change_external_expect_error(A_path, ext,
+                                 '.*Error parsing svn:externals.*')
 
   for ext in [ 'http://example.com/ http://example.com/',
                '-r1 http://example.com/ http://example.com/',
@@ -954,38 +900,18 @@ def disallow_propset_invalid_formatted_e
                'http://example.com/ -r1 http://example.com/',
                'http://example.com/ -r 1 http://example.com/',
                ]:
-    (fd, tmp_f) = tempfile.mkstemp()
-    svntest.main.file_append(tmp_f, ext)
-    svntest.actions.run_and_verify_svn("No error for externals '%s'" % ext,
-                                       None,
-                                       '.*cannot use two absolute URLs.*',
-                                       'propset',
-                                       '-F',
-                                       tmp_f,
-                                       'svn:externals',
-                                       A_path)
-    os.close(fd)
-    os.remove(tmp_f)
+    change_external_expect_error(A_path, ext,
+                                 '.*cannot use two absolute URLs.*')
 
   for ext in [ 'http://example.com/ -r1 foo',
                'http://example.com/ -r 1 foo',
                '-r1 foo http://example.com/',
                '-r 1 foo http://example.com/'
                ]:
-    (fd, tmp_f) = tempfile.mkstemp()
-    svntest.main.file_append(tmp_f, ext)
-    svntest.actions.run_and_verify_svn("No error for externals '%s'" % ext,
-                                       None,
-                                       '.*cannot use a URL \'.*\' as the ' \
-                                         'target directory for an external ' \
-                                         'definition.*',
-                                       'propset',
-                                       '-F',
-                                       tmp_f,
-                                       'svn:externals',
-                                       A_path)
-    os.close(fd)
-    os.remove(tmp_f)
+    change_external_expect_error(A_path, ext,
+                                 '.*cannot use a URL \'.*\' as the ' \
+                                   'target directory for an external ' \
+                                   'definition.*')
 
 #----------------------------------------------------------------------
 
@@ -1114,14 +1040,10 @@ def can_place_file_external_into_dir_ext
                                      repo_url, wc_dir)
 
   beta1_path = os.path.join(wc_dir, 'A', 'B', 'E', 'beta')
-  f = open(beta1_path)
-  beta1_contents = f.read()
-  f.close()
+  beta1_contents = open(beta1_path).read()
 
   beta2_path = os.path.join(wc_dir, 'A', 'D-copy', 'G', 'beta')
-  f = open(beta2_path)
-  beta2_contents = f.read()
-  f.close()
+  beta2_contents = open(beta2_path).read()
 
   if beta1_contents != beta2_contents:
       raise svntest.Failure("Contents of '%s' and '%s' do not match" %
@@ -1177,8 +1099,7 @@ def binary_file_externals(sbox):
   wc_dir = sbox.wc_dir
 
   # Add a binary file A/theta, write PNG file data into it.
-  theta_contents = svntest.main.file_read(
-    os.path.join(sys.path[0], "theta.bin"), 'rb')
+  theta_contents = open(os.path.join(sys.path[0], "theta.bin"), 'rb').read()
   theta_path = os.path.join(wc_dir, 'A', 'theta')
   svntest.main.file_write(theta_path, theta_contents, 'wb')
 
@@ -1334,9 +1255,6 @@ def switch_relative_external(sbox):
   ext_path = os.path.join(D_path, 'ext')
   externals_prop = "../B ext\n"
   change_external(D_path, externals_prop)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'ci', '-m', 'log msg',
-                                     '--quiet', wc_dir)
 
   # Update our working copy, and create a "branch" (A => A_copy)
   svntest.actions.run_and_verify_svn(None, None, [], 'up',
@@ -1425,11 +1343,7 @@ def relegate_external(sbox):
 
   # point external to the other repository
   externals_desc = other_repo_url + '/A/B/E        external\n'
-  (fd, tmp_f) = tempfile.mkstemp()
-  svntest.main.file_append(tmp_f, externals_desc)
-  svntest.actions.run_and_verify_svn(None, None, [],
-                                     'pset', '-F', tmp_f,
-                                     'svn:externals', A_path)
+  change_external(A_path, externals_desc, commit=False)
 
   # Update "relegates", i.e. throws-away and recreates, the external
   expected_output = svntest.wc.State(wc_dir, {

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Tue Aug 10 20:55:56 2010
@@ -53,6 +53,27 @@ Valid options:
   --with-all-revprops      : retrieve all revision properties
   --with-no-revprops       : retrieve no revision properties
   --with-revprop ARG       : retrieve revision property ARG
+  --show-diff              : produce diff output
+                             [alias: --diff]
+  --diff-cmd ARG           : use ARG as diff command
+  --internal-diff          : override diff-cmd specified in config file
+                             [alias: --idiff]
+  -x [--extensions] ARG    : Default: '-u'. When Subversion is invoking an
+                             external diff program, ARG is simply passed along
+                             to the program. But when Subversion is using its
+                             default internal diff implementation, or when
+                             Subversion is displaying blame annotations, ARG
+                             could be any of the following:
+                                -u (--unified):
+                                   Output 3 lines of unified context.
+                                -b (--ignore-space-change):
+                                   Ignore changes in the amount of white space.
+                                -w (--ignore-all-space):
+                                   Ignore all white space.
+                                --ignore-eol-style:
+                                   Ignore changes in EOL style.
+                                -p (--show-c-function):
+                                   Show C function name in diff output.
 
 Global options:
   --username ARG           : specify a username ARG

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/lock_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/lock_tests.py Tue Aug 10 20:55:56 2010
@@ -1472,6 +1472,43 @@ def lock_path_not_in_head(sbox):
   svntest.actions.run_and_verify_svn2(None, None, expected_lock_fail_err_re,
                                       0, 'lock', lambda_path)
 
+def verify_path_escaping(sbox):
+  "verify escaping of lock paths"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # 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')
+
+  svntest.main.file_write(file1, 'File 1')
+  svntest.main.file_write(file2, 'File 2')
+  svntest.main.file_write(file3, 'File 3')
+
+  svntest.main.run_svn(None, 'add', file1, file2, file3)
+
+  svntest.main.run_svn(None, 'ci', '-m', 'commit', wc_dir)
+
+  svntest.main.run_svn(None, 'lock', '-m', 'lock 1', file1)
+  svntest.main.run_svn(None, 'lock', '-m', 'lock 2', sbox.repo_url + '/file%20%232')
+  svntest.main.run_svn(None, 'lock', '-m', 'lock 3', file3)
+  svntest.main.run_svn(None, 'unlock', sbox.repo_url + '/file%20%233')
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add(
+    {
+      'file #1'           : Item(status='  ', writelocked='K', wc_rev='2'),
+      'file #2'           : Item(status='  ', writelocked='O', wc_rev='2'),
+      'file #3'           : Item(status='  ', writelocked='B', wc_rev='2')
+    });
+
+  # Make sure the file locking is reported correctly
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
 ########################################################################
 # Run the tests
 
@@ -1515,6 +1552,7 @@ test_list = [ None,
               lock_funky_comment_chars,
               lock_twice_in_one_wc,
               lock_path_not_in_head,
+              verify_path_escaping,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/merge_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/merge_authz_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/merge_authz_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/merge_authz_tests.py Tue Aug 10 20:55:56 2010
@@ -224,7 +224,6 @@ def mergeinfo_and_skipped_paths(sbox):
   # parent of a missing child and the sibling of missing child, but the former
   # always takes precedence in terms of getting *non*-inheritable mergeinfo.
   expected_output = wc.State(A_COPY_2_path, {
-    'D/G'       : Item(status='  ', treeconflict='C'),
     'D/H/omega' : Item(status='U '),
     })
   expected_mergeinfo_output = wc.State(A_COPY_2_path, {
@@ -238,7 +237,6 @@ def mergeinfo_and_skipped_paths(sbox):
     })
   expected_status = wc.State(A_COPY_2_path, {
     ''          : Item(status=' M', wc_rev=8),
-    'D/G'       : Item(status='! ', treeconflict='C'),
     'D/H/chi'   : Item(status='  ', wc_rev=8),
     'D/H/omega' : Item(status='MM', wc_rev=8),
     'D/H'       : Item(status=' M', wc_rev=8),
@@ -272,6 +270,7 @@ def mergeinfo_and_skipped_paths(sbox):
     })
   expected_skip = wc.State(A_COPY_2_path, {
     'B/E'     : Item(),
+    'D/G'       : Item(),
     'D/H/psi'   : Item(),
     })
   saved_cwd = os.getcwd()
@@ -577,6 +576,130 @@ def merge_fails_if_subtree_is_deleted_on
     [], 'merge', '-r1:6', '--force',
     A_url, Acopy_path)
 
+def reintegrate_fails_if_no_root_access(sbox):
+  "reintegrate fails if no root access"
+
+  # If a user is authorized to a reintegrate source and target, they
+  # should be able to reintegrate, regardless of what authorization
+  # they have to parents of the source and target.
+  #
+  # See http://subversion.tigris.org/issues/show_bug.cgi?id=3242#desc78
+
+  # Some paths we'll care about
+  wc_dir = sbox.wc_dir
+  A_path          = os.path.join(wc_dir, 'A')
+  A_COPY_path     = os.path.join(wc_dir, 'A_COPY')
+  beta_COPY_path  = os.path.join(wc_dir, 'A_COPY', 'B', 'E', 'beta')
+  rho_COPY_path   = os.path.join(wc_dir, 'A_COPY', 'D', 'G', 'rho')
+  omega_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'omega')
+  psi_COPY_path   = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'psi')
+      
+  # Copy A@1 to A_COPY in r2, and then make some changes to A in r3-6.
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  expected_disk, expected_status = set_up_branch(sbox)
+
+  # Make a change on the branch, to A_COPY/mu, commit in r7.
+  svntest.main.file_write(os.path.join(wc_dir, "A_COPY", "mu"),
+                          "Changed on the branch.")
+  expected_output = wc.State(wc_dir, {'A_COPY/mu' : Item(verb='Sending')})
+  expected_status.tweak('A_COPY/mu', wc_rev=7)
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None, wc_dir)
+  expected_disk.tweak('A_COPY/mu', contents='Changed on the branch.')
+
+  # Update the WC.
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+
+  # Sync A_COPY with A.
+  expected_output = expected_merge_output([[2,7]],
+                                          ['U    ' + beta_COPY_path  + '\n',
+                                           'U    ' + rho_COPY_path   + '\n',
+                                           'U    ' + omega_COPY_path + '\n',
+                                           'U    ' + psi_COPY_path   + '\n',
+                                           # Mergeinfo notification
+                                           ' U   ' + A_COPY_path     + '\n'])
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge',
+                                     sbox.repo_url + '/A', A_COPY_path)
+  svntest.main.run_svn(None, 'ci', '-m', 'synch A_COPY with A', wc_dir)
+
+  # Update so we are ready for reintegrate.
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # Change authz file so everybody has access to everything but the root.  
+  if is_ra_type_svn() or is_ra_type_dav():
+    write_restrictive_svnserve_conf(sbox.repo_dir)
+    write_authz_file(sbox, {"/"       : "* =",
+                            "/A"      : "* = rw",
+                            "/A_COPY" : "* = rw",
+                            "/iota"   : "* = rw"})
+
+  # Now reintegrate A_COPY back to A.  The lack of access to the root of the
+  # repository shouldn't be a problem.
+  expected_output = wc.State(A_path, {
+    'mu'           : Item(status='U '),
+    })
+  expected_mergeinfo_output = wc.State(A_path, {
+    '' : Item(status=' G'),
+    })
+  expected_elision_output = wc.State(A_path, {
+    })
+  expected_disk = wc.State('', {
+    ''          : Item(props={SVN_PROP_MERGEINFO : '/A_COPY:2-8'}),
+    'B'         : Item(),
+    'B/lambda'  : Item("This is the file 'lambda'.\n"),
+    'B/E'       : Item(),
+    'B/E/alpha' : Item("This is the file 'alpha'.\n"),
+    'B/E/beta'  : Item("New content"),
+    'B/F'       : Item(),
+    'mu'        : Item("Changed on the branch."),
+    'C'         : Item(),
+    'D'         : Item(),
+    'D/gamma'   : Item("This is the file 'gamma'.\n"),
+    'D/G'       : Item(),
+    'D/G/pi'    : Item("This is the file 'pi'.\n"),
+    'D/G/rho'   : Item("New content"),
+    'D/G/tau'   : Item("This is the file 'tau'.\n"),
+    'D/H'       : Item(),
+    'D/H/chi'   : Item("This is the file 'chi'.\n"),
+    'D/H/omega' : Item("New content"),
+    'D/H/psi'   : Item("New content"),
+  })
+  expected_status = wc.State(A_path, {
+    "B"            : Item(status='  ', wc_rev=8),
+    "B/lambda"     : Item(status='  ', wc_rev=8),
+    "B/E"          : Item(status='  ', wc_rev=8),
+    "B/E/alpha"    : Item(status='  ', wc_rev=8),
+    "B/E/beta"     : Item(status='  ', wc_rev=8),
+    "B/F"          : Item(status='  ', wc_rev=8),
+    "mu"           : Item(status='M ', wc_rev=8),
+    "C"            : Item(status='  ', wc_rev=8),
+    "D"            : Item(status='  ', wc_rev=8),
+    "D/gamma"      : Item(status='  ', wc_rev=8),
+    "D/G"          : Item(status='  ', wc_rev=8),
+    "D/G/pi"       : Item(status='  ', wc_rev=8),
+    "D/G/rho"      : Item(status='  ', wc_rev=8),
+    "D/G/tau"      : Item(status='  ', wc_rev=8),
+    "D/H"          : Item(status='  ', wc_rev=8),
+    "D/H/chi"      : Item(status='  ', wc_rev=8),
+    "D/H/omega"    : Item(status='  ', wc_rev=8),
+    "D/H/psi"      : Item(status='  ', wc_rev=8),
+    ""             : Item(status=' M', wc_rev=8),
+  })
+  expected_skip = wc.State(A_path, {})
+  svntest.actions.run_and_verify_merge(A_path, None, None,
+                                       sbox.repo_url + '/A_COPY', None,
+                                       expected_output,
+                                       expected_mergeinfo_output,
+                                       expected_elision_output,
+                                       expected_disk,
+                                       expected_status,
+                                       expected_skip,
+                                       None, None, None, None,
+                                       None, True, True,
+                                       '--reintegrate')
+  
 ########################################################################
 # Run the tests
 
@@ -588,6 +711,9 @@ test_list = [ None,
                          svntest.main.server_has_mergeinfo),
               SkipUnless(merge_fails_if_subtree_is_deleted_on_src,
                          server_has_mergeinfo),
+              SkipUnless(Skip(reintegrate_fails_if_no_root_access,
+                              svntest.main.is_ra_type_file),
+                         svntest.main.server_has_mergeinfo),
              ]
 
 if __name__ == '__main__':