subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From phi...@apache.org
Subject svn commit: r1227105 [8/8] - in /subversion/branches/moves-scan-log: ./ notes/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/swig/ruby/test/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ su...
Date Wed, 04 Jan 2012 10:30:19 GMT
Modified: subversion/branches/moves-scan-log/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/cl.h?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/cl.h (original)
+++ subversion/branches/moves-scan-log/subversion/svn/cl.h Wed Jan  4 10:30:16 2012
@@ -825,6 +825,23 @@ svn_cl__local_style_skip_ancestor(const 
                                   const char *path,
                                   apr_pool_t *pool);
 
+/* Check that PATH_OR_URL1@REVISION1 is related to PATH_OR_URL2@REVISION2.
+ * Raise an error if not.
+ *
+ * ### Ideally we would also check that they are on different lines of
+ * history.  That is easy in common cases, but to give a correct answer in
+ * general we need to know the operative revision(s) as well.  For example,
+ * when one location is the branch point from which the other branch was
+ * copied.
+ */
+svn_error_t *
+svn_cl__check_related_source_and_target(const char *path_or_url1,
+                                        const svn_opt_revision_t *revision1,
+                                        const char *path_or_url2,
+                                        const svn_opt_revision_t *revision2,
+                                        svn_client_ctx_t *ctx,
+                                        apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/moves-scan-log/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/log-cmd.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/log-cmd.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/log-cmd.c Wed Jan  4 10:30:16 2012
@@ -274,6 +274,9 @@ log_entry_receiver(void *baton,
       SVN_ERR(svn_cmdline_printf(pool, "\n%s\n", message));
     }
 
+  SVN_ERR(svn_cmdline_fflush(stdout));
+  SVN_ERR(svn_cmdline_fflush(stderr));
+
   /* Print a diff if requested. */
   if (lb->show_diff)
     {
@@ -298,7 +301,7 @@ log_entry_receiver(void *baton,
       end_revision.kind = svn_opt_revision_number;
       end_revision.value.number = log_entry->revision;
 
-      SVN_ERR(svn_cmdline_printf(pool, _("\n")));
+      SVN_ERR(svn_stream_printf(outstream, pool, _("\n")));
       SVN_ERR(svn_client_diff_peg6(diff_options,
                                    lb->target_path_or_url,
                                    &lb->target_peg_revision,
@@ -315,12 +318,11 @@ log_entry_receiver(void *baton,
                                    errstream,
                                    NULL,
                                    lb->ctx, pool));
-      SVN_ERR(svn_cmdline_printf(pool, _("\n")));
+      SVN_ERR(svn_stream_printf(outstream, pool, _("\n")));
+      SVN_ERR(svn_stream_close(outstream));
+      SVN_ERR(svn_stream_close(errstream));
     }
 
-  SVN_ERR(svn_cmdline_fflush(stdout));
-  SVN_ERR(svn_cmdline_fflush(stderr));
-
   if (log_entry->has_children)
     APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
 

Modified: subversion/branches/moves-scan-log/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/main.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/main.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/main.c Wed Jan  4 10:30:16 2012
@@ -55,7 +55,6 @@
 #include "cl.h"
 
 #include "private/svn_opt_private.h"
-#include "private/svn_wc_private.h"
 #include "private/svn_cmdline_private.h"
 
 #include "svn_private_config.h"
@@ -666,7 +665,11 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    svn log bar.c@42\n"
      "    svn log http://www.example.com/repo/project/foo.c\n"
      "    svn log http://www.example.com/repo/project foo.c bar.c\n"
-     "    svn log http://www.example.com/repo/project@50 foo.c bar.c\n"),
+     "    svn log http://www.example.com/repo/project@50 foo.c bar.c\n"
+     "\n"
+     "    This command shows the log entry for the revision the branch\n"
+     "    ^/branches/foo was created in:\n"
+     "      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo\n"),
     {'r', 'q', 'v', 'g', 'c', opt_targets, opt_stop_on_copy, opt_incremental,
      opt_xml, 'l', opt_with_all_revprops, opt_with_no_revprops, opt_with_revprop,
      opt_depth, opt_diff, opt_diff_cmd, opt_internal_diff, 'x'},
@@ -910,8 +913,10 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "     directly related -- one is not a direct copy of the other. A 2-URL\n"
 "     merge is necessary.\n"
 "\n"
-"     The 'bar' branch has been synced with trunk up to revision 500. So the\n"
-"     difference between trunk@500 and bar@HEAD contains the complete\n"
+"     The 'bar' branch has been synced with trunk up to revision 500.\n"
+"     (If this revision number is not known, it can be located using the\n"
+"     'svn log' and/or 'svn mergeinfo' commands.)\n"
+"     The difference between trunk@500 and bar@HEAD contains the complete\n"
 "     set of changes related to feature 'bar', and no other changes. These\n"
 "     changes are applied to the 'foo' branch.\n"
 "\n"
@@ -941,14 +946,6 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "\n"
 "         svn diff ^/trunk@500 ^/bar@HEAD\n"
 "\n"
-"     Note that a 2-URL merge can also merge from foreign repositories.\n"
-"     While SOURCE1 and SOURCE2 must both come from the same repository,\n"
-"     TARGET_WCPATH may come from a different repository than the sources.\n"
-"     However, there are some caveats. Most notably, copies made in the\n"
-"     merge source will be transformed into plain additions in the merge\n"
-"     target. Also, merge-tracking is not supported when foreign\n"
-"     repositories are involved.\n"
-"\n"
 "\n"
 "  The following applies to all types of merges:\n"
 "\n"
@@ -993,7 +990,17 @@ const svn_opt_subcommand_desc2_t svn_cl_
 "  reintegrate merges.\n"
 "\n"
 "  The --ignore-ancestry option prevents merge tracking and thus ignores\n"
-"  mergeinfo, neither considering it nor recording it.\n"),
+"  mergeinfo, neither considering it nor recording it.\n"
+"\n"
+"    - Merging from foreign repositories -\n"
+"\n"
+"  Subversion does support merging from foreign repositories.\n"
+"  While all merge source URLs must point to the same repository, the merge\n"
+"  target working copy may come from a different repository than the source.\n"
+"  However, there are some caveats. Most notably, copies made in the\n"
+"  merge source will be transformed into plain additions in the merge\n"
+"  target. Also, merge-tracking is not supported for merges from foreign\n"
+"  repositories.\n"),
     {'r', 'c', 'N', opt_depth, 'q', opt_force, opt_dry_run, opt_merge_cmd,
      opt_record_only, 'x', opt_ignore_ancestry, opt_accept, opt_reintegrate,
      opt_allow_mixed_revisions} },
@@ -2689,6 +2696,15 @@ main(int argc, const char *argv[])
                                      _("Please see the 'svn upgrade' command"));
         }
 
+      /* Tell the user about 'svn cleanup' if any error on the stack
+         was about locked working copies. */
+      if (svn_error_find_cause(err, SVN_ERR_WC_LOCKED))
+        {
+          err = svn_error_quick_wrap(
+                  err, _("Run 'svn cleanup' to remove locks "
+                         "(type 'svn help cleanup' for details)"));
+        }
+
       /* Issue #3014:
        * Don't print anything on broken pipes. The pipe was likely
        * closed by the process at the other end. We expect that
@@ -2699,14 +2715,6 @@ main(int argc, const char *argv[])
       if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
         svn_handle_error2(err, stderr, FALSE, "svn: ");
 
-      /* Tell the user about 'svn cleanup' if any error on the stack
-         was about locked working copies. */
-      if (svn_error_find_cause(err, SVN_ERR_WC_LOCKED))
-        svn_error_clear(svn_cmdline_fputs(_("svn: run 'svn cleanup' to "
-                                            "remove locks (type 'svn help "
-                                            "cleanup' for details)\n"),
-                                          stderr, pool));
-
       svn_error_clear(err);
       svn_pool_destroy(pool);
       return EXIT_FAILURE;

Modified: subversion/branches/moves-scan-log/subversion/svn/merge-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/merge-cmd.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/merge-cmd.c Wed Jan  4 10:30:16 2012
@@ -39,6 +39,63 @@
 
 /*** Code. ***/
 
+/* Do a reintegrate merge from SOURCE_PATH_OR_URL@SOURCE_PEG_REVISION into
+ * TARGET_WCPATH.  Do it with a WC write lock unless DRY_RUN is true. */
+static svn_error_t *
+merge_reintegrate(const char *source_path_or_url,
+                  const svn_opt_revision_t *source_peg_revision,
+                  const char *target_wcpath,
+                  svn_boolean_t dry_run,
+                  const apr_array_header_t *merge_options,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *scratch_pool)
+{
+  const char *url1, *url2;
+  svn_revnum_t rev1, rev2;
+
+  SVN_ERR(svn_client_find_reintegrate_merge(
+            &url1, &rev1, &url2, &rev2,
+            source_path_or_url, source_peg_revision, target_wcpath,
+            ctx, scratch_pool, scratch_pool));
+
+  if (url1)
+    {
+      svn_opt_revision_t revision1 = { svn_opt_revision_number, { rev1 } };
+      svn_opt_revision_t revision2 = { svn_opt_revision_number, { rev2 } };
+
+      /* Do the merge.  Set 'allow_mixed_rev' to true, not because we want
+       * to allow a mixed-rev WC but simply to bypass the check, as it was
+       * already checked in svn_client_find_reintegrate_merge(). */
+      SVN_ERR(svn_client_merge4(url1, &revision1, url2, &revision2,
+                                target_wcpath, svn_depth_infinity,
+                                FALSE /* ignore_ancestry */,
+                                FALSE /* force */,
+                                FALSE /* record_only */,
+                                dry_run, TRUE /* allow_mixed_rev */,
+                                merge_options, ctx, scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Throw an error if PATH_OR_URL is a path and REVISION isn't a repository
+ * revision. */
+static svn_error_t *
+ensure_wc_path_has_repo_revision(const char *path_or_url,
+                                 const svn_opt_revision_t *revision,
+                                 apr_pool_t *scratch_pool)
+{
+  if (revision->kind != svn_opt_revision_number
+      && revision->kind != svn_opt_revision_date
+      && revision->kind != svn_opt_revision_head
+      && ! svn_path_is_url(path_or_url))
+    return svn_error_createf(
+      SVN_ERR_CLIENT_BAD_REVISION, NULL,
+      _("Invalid merge source '%s'; a working copy path can only be "
+        "used with a repository revision (a number, a date, or head)"),
+      svn_dirent_local_style(path_or_url, scratch_pool));
+  return SVN_NO_ERROR;
+}
 
 /* This implements the `svn_opt_subcommand_t' interface. */
 svn_error_t *
@@ -55,6 +112,7 @@ svn_cl__merge(apr_getopt_t *os,
   svn_opt_revision_t first_range_start, first_range_end, peg_revision1,
     peg_revision2;
   apr_array_header_t *options, *ranges_to_merge = opt_state->revision_ranges;
+  svn_opt_revision_t unspecified = { svn_opt_revision_unspecified, { 0 } };
 
   /* Merge doesn't support specifying a revision or revision range
      when using --reintegrate. */
@@ -205,16 +263,13 @@ svn_cl__merge(apr_getopt_t *os,
 
       /* Catch 'svn merge wc_path1 wc_path2 [target]' without explicit
          revisions--since it ignores local modifications it may not do what
-         the user expects.  Forcing the user to specify a repository
+         the user expects.  That is, it doesn't read from the WC itself, it
+         reads from the WC's URL.  Forcing the user to specify a repository
          revision should avoid any confusion. */
-      if ((first_range_start.kind == svn_opt_revision_unspecified
-           && ! svn_path_is_url(sourcepath1))
-          ||
-          (first_range_end.kind == svn_opt_revision_unspecified
-           && ! svn_path_is_url(sourcepath2)))
-        return svn_error_create
-          (SVN_ERR_CLIENT_BAD_REVISION, 0,
-           _("A working copy merge source needs an explicit revision"));
+      SVN_ERR(ensure_wc_path_has_repo_revision(sourcepath1, &first_range_start,
+                                               pool));
+      SVN_ERR(ensure_wc_path_has_repo_revision(sourcepath2, &first_range_end,
+                                               pool));
 
       /* Default peg revisions to each URL's youngest revision. */
       if (first_range_start.kind == svn_opt_revision_unspecified)
@@ -293,11 +348,13 @@ svn_cl__merge(apr_getopt_t *os,
 
   if (opt_state->reintegrate)
     {
-      err = svn_client_merge_reintegrate(sourcepath1,
-                                         &peg_revision1,
-                                         targetpath,
-                                         opt_state->dry_run,
-                                         options, ctx, pool);
+      SVN_ERR_W(svn_cl__check_related_source_and_target(
+                  sourcepath1, &peg_revision1, targetpath, &unspecified,
+                  ctx, pool),
+                _("Source and target must be different but related branches"));
+
+      err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
+                              opt_state->dry_run, options, ctx, pool);
     }
   else if (! two_sources_specified)
     {
@@ -313,6 +370,12 @@ svn_cl__merge(apr_getopt_t *os,
           range->start.value.number = 1;
           range->end = peg_revision1;
           APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = range;
+
+          /* This must be a 'sync' merge so check branch relationship. */
+          SVN_ERR_W(svn_cl__check_related_source_and_target(
+                      sourcepath1, &peg_revision1, targetpath, &unspecified,
+                      ctx, pool),
+                _("Source and target must be different but related branches"));
         }
 
       err = svn_client_merge_peg4(sourcepath1,

Modified: subversion/branches/moves-scan-log/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/mergeinfo-cmd.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/mergeinfo-cmd.c Wed Jan  4 10:30:16 2012
@@ -114,6 +114,11 @@ svn_cl__mergeinfo(apr_getopt_t *os,
         tgt_peg_revision.kind = svn_opt_revision_base;
     }
 
+  SVN_ERR_W(svn_cl__check_related_source_and_target(source, &src_peg_revision,
+                                                    target, &tgt_peg_revision,
+                                                    ctx, pool),
+            _("Source and target must be different but related branches"));
+
   /* Do the real work, depending on the requested data flavor. */
   if (opt_state->show_revs == svn_cl__show_revs_merged)
     {

Modified: subversion/branches/moves-scan-log/subversion/svn/propedit-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/propedit-cmd.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/propedit-cmd.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/propedit-cmd.c Wed Jan  4 10:30:16 2012
@@ -39,8 +39,6 @@
 #include "svn_props.h"
 #include "cl.h"
 
-#include "private/svn_wc_private.h"
-
 #include "svn_private_config.h"
 
 

Modified: subversion/branches/moves-scan-log/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/util.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/util.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/util.c Wed Jan  4 10:30:16 2012
@@ -1423,3 +1423,43 @@ svn_cl__local_style_skip_ancestor(const 
 
   return svn_dirent_local_style(relpath ? relpath : path, pool);
 }
+
+/* Return a string of the form "PATH_OR_URL@REVISION". */
+static const char *
+path_for_display(const char *path_or_url,
+                 const svn_opt_revision_t *revision,
+                 apr_pool_t *pool)
+{
+  const char *rev_str = svn_opt__revision_to_string(revision, pool);
+
+  if (! svn_path_is_url(path_or_url))
+    path_or_url = svn_dirent_local_style(path_or_url, pool);
+  return apr_psprintf(pool, "%s@%s", path_or_url, rev_str);
+}
+
+svn_error_t *
+svn_cl__check_related_source_and_target(const char *path_or_url1,
+                                        const svn_opt_revision_t *revision1,
+                                        const char *path_or_url2,
+                                        const svn_opt_revision_t *revision2,
+                                        svn_client_ctx_t *ctx,
+                                        apr_pool_t *pool)
+{
+  const char *ancestor_url;
+  svn_revnum_t ancestor_rev;
+
+  SVN_ERR(svn_client__youngest_common_ancestor(
+            &ancestor_url, &ancestor_rev,
+            path_or_url1, revision1, path_or_url2, revision2,
+            ctx, pool, pool));
+
+  if (ancestor_url == NULL)
+    {
+      return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                               _("Source and target have no common ancestor: "
+                                 "'%s' and '%s'"),
+                               path_for_display(path_or_url1, revision1, pool),
+                               path_for_display(path_or_url2, revision2, pool));
+    }
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/moves-scan-log/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svnadmin/main.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svnadmin/main.c (original)
+++ subversion/branches/moves-scan-log/subversion/svnadmin/main.c Wed Jan  4 10:30:16 2012
@@ -208,7 +208,7 @@ static const apr_getopt_option_t options
      N_("specify revision number ARG (or X:Y range)")},
 
     {"incremental",   svnadmin__incremental, 0,
-     N_("dump incrementally")},
+     N_("dump or hotcopy incrementally")},
 
     {"deltas",        svnadmin__deltas, 0,
      N_("use deltas in dump output")},
@@ -332,8 +332,10 @@ static const svn_opt_subcommand_desc2_t 
 
   {"hotcopy", subcommand_hotcopy, {0}, N_
    ("usage: svnadmin hotcopy REPOS_PATH NEW_REPOS_PATH\n\n"
-    "Makes a hot copy of a repository.\n"),
-   {svnadmin__clean_logs} },
+    "Makes a hot copy of a repository.\n"
+    "If --incremental is passed, data which already exists at the destination\n"
+    "is not copied again.  Incremental mode is implemented for FSFS repositories.\n"),
+   {svnadmin__clean_logs, svnadmin__incremental} },
 
   {"list-dblogs", subcommand_list_dblogs, {0}, N_
    ("usage: svnadmin list-dblogs REPOS_PATH\n\n"
@@ -1431,8 +1433,9 @@ subcommand_hotcopy(apr_getopt_t *os, voi
   new_repos_path = APR_ARRAY_IDX(targets, 0, const char *);
   SVN_ERR(target_arg_to_dirent(&new_repos_path, new_repos_path, pool));
 
-  return svn_repos_hotcopy(opt_state->repository_path, new_repos_path,
-                           opt_state->clean_logs, pool);
+  return svn_repos_hotcopy2(opt_state->repository_path, new_repos_path,
+                            opt_state->clean_logs, opt_state->incremental,
+                            check_cancel, NULL, pool);
 }
 
 

Modified: subversion/branches/moves-scan-log/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svnsync/sync.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svnsync/sync.c (original)
+++ subversion/branches/moves-scan-log/subversion/svnsync/sync.c Wed Jan  4 10:30:16 2012
@@ -33,9 +33,6 @@
 #include "svn_subst.h"
 #include "svn_string.h"
 
-#include "private/svn_opt_private.h"
-#include "private/svn_cmdline_private.h"
-
 #include "sync.h"
 
 #include "svn_private_config.h"

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/copy_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/copy_tests.py Wed Jan  4 10:30:16 2012
@@ -4654,9 +4654,15 @@ def changed_dir_data_should_match_checko
 
   os.chdir(was_cwd)
   os.chdir(wc_dir)
-  svntest.actions.run_and_verify_svn(None, verify_out, [], 'status', '-v')
+  rv, verify_out2, err = main.run_svn (None, 'status', '-v')
   os.chdir(was_cwd)
 
+  # The order of the status output is not absolutely defined, but
+  # otherwise should match
+  svntest.verify.verify_outputs(None,
+                                sorted(verify_out2), None,
+                                sorted(verify_out), None)
+
 def move_added_nodes(sbox):
   """move added nodes"""
 

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/diff_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/diff_tests.py Wed Jan  4 10:30:16 2012
@@ -57,6 +57,16 @@ def make_diff_header(path, old_tag, new_
     "+++ " + path_as_shown + "\t(" + new_tag + ")\n",
     ]
 
+def make_no_diff_deleted_header(path, old_tag, new_tag):
+  """Generate the expected diff header for a deleted file PATH when in
+  'no-diff-deleted' mode. (In that mode, no further details appear after the
+  header.) Return the header as an array of newline-terminated strings."""
+  path_as_shown = path.replace('\\', '/')
+  return [
+    "Index: " + path_as_shown + " (deleted)\n",
+    "===================================================================\n",
+    ]
+
 def make_git_diff_header(target_path, repos_relpath,
                          old_tag, new_tag, add=False, src_label=None,
                          dst_label=None, delete=False, text_changes=True,

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/externals_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/externals_tests.py Wed Jan  4 10:30:16 2012
@@ -2651,6 +2651,26 @@ def include_immediate_dir_externals(sbox
     None, '--include-externals', '--depth=immediates', X)
 
 
+@Issue(4085)
+@XFail()
+def shadowing(sbox):
+  "external shadows an existing dir"
+
+  sbox.build(read_only=True)
+  wc_dir = sbox.wc_dir
+
+  # Setup external: /A/B/F as 'C' child of /A
+  externals_prop = "^/A/B/F C\n"
+
+  raised = False
+  try:
+    change_external(sbox.ospath('A'), externals_prop, commit=False)
+  except:
+    raised = True
+  if not raised:
+    raise svntest.Failure("Creating conflicting child 'C' of 'A' didn't error")
+
+
 ########################################################################
 # Run the tests
 
@@ -2694,6 +2714,7 @@ test_list = [ None,
               copy_file_externals,
               include_externals,
               include_immediate_dir_externals,
+              shadowing,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Wed Jan  4 10:30:16 2012
@@ -38,6 +38,10 @@ usage: 1. log [PATH][@REV]
     svn log http://www.example.com/repo/project foo.c bar.c
     svn log http://www.example.com/repo/project@50 foo.c bar.c
 
+    This command shows the log entry for the revision the branch
+    ^/branches/foo was created in:
+      svn log --stop-on-copy --limit 1 -r0:HEAD ^/branches/foo
+
 Valid options:
   -r [--revision] ARG      : ARG (some commands also take ARG1:ARG2 range)
                              A revision argument can be one of:

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/input_validation_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/input_validation_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/input_validation_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/input_validation_tests.py Wed Jan  4 10:30:16 2012
@@ -151,13 +151,18 @@ def invalid_log_targets(sbox):
 def invalid_merge_args(sbox):
   "invalid arguments for 'merge'"
   sbox.build(read_only=True)
-  run_and_verify_svn_in_wc(sbox, "svn: E195002: A working copy merge source needs "
-                           "an explicit revision", 'merge', 'iota', '^/')
-  for (src, target) in [('iota@HEAD', '^/'), ('iota@BASE', 'file://')]:
-    run_and_verify_svn_in_wc(sbox, "svn: E205000: Merge sources must both be either "
-                             "paths or URLs", 'merge', src, target)
+  for args in [('iota', 'A/mu@HEAD'),
+               ('iota@BASE', 'A/mu@HEAD')]:
+    run_and_verify_svn_in_wc(sbox, "svn: E195002: .* working copy .* revision",
+                             'merge', *args)
+  for args in [(sbox.repo_url, 'A@1', 'A'),
+               ('^/A', 'A@HEAD', 'A'),
+               ('A@HEAD', '^/A', 'A'),
+               ('A@HEAD', '^/A')]:
+    run_and_verify_svn_in_wc(sbox, "svn: E205000: Merge sources must both "
+                             "be either paths or URLs", 'merge', *args)
   run_and_verify_svn_in_wc(sbox, "svn: E155010: Path '.*' does not exist",
-                           'merge', 'iota@BASE', 'iota@HEAD', 'nonexistent')
+                           'merge', '^/@0', '^/@1', 'nonexistent')
   run_and_verify_svn_in_wc(sbox, "svn: E205000: Too many arguments given",
                           'merge', '-c42', '^/A/B', '^/A/C', 'iota')
   run_and_verify_svn_in_wc(sbox, "svn: E205000: Cannot specify a revision range with" +

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/log_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/log_tests.py Wed Jan  4 10:30:16 2012
@@ -34,6 +34,7 @@ from svntest import wc
 from svntest.main import server_has_mergeinfo
 from svntest.main import SVN_PROP_MERGEINFO
 from merge_tests import set_up_branch
+from diff_tests import make_diff_header, make_no_diff_deleted_header
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -178,7 +179,8 @@ def guarantee_repos_and_wc(sbox):
   to test the code"""
   svntest.main.file_write(msg_file, msg)
   svntest.main.file_append(iota_path, "8")
-  svntest.main.file_append(rho_path, "8")
+  svntest.main.file_append(rho_path, "88") # More than one char so libmagic
+                                           # treats it as text.
   svntest.main.run_svn(None, 'add', rho_path)
   svntest.main.run_svn(None,
                        'ci', '-F', msg_file)
@@ -424,7 +426,7 @@ class SVNLogParseError(Exception):
   pass
 
 
-def parse_log_output(log_lines):
+def parse_log_output(log_lines, with_diffs=False):
   """Return a log chain derived from LOG_LINES.
   A log chain is a list of hashes; each hash represents one log
   message, in the order it appears in LOG_LINES (the first log
@@ -438,6 +440,7 @@ def parse_log_output(log_lines):
      'date'     ===>  string
      'msg'      ===>  string  (the log message itself)
      'lines'    ===>  number  (so that it may be checked against rev)
+
   If LOG_LINES contains changed-path information, then the hash
   also contains
 
@@ -451,7 +454,11 @@ def parse_log_output(log_lines):
 
      'reverse_merges'   ===> list of reverse-merging revisions that resulted
   in this log being part of the list of messages.
-     """
+
+  If LOG_LINES contains diffs and WITH_DIFFS=True, then the hash also contains
+
+     'diff_lines'  ===> list of strings  (diffs)
+  """
 
   # Here's some log output to look at while writing this function:
 
@@ -566,6 +573,20 @@ def parse_log_output(log_lines):
       for line in log_lines[0:lines]:
         msg += line
       del log_lines[0:lines]
+
+      # Maybe accumulate a diff.
+      # If there is a diff, there is a blank line before and after it.
+      if with_diffs and len(log_lines) >= 2 and log_lines[0] == '\n':
+        log_lines.pop(0)
+        diff_lines = []
+        while len(log_lines) and log_lines[0] != msg_separator:
+          diff_lines.append(log_lines.pop(0))
+        if diff_lines[-1] == '\n':
+          diff_lines.pop()
+        else:
+          raise SVNLogParseError("no blank line after diff in log")
+        this_item['diff_lines'] = diff_lines
+
     elif this_line == msg_separator:
       if this_item:
         this_item['msg'] = msg
@@ -2125,11 +2146,25 @@ def log_diff(sbox):
                                                               '-r10:8', 'A2')
   os.chdir(was_cwd)
 
-  for line in output:
-    if line.startswith('Index:'):
-      break
-  else:
-    raise SVNLogParseError("no diffs found in log output")
+  r9diff = make_no_diff_deleted_header('A2/B/E/alpha', 8, 9) \
+           + make_diff_header('A2/B/E/beta', 'revision 8', 'revision 9') \
+           + [ "@@ -1 +1,2 @@\n",
+               " This is the file 'beta'.\n",
+               "+9\n",
+               "\ No newline at end of file\n",
+             ]
+  r8diff = make_diff_header('A2/D/G/rho', 'revision 0', 'revision 8') \
+           + [ "@@ -0,0 +1 @@\n",
+               "+88\n",
+               "\ No newline at end of file\n",
+             ]
+  log_chain = parse_log_output(output, with_diffs=True)
+  if len(log_chain) != 3:
+    raise SVNLogParseError("%d logs found, 3 expected" % len(log_chain))
+  svntest.verify.compare_and_display_lines(None, "diff for r9",
+                                           r9diff, log_chain[1]['diff_lines'])
+  svntest.verify.compare_and_display_lines(None, "diff for r8",
+                                           r8diff, log_chain[2]['diff_lines'])
 
 
 ########################################################################

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_reintegrate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_reintegrate_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_reintegrate_tests.py Wed Jan  4 10:30:16 2012
@@ -2435,7 +2435,7 @@ def reintegrate_replaced_source(sbox):
   # Using cherrypick merges, simulate a series of sync merges from A to
   # A_COPY with a replace of A_COPY along the way.
   #
-  # r6 - Merge r3 from A to A_COPY
+  # r7 - Merge r3 from A to A_COPY
   svntest.main.run_svn(None, 'up', wc_dir)
   svntest.main.run_svn(None, 'merge', sbox.repo_url + '/A', A_COPY_path,
                        '-c3')

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/merge_tests.py Wed Jan  4 10:30:16 2012
@@ -861,7 +861,8 @@ def merge_similar_unrelated_trees(sbox):
 
 #----------------------------------------------------------------------
 def merge_one_file_helper(sbox, arg_flav, record_only = 0):
-  "ARG_FLAV is one of 'r' (revision range) or 'c' (single change)."
+  """ARG_FLAV is one of 'r' (revision range) or 'c' (single change) or
+  '*' (no revision specified)."""
 
   if arg_flav not in ('r', 'c', '*'):
     raise svntest.Failure("Unrecognized flavor of merge argument")
@@ -998,9 +999,13 @@ def merge_record_only(sbox):
   merge_one_file_helper(sbox, 'r', 1)
 
 #----------------------------------------------------------------------
-# This is a regression for the enhancement added in issue #785.
+# This is a regression test for the enhancement added in issue #785 "add
+# friendly enhancement to 'svn merge'", which is about inferring that
+# the default target of "svn merge [-r...] FILE" should not be "." but
+# rather should be "FILE".
 def merge_with_implicit_target_helper(sbox, arg_flav):
-  "ARG_FLAV is one of 'r' (revision range) or 'c' (single change)."
+  """ARG_FLAV is one of 'r' (revision range) or 'c' (single change) or
+  '*' (no revision specified)."""
 
   if arg_flav not in ('r', 'c', '*'):
     raise svntest.Failure("Unrecognized flavor of merge argument")

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/mergeinfo_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/mergeinfo_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/mergeinfo_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/mergeinfo_tests.py Wed Jan  4 10:30:16 2012
@@ -68,8 +68,11 @@ def no_mergeinfo(sbox):
   "'mergeinfo' on a URL that lacks mergeinfo"
 
   sbox.build(create_wc=False)
+  sbox.simple_repo_copy('A', 'A2')
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           [], sbox.repo_url, sbox.repo_url)
+                                           [],
+                                           sbox.repo_url + '/A',
+                                           sbox.repo_url + '/A2')
 
 def mergeinfo(sbox):
   "'mergeinfo' on a path with mergeinfo"
@@ -77,41 +80,65 @@ def mergeinfo(sbox):
   sbox.build()
   wc_dir = sbox.wc_dir
 
+  # make a branch 'A2'
+  sbox.simple_repo_copy('A', 'A2')  # r2
+  # make a change in branch 'A'
+  sbox.simple_mkdir('A/newdir')
+  sbox.simple_commit()  # r3
+  sbox.simple_update()
+
   # Dummy up some mergeinfo.
-  svntest.actions.run_and_verify_svn(None, None, [], 'ps', SVN_PROP_MERGEINFO,
-                                     '/:1', wc_dir)
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'ps', SVN_PROP_MERGEINFO, '/A:3',
+                                     sbox.ospath('A2'))
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           ['1'], sbox.repo_url, wc_dir)
+                                           ['3'],
+                                           sbox.repo_url + '/A',
+                                           sbox.ospath('A2'))
 
 @SkipUnless(server_has_mergeinfo)
 def explicit_mergeinfo_source(sbox):
   "'mergeinfo' with source selection"
 
+  # The idea is the target has mergeinfo pertaining to two or more different
+  # source branches and we're asking about just one of them.
+
   sbox.build()
-  wc_dir = sbox.wc_dir
-  H_path = os.path.join(wc_dir, 'A', 'D', 'H')
-  H2_path = os.path.join(wc_dir, 'A', 'D', 'H2')
-  B_url = sbox.repo_url + '/A/B'
-  B_path = os.path.join(wc_dir, 'A', 'B')
-  G_url = sbox.repo_url + '/A/D/G'
-  G_path = os.path.join(wc_dir, 'A', 'D', 'G')
-  H2_url = sbox.repo_url + '/A/D/H2'
 
-  # Make a copy, and dummy up some mergeinfo.
-  mergeinfo = '/A/B:1\n/A/D/G:1\n'
-  svntest.actions.set_prop(SVN_PROP_MERGEINFO, mergeinfo, H_path)
-  svntest.main.run_svn(None, "cp", H_path, H2_path)
-  svntest.main.run_svn(None, "ci", "-m", "r2", wc_dir)
+  def url(relpath):
+    return sbox.repo_url + '/' + relpath
+  def path(relpath):
+    return sbox.ospath(relpath)
+
+  B = 'A/B'
+
+  # make some branches
+  B2 = 'A/B2'
+  B3 = 'A/B3'
+  sbox.simple_repo_copy(B, B2)  # r2
+  sbox.simple_repo_copy(B, B3)  # r3
+  sbox.simple_update()
+
+  # make changes in the branches
+  sbox.simple_mkdir('A/B2/newdir')
+  sbox.simple_commit()  # r4
+  sbox.simple_mkdir('A/B3/newdir')
+  sbox.simple_commit()  # r5
+
+  # Put dummy mergeinfo on branch root
+  mergeinfo = '/A/B2:2-5\n/A/B3:2-5\n'
+  sbox.simple_propset(SVN_PROP_MERGEINFO, mergeinfo, B)
+  sbox.simple_commit()
 
   # Check using each of our recorded merge sources (as paths and URLs).
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           ['1'], B_url, H_path)
+                                           ['2', '4'], url(B2), path(B))
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           ['1'], B_path, H_path)
+                                           ['2', '4'], path(B2), path(B))
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           ['1'], G_url, H_path)
+                                           ['3', '5'], url(B3), path(B))
   svntest.actions.run_and_verify_mergeinfo(adjust_error_for_server_version(""),
-                                           ['1'], G_path, H_path)
+                                           ['3', '5'], path(B3), path(B))
 
 @SkipUnless(server_has_mergeinfo)
 def mergeinfo_non_source(sbox):

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/special_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/special_tests.py Wed Jan  4 10:30:16 2012
@@ -30,7 +30,7 @@ import sys, os, re
 # Our testing module
 import svntest
 
-from svntest.main import server_has_mergeinfo
+from svntest.main import server_has_mergeinfo, run_svn, file_write
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -906,6 +906,123 @@ 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()
+  wc = sbox.ospath
+
+  # Some of these tests are implemented for git (in test script
+  # t/t9100-git-svn-basic.sh) using the Perl bindings for Subversion.
+  # Our issue #4091 is about 'svn update' failures in the git tests.
+
+  sbox.simple_mkdir('A/D/G/Z')
+  sbox.simple_mkdir('A/D/Gx')
+  sbox.simple_mkdir('A/D/Gx/Z')
+  sbox.simple_mkdir('A/D/Hx')
+  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')
+
+  for p in ['Ax/mu',
+            'A/D/Gx/pi',
+            'A/D/Hx/chi',
+            ]:
+      file_write(wc(p), 'This starts as a normal file.\n')
+      sbox.simple_add(p)
+  for p in ['iota.sh',
+            'A/mu.sh',
+            'Ax/mu.sh',
+            'A/D/gamma.sh',
+            'A/B/E/beta.sh',
+            'A/D/G/rho.sh',
+            'A/D/Gx/rho.sh',
+            'A/D/H/psi.sh',
+            'A/D/Hx/psi.sh',
+            ]:
+      file_write(wc(p), '#!/bin/sh\necho "hello, svn!"\n')
+      os.chmod(wc(p), 0775)
+      sbox.simple_add(p)
+  sbox.simple_commit() # 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')
+
+  # 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')
+
+  # Replace a normal {file, exec, dir} with a symlink to the same kind
+  # via Subversion replacement.
+  sbox.simple_rm('A/D/G/pi',
+                 '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',
+                  )
+
+  # Replace a symlink to {file, exec, dir} with a normal item of the
+  # same kind via Subversion replacement.
+  sbox.simple_rm('A/D/H/chi',
+                 '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',
+                  )
+
+  # 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')
+ 
+  # 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', '*',
+                      'Ax/mu',
+                      'Ax/mu.sh')
+  sbox.simple_propdel('svn:executable', 'Ax/mu.sh')
+  
+  ### TODO Replace a normal {file, exec, dir, dir} with a symlink to
+  ### {dir, dir, file, exec}.  And the same symlink-to-normal.
+
+  ### Commit fails as of r1226697 with either "svn: E145001: Entry
+  ### '.../A/D/Gx/Z' has unexpectedly changed special status" or "svn:
+  ### E155010: The node '.../Ax/mu' was not found".
+  sbox.simple_commit() # r3
+
+  # Try updating from HEAD-1 to HEAD.
+  run_svn(None, 'up', '-r2', sbox.wc_dir)
+  sbox.simple_update()
+
+
 ########################################################################
 # Run the tests
 
@@ -933,6 +1050,7 @@ test_list = [ None,
               symlink_to_wc_basic,
               symlink_to_wc_svnversion,
               update_symlink,
+              replace_symlinks,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/svnadmin_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/svnadmin_tests.py Wed Jan  4 10:30:16 2012
@@ -46,6 +46,85 @@ Issue = svntest.testcase.Issue_deco
 Wimp = svntest.testcase.Wimp_deco
 Item = svntest.wc.StateItem
 
+def check_hotcopy_bdb(src, dst):
+  "Verify that the SRC BDB repository has been correctly copied to DST."
+  ### TODO: This function should be extended to verify all hotcopied files,
+  ### not just compare the output of 'svnadmin dump'. See check_hotcopy_fsfs().
+  exit_code, origout, origerr = svntest.main.run_svnadmin("dump", src,
+                                                          '--quiet')
+  exit_code, backout, backerr = svntest.main.run_svnadmin("dump", dst,
+                                                          '--quiet')
+  if origerr or backerr or origout != backout:
+    raise svntest.Failure
+
+def check_hotcopy_fsfs(src, dst):
+    "Verify that the SRC FSFS repository has been correctly copied to DST."
+    # Walk the source and compare all files to the destination
+    for src_dirpath, src_dirs, src_files in os.walk(src):
+      # Verify that the current directory exists in the destination
+      dst_dirpath = src_dirpath.replace(src, dst)
+      if not os.path.isdir(dst_dirpath):
+        raise svntest.Failure("%s does not exist in hotcopy "
+                              "destination" % dst_dirpath)
+      # Verify that all dirents in the current directory also exist in source
+      for dst_dirent in os.listdir(dst_dirpath):
+        src_dirent = os.path.join(src_dirpath, dst_dirent)
+        if not os.path.exists(src_dirent):
+          raise svntest.Failure("%s does not exist in hotcopy "
+                                "source" % src_dirent)
+      # Compare all files in this directory
+      for src_file in src_files:
+        src_path = os.path.join(src_dirpath, src_file)
+        dst_path = os.path.join(dst_dirpath, src_file)
+        if not os.path.isfile(dst_path):
+          raise svntest.Failure("%s does not exist in hotcopy "
+                                "destination" % dst_path)
+
+        # Special case for rep-cache: It will always differ in a byte-by-byte
+        # comparison, so compare db tables instead.
+        if src_file == 'rep-cache.db':
+          db1 = svntest.sqlite3.connect(src_path)
+          db2 = svntest.sqlite3.connect(dst_path)
+          rows1 = []
+          rows2 = []
+          for row in db1.execute("select * from rep_cache order by hash"):
+            rows1.append(row)
+          for row in db2.execute("select * from rep_cache order by hash"):
+            rows2.append(row)
+          if len(rows1) != len(rows2):
+            raise svntest.Failure("number of rows in rep-cache differs")
+          for i in range(len(rows1)):
+            if rows1[i] != rows2[i]:
+              raise svntest.Failure("rep-cache row %i differs: '%s' vs. '%s'"
+                                    % (row, rows1[i]))
+          continue
+
+        f1 = open(src_path, 'r')
+        f2 = open(dst_path, 'r')
+        while True:
+          offset = 0
+          BUFSIZE = 1024
+          buf1 = f1.read(BUFSIZE)
+          buf2 = f2.read(BUFSIZE)
+          if not buf1 or not buf2:
+            if not buf1 and not buf2:
+              # both at EOF
+              break
+            elif buf1:
+              raise svntest.Failure("%s differs at offset %i" % 
+                                    (dst_path, offset))
+            elif buf2:
+              raise svntest.Failure("%s differs at offset %i" % 
+                                    (dst_path, offset))
+          if len(buf1) != len(buf2):
+            raise svntest.Failure("%s differs in length" % dst_path)
+          for i in range(len(buf1)):
+            if buf1[i] != buf2[i]:
+              raise svntest.Failure("%s differs at offset %i"
+                                    % (dst_path, offset))
+            offset += 1
+        f1.close()
+        f2.close()
 
 #----------------------------------------------------------------------
 
@@ -359,17 +438,16 @@ def hotcopy_dot(sbox):
 
   os.chdir(cwd)
 
-  exit_code, origout, origerr = svntest.main.run_svnadmin("dump",
-                                                          sbox.repo_dir,
-                                                          '--quiet')
-  exit_code, backout, backerr = svntest.main.run_svnadmin("dump",
-                                                          backup_dir,
-                                                          '--quiet')
-  if origerr or backerr or origout != backout:
-    raise svntest.Failure
+  if svntest.main.is_fs_type_fsfs():
+    check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
+  else:
+    check_hotcopy_bdb(sbox.repo_dir, backup_dir)
 
 #----------------------------------------------------------------------
 
+# This test is redundant for FSFS. The hotcopy_dot and hotcopy_incremental
+# tests cover this check for FSFS already.
+@SkipUnless(svntest.main.is_fs_type_bdb)
 def hotcopy_format(sbox):
   "'svnadmin hotcopy' checking db/format file"
   sbox.build()
@@ -1510,6 +1588,64 @@ def load_ranges(sbox):
   svntest.verify.compare_and_display_lines("Dump files", "DUMP",
                                            expected_dump, new_dumpdata)
 
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def hotcopy_incremental(sbox):
+  "'svnadmin hotcopy --incremental PATH .'"
+  sbox.build()
+
+  backup_dir, backup_url = sbox.add_repo_path('backup')
+  os.mkdir(backup_dir)
+  cwd = os.getcwd()
+
+  for i in [1, 2, 3]:
+    os.chdir(backup_dir)
+    svntest.actions.run_and_verify_svnadmin(
+      None, None, [],
+      "hotcopy", "--incremental", os.path.join(cwd, sbox.repo_dir), '.')
+
+    os.chdir(cwd)
+
+    check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
+
+    if i < 3:
+      sbox.simple_mkdir("newdir-%i" % i)
+      sbox.simple_commit()
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def hotcopy_incremental_packed(sbox):
+  "'svnadmin hotcopy --incremental' with packing"
+  sbox.build()
+
+  backup_dir, backup_url = sbox.add_repo_path('backup')
+  os.mkdir(backup_dir)
+  cwd = os.getcwd()
+  # Configure two files per shard to trigger packing
+  format_file = open(os.path.join(sbox.repo_dir, 'db', 'format'), 'wb')
+  format_file.write("4\nlayout sharded 2\n")
+  format_file.close()
+
+  # Pack revisions 0 and 1.
+  svntest.actions.run_and_verify_svnadmin(
+    None, None, [], "pack", os.path.join(cwd, sbox.repo_dir))
+
+  # Commit 5 more revs, hotcopy and pack after each commit.
+  for i in [1, 2, 3, 4, 5]:
+    os.chdir(backup_dir)
+    svntest.actions.run_and_verify_svnadmin(
+      None, None, [],
+      "hotcopy", "--incremental", os.path.join(cwd, sbox.repo_dir), '.')
+
+    os.chdir(cwd)
+
+    check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
+
+    if i < 5:
+      sbox.simple_mkdir("newdir-%i" % i)
+      sbox.simple_commit()
+      svntest.actions.run_and_verify_svnadmin(
+        None, None, [], "pack", os.path.join(cwd, sbox.repo_dir))
+
+
 ########################################################################
 # Run the tests
 
@@ -1541,6 +1677,8 @@ test_list = [ None,
               verify_non_utf8_paths,
               test_lslocks_and_rmlocks,
               load_ranges,
+              hotcopy_incremental,
+              hotcopy_incremental_packed,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/svnrdump_tests.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/svnrdump_tests.py Wed Jan  4 10:30:16 2012
@@ -225,26 +225,32 @@ def no_author_load(sbox):
   "load: copy revs with no svn:author revprops"
   run_load_test(sbox, "no-author.dump")
 
+@XFail()
 def copy_from_previous_version_and_modify_dump(sbox):
   "dump: copy from previous version and modify"
   run_dump_test(sbox, "copy-from-previous-version-and-modify.dump")
 
+@XFail()
 def copy_from_previous_version_and_modify_load(sbox):
   "load: copy from previous version and modify"
   run_load_test(sbox, "copy-from-previous-version-and-modify.dump")
 
+@XFail()
 def modified_in_place_dump(sbox):
   "dump: modified in place"
   run_dump_test(sbox, "modified-in-place.dump")
 
+@XFail()
 def modified_in_place_load(sbox):
   "load: modified in place"
   run_load_test(sbox, "modified-in-place.dump")
 
+@XFail()
 def move_and_modify_in_the_same_revision_dump(sbox):
   "dump: move parent & modify child file in same rev"
   run_dump_test(sbox, "move-and-modify.dump")
 
+@XFail()
 def move_and_modify_in_the_same_revision_load(sbox):
   "load: move parent & modify child file in same rev"
   run_load_test(sbox, "move-and-modify.dump")
@@ -289,19 +295,23 @@ def copy_parent_modify_prop_load(sbox):
   "load: copy parent and modify prop"
   run_load_test(sbox, "copy-parent-modify-prop.dump")
 
+@XFail()
 def copy_revprops_dump(sbox):
   "dump: copy revprops other than svn:*"
   run_dump_test(sbox, "revprops.dump")
 
+@XFail()
 def copy_revprops_load(sbox):
   "load: copy revprops other than svn:*"
   run_load_test(sbox, "revprops.dump")
 
+@XFail()
 def only_trunk_dump(sbox):
   "dump: subdirectory"
   run_dump_test(sbox, "trunk-only.dump", subdir="/trunk",
                 expected_dumpfile_name="trunk-only.expected.dump")
 
+@XFail()
 def only_trunk_A_with_changes_dump(sbox):
   "dump: subdirectory with changes on root"
   run_dump_test(sbox, "trunk-A-changes.dump", subdir="/trunk/A",

Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_client/client-test.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_client/client-test.c Wed Jan  4 10:30:16 2012
@@ -28,6 +28,7 @@
 #include <limits.h>
 #include "svn_mergeinfo.h"
 #include "../../libsvn_client/mergeinfo.h"
+#include "../../libsvn_client/client.h"
 #include "svn_pools.h"
 #include "svn_client.h"
 #include "svn_repos.h"
@@ -650,6 +651,71 @@ test_16k_add(const svn_test_opts_t *opts
 }
 #endif
 
+static svn_error_t *
+test_youngest_common_ancestor(const svn_test_opts_t *opts,
+                              apr_pool_t *pool)
+{
+  const char *repos_url;
+  svn_client_ctx_t *ctx;
+  svn_opt_revision_t head_rev = { svn_opt_revision_head, { 0 } };
+  svn_opt_revision_t zero_rev = { svn_opt_revision_number, { 0 } };
+  svn_client_copy_source_t source;
+  apr_array_header_t *sources;
+  const char *dest;
+  const char *yc_ancestor_relpath;
+  svn_revnum_t yc_ancestor_rev;
+
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "test-youngest-common-ancestor", opts, pool));
+
+  svn_client_create_context(&ctx, pool);
+
+  /* Copy a file into dir 'A', keeping its own basename. */
+  sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+  source.path = svn_path_url_add_component2(repos_url, "iota", pool);
+  source.peg_revision = &head_rev;
+  source.revision = &head_rev;
+  APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = &source;
+  dest = svn_path_url_add_component2(repos_url, "A", pool);
+  SVN_ERR(svn_client_copy6(sources, dest, TRUE /* copy_as_child */,
+                           FALSE /* make_parents */,
+                           FALSE /* ignore_externals */,
+                           NULL, NULL, NULL, ctx, pool));
+
+  /* Test: YCA(iota@2, A/iota@2) is iota@1. */
+  SVN_ERR(svn_client__get_youngest_common_ancestor(
+            &yc_ancestor_relpath, NULL, &yc_ancestor_rev,
+            svn_path_url_add_component2(repos_url, "iota", pool), 2,
+            svn_path_url_add_component2(repos_url, "A/iota", pool), 2,
+            ctx, pool));
+  SVN_TEST_STRING_ASSERT(yc_ancestor_relpath, "iota");
+  SVN_TEST_ASSERT(yc_ancestor_rev == 1);
+
+  /* Copy the root directory (at revision 0) into A as 'ROOT'. */
+  sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+  source.path = repos_url;
+  source.peg_revision = &zero_rev;
+  source.revision = &zero_rev;
+  APR_ARRAY_PUSH(sources, svn_client_copy_source_t *) = &source;
+  dest = svn_path_url_add_component2(repos_url, "A/ROOT", pool);
+  SVN_ERR(svn_client_copy6(sources, dest, FALSE /* copy_as_child */,
+                           FALSE /* make_parents */,
+                           FALSE /* ignore_externals */,
+                           NULL, NULL, NULL, ctx, pool));
+
+  /* Test: YCA(''@0, A/ROOT@3) is ''@0 (handled as a special case). */
+  SVN_ERR(svn_client__get_youngest_common_ancestor(
+            &yc_ancestor_relpath, NULL, &yc_ancestor_rev,
+            svn_path_url_add_component2(repos_url, "", pool), 0,
+            svn_path_url_add_component2(repos_url, "A/ROOT", pool), 3,
+            ctx, pool));
+  SVN_TEST_STRING_ASSERT(yc_ancestor_relpath, "");
+  SVN_TEST_ASSERT(yc_ancestor_rev == 0);
+
+  return SVN_NO_ERROR;
+}
+
+
 /* ========================================================================== */
 
 struct svn_test_descriptor_t test_funcs[] =
@@ -665,5 +731,6 @@ struct svn_test_descriptor_t test_funcs[
 #ifdef TEST16K_ADD
     SVN_TEST_OPTS_PASS(test_16k_add, "test adding 16k files"),
 #endif
+    SVN_TEST_OPTS_PASS(test_youngest_common_ancestor, "test youngest_common_ancestor"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/cache-test.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/cache-test.c Wed Jan  4 10:30:16 2012
@@ -193,6 +193,7 @@ test_membuffer_cache_basic(apr_pool_t *p
                                             deserialize_revnum,
                                             APR_HASH_KEY_STRING,
                                             "cache:",
+                                            FALSE,
                                             pool));
 
   return basic_cache_test(cache, FALSE, pool);

Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.c Wed Jan  4 10:30:16 2012
@@ -211,7 +211,7 @@ test_boolean_retrieval(apr_pool_t *pool)
 }
 
 static svn_error_t *
-test_has_section(apr_pool_t *pool)
+test_has_section_case_insensitive(apr_pool_t *pool)
 {
   svn_config_t *cfg;
   const char *cfg_file;
@@ -225,12 +225,50 @@ test_has_section(apr_pool_t *pool)
   if (! svn_config_has_section(cfg, "section1"))
     return fail(pool, "Failed to find section1");
 
+  if (! svn_config_has_section(cfg, "SECTION1"))
+    return fail(pool, "Failed to find SECTION1");
+
+  if (! svn_config_has_section(cfg, "UpperCaseSection"))
+    return fail(pool, "Failed to find UpperCaseSection");
+
+  if (! svn_config_has_section(cfg, "uppercasesection"))
+    return fail(pool, "Failed to find UpperCaseSection");
+
   if (svn_config_has_section(cfg, "notthere"))
     return fail(pool, "Returned true on missing section");
 
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_has_section_case_sensitive(apr_pool_t *pool)
+{
+  svn_config_t *cfg;
+  const char *cfg_file;
+
+  if (!srcdir)
+    SVN_ERR(init_params(pool));
+
+  cfg_file = apr_pstrcat(pool, srcdir, "/", "config-test.cfg", (char *)NULL);
+  SVN_ERR(svn_config_read2(&cfg, cfg_file, TRUE, TRUE, pool));
+
+  if (! svn_config_has_section(cfg, "section1"))
+    return fail(pool, "Failed to find section1");
+
+  if (svn_config_has_section(cfg, "SECTION1"))
+    return fail(pool, "Returned true on missing section");
+
+  if (! svn_config_has_section(cfg, "UpperCaseSection"))
+    return fail(pool, "Failed to find UpperCaseSection");
+
+  if (svn_config_has_section(cfg, "uppercasesection"))
+    return fail(pool, "Returned true on missing section");
+
+  if (svn_config_has_section(cfg, "notthere"))
+    return fail(pool, "Returned true on missing section");
+
+  return SVN_NO_ERROR;
+}
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -246,7 +284,9 @@ struct svn_test_descriptor_t test_funcs[
                    "test svn_config"),
     SVN_TEST_PASS2(test_boolean_retrieval,
                    "test svn_config boolean conversion"),
-    SVN_TEST_PASS2(test_has_section,
-                   "test svn_config_has_section"),
+    SVN_TEST_PASS2(test_has_section_case_insensitive,
+                   "test svn_config_has_section (case insensitive)"),
+    SVN_TEST_PASS2(test_has_section_case_sensitive,
+                   "test svn_config_has_section (case sensitive)"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.cfg
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.cfg?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.cfg (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/config-test.cfg Wed Jan  4 10:30:16 2012
@@ -41,6 +41,9 @@ h=  %(unterminated
 # Multiple expansions
 i=%(a)s %(b)s
 
+[UpperCaseSection]
+a=Aa
+
 [booleans]
 true1 = true
 true2 = Yes

Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_wc/op-depth-test.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_wc/op-depth-test.c Wed Jan  4 10:30:16 2012
@@ -1731,7 +1731,7 @@ test_wc_move(const svn_test_opts_t *opts
       { 2, "A/B",             "base-deleted", NO_COPY_FROM },
       { 2, "A/B/C",           "base-deleted", NO_COPY_FROM },
       { 2, "A/B-move",        "normal",       1, "A/B", MOVED_HERE },
-      { 2, "A/B-move/C",      "normal",       1, "A/B/C" },
+      { 2, "A/B-move/C",      "normal",       1, "A/B/C", MOVED_HERE },
       { 3, "A/B-move/C",      "base-deleted", NO_COPY_FROM },
       { 3, "A/B-move/C-move", "normal",       1, "A/B/C", MOVED_HERE },
       { 0 }
@@ -3790,7 +3790,7 @@ nested_moves_child_first(const svn_test_
       {2, "A/B",     "base-deleted", NO_COPY_FROM},
       {2, "A/B/C",   "base-deleted", NO_COPY_FROM},
       {2, "A/B2",    "normal",       1, "A/B",   MOVED_HERE},
-      {2, "A/B2/C",  "normal",       1, "A/B/C"},
+      {2, "A/B2/C",  "normal",       1, "A/B/C", MOVED_HERE},
       {3, "A/B2/C",  "base-deleted", NO_COPY_FROM},
       {3, "A/B2/C2", "normal",       1, "A/B/C", MOVED_HERE},
       {0}
@@ -3808,12 +3808,12 @@ nested_moves_child_first(const svn_test_
       {1, "A/B",     "base-deleted", NO_COPY_FROM},
       {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
       {1, "A2",      "normal",       1, "A",     MOVED_HERE},
-      {1, "A2/B",    "normal",       1, "A/B"},
-      {1, "A2/B/C",  "normal",       1, "A/B/C"},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
       {2, "A2/B",    "base-deleted", NO_COPY_FROM},
       {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
       {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
-      {2, "A2/B2/C", "normal",       1, "A/B/C"},
+      {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
       {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
       {3, "A2/B2/C2","normal",       1, "A/B/C", MOVED_HERE},
       {0}
@@ -3821,6 +3821,26 @@ nested_moves_child_first(const svn_test_
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
+  /* Revert should leave the A to A2 move */
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
   return SVN_NO_ERROR;
 }
 
@@ -3864,8 +3884,7 @@ nested_moves_child_last(const svn_test_o
     };
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
-  SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));  /* ### Leaves moved-here on lines
-                                             marked XFAIL */
+  SVN_ERR(wc_move(&b, "A2/B", "A2/B2"));
   {
     nodes_row_t nodes[] = {
       {0, "",        "normal",       1, ""},
@@ -3876,8 +3895,8 @@ nested_moves_child_last(const svn_test_o
       {1, "A/B",     "base-deleted", NO_COPY_FROM},
       {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
       {1, "A2",      "normal",       1, "A",     MOVED_HERE},
-      {1, "A2/B",    "normal",       1, "A/B"},               /* XFAIL */
-      {1, "A2/B/C",  "normal",       1, "A/B/C"},             /* XFAIL */
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
       {2, "A2/B",    "base-deleted", NO_COPY_FROM},
       {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
       {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
@@ -3886,8 +3905,7 @@ nested_moves_child_last(const svn_test_o
     };
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
-  SVN_ERR(wc_move(&b, "A2/B2/C", "A2/B2/C2")); /* ### Leaves moved-here on line
-                                                  marked XFAIL */
+  SVN_ERR(wc_move(&b, "A2/B2/C", "A2/B2/C2"));
   {
     nodes_row_t nodes[] = {
       {0, "",        "normal",       1, ""},
@@ -3898,12 +3916,12 @@ nested_moves_child_last(const svn_test_o
       {1, "A/B",     "base-deleted", NO_COPY_FROM},
       {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
       {1, "A2",      "normal",       1, "A",     MOVED_HERE},
-      {1, "A2/B",    "normal",       1, "A/B"},
-      {1, "A2/B/C",  "normal",       1, "A/B/C"},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
       {2, "A2/B",    "base-deleted", NO_COPY_FROM},
       {2, "A2/B/C",  "base-deleted", NO_COPY_FROM},
       {2, "A2/B2",   "normal",       1, "A/B",   MOVED_HERE},
-      {2, "A2/B2/C", "normal",       1, "A/B/C"},                /* XFAIL */
+      {2, "A2/B2/C", "normal",       1, "A/B/C", MOVED_HERE},
       {3, "A2/B2/C", "base-deleted", NO_COPY_FROM},
       {3, "A2/B2/C2","normal",       1, "A/B/C", MOVED_HERE},
       {0}
@@ -3911,6 +3929,26 @@ nested_moves_child_last(const svn_test_o
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
+  /* Revert should leave the A to A2 move */
+  SVN_ERR(wc_revert(&b, "A2/B2", svn_depth_infinity));
+  SVN_ERR(wc_revert(&b, "A2/B", svn_depth_infinity));
+  {
+    nodes_row_t nodes[] = {
+      {0, "",        "normal",       1, ""},
+      {0, "A",       "normal",       1, "A",     FALSE, "A2"},
+      {0, "A/B",     "normal",       1, "A/B"},
+      {0, "A/B/C",   "normal",       1, "A/B/C"},
+      {1, "A",       "base-deleted", NO_COPY_FROM},
+      {1, "A/B",     "base-deleted", NO_COPY_FROM},
+      {1, "A/B/C",   "base-deleted", NO_COPY_FROM},
+      {1, "A2",      "normal",       1, "A",     MOVED_HERE},
+      {1, "A2/B",    "normal",       1, "A/B",   MOVED_HERE},
+      {1, "A2/B/C",  "normal",       1, "A/B/C", MOVED_HERE},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
   return SVN_NO_ERROR;
 }
 
@@ -3919,7 +3957,7 @@ move_in_copy(const svn_test_opts_t *opts
 {
   svn_test__sandbox_t b;
 
-  SVN_ERR(svn_test__sandbox_create(&b, "move_in_replace", opts, pool));
+  SVN_ERR(svn_test__sandbox_create(&b, "move_in_copy", opts, pool));
 
   SVN_ERR(wc_mkdir(&b, "A"));
   SVN_ERR(wc_mkdir(&b, "A/B"));
@@ -4116,10 +4154,10 @@ move_to_swap(const svn_test_opts_t *opts
       {0, "X",   "normal",       1, "X",   FALSE, "A"},
       {0, "X/Y", "normal",       1, "X/Y", FALSE, "X/Y"},
       {1, "A",   "normal",       1, "X",   MOVED_HERE},
-      {1, "A/Y", "normal",       1, "X/Y"},                /* moved-here? */
+      {1, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
       {1, "A/B", "base-deleted", NO_COPY_FROM},
       {1, "X",   "normal",       1, "A",   MOVED_HERE},
-      {1, "X/B", "normal",       1, "A/B"},                /* moved-here? */
+      {1, "X/B", "normal",       1, "A/B", MOVED_HERE},
       {1, "X/Y", "base-deleted", NO_COPY_FROM},
       {2, "A/Y", "base-deleted", NO_COPY_FROM},
       {2, "X/B", "base-deleted", NO_COPY_FROM},
@@ -4158,8 +4196,6 @@ move_to_swap(const svn_test_opts_t *opts
   SVN_ERR(wc_move(&b, "A/Y", "X/Y"));
   SVN_ERR(wc_move(&b, "X/B", "A/B"));
   
-  /* Currently XFAIL on because marked lines set moved-here.  Perhaps
-     this is correct and it should XFAIL on the earlier order?  */
   {
     nodes_row_t nodes[] = {
       {0, "",    "normal",       1, ""},
@@ -4168,10 +4204,10 @@ move_to_swap(const svn_test_opts_t *opts
       {0, "X",   "normal",       1, "X",   FALSE, "A"},
       {0, "X/Y", "normal",       1, "X/Y", FALSE, "X/Y"},
       {1, "A",   "normal",       1, "X",   MOVED_HERE},
-      {1, "A/Y", "normal",       1, "X/Y"},                /* XFAIL */
+      {1, "A/Y", "normal",       1, "X/Y", MOVED_HERE},
       {1, "A/B", "base-deleted", NO_COPY_FROM},
       {1, "X",   "normal",       1, "A",   MOVED_HERE},
-      {1, "X/B", "normal",       1, "A/B"},                /* XFAIL */
+      {1, "X/B", "normal",       1, "A/B", MOVED_HERE},
       {1, "X/Y", "base-deleted", NO_COPY_FROM},
       {2, "A/Y", "base-deleted", NO_COPY_FROM},
       {2, "X/B", "base-deleted", NO_COPY_FROM},
@@ -4393,6 +4429,43 @@ move_on_move2(const svn_test_opts_t *opt
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+move_added(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "move_added", opts, pool));
+
+  SVN_ERR(wc_mkdir(&b, "A"));
+  SVN_ERR(wc_mkdir(&b, "A/B"));
+  SVN_ERR(wc_commit(&b, ""));
+  SVN_ERR(wc_update(&b, "", 1));
+
+  SVN_ERR(wc_mkdir(&b, "A/B/C"));
+  SVN_ERR(wc_move(&b, "A", "A2"));
+  SVN_ERR(wc_mkdir(&b, "A2/B/C2"));
+
+  /* Both A2/B/C and A2/B/C2 are simple adds inside the move.  It
+     doesn't seem right for A2/B/C to be marked moved_here. */
+  {
+    nodes_row_t nodes[] = {
+      {0, "",         "normal",       1, ""},
+      {0, "A",        "normal",       1, "A",   FALSE, "A2"},
+      {0, "A/B",      "normal",       1, "A/B"},
+      {1, "A",        "base-deleted", NO_COPY_FROM},
+      {1, "A/B",      "base-deleted", NO_COPY_FROM},
+      {1, "A2",       "normal",       1, "A",   MOVED_HERE},
+      {1, "A2/B",     "normal",       1, "A/B", MOVED_HERE},
+      {3, "A2/B/C",   "normal",       NO_COPY_FROM},          /* XFAIL */
+      {3, "A2/B/C2",  "normal",       NO_COPY_FROM},
+      {0}
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /* ---------------------------------------------------------------------- */
@@ -4465,7 +4538,7 @@ struct svn_test_descriptor_t test_funcs[
                        "incomplete_switch (issue 4040)"),
     SVN_TEST_OPTS_PASS(nested_moves_child_first,
                        "nested_moves_child_first"),
-    SVN_TEST_OPTS_XFAIL(nested_moves_child_last,
+    SVN_TEST_OPTS_PASS(nested_moves_child_last,
                        "nested_moves_child_last"),
     SVN_TEST_OPTS_XFAIL(move_in_copy,
                        "move_in_copy"),
@@ -4473,7 +4546,7 @@ struct svn_test_descriptor_t test_funcs[
                        "move_in_replace"),
     SVN_TEST_OPTS_PASS(copy_a_move,
                        "copy_a_move"),
-    SVN_TEST_OPTS_XFAIL(move_to_swap,
+    SVN_TEST_OPTS_PASS(move_to_swap,
                        "move_to_swap"),
     SVN_TEST_OPTS_PASS(revert_nested_move,
                        "revert_nested_move"),
@@ -4481,5 +4554,7 @@ struct svn_test_descriptor_t test_funcs[
                        "move_on_move"),
     SVN_TEST_OPTS_XFAIL(move_on_move2,
                        "move_on_move2"),
+    SVN_TEST_OPTS_XFAIL(move_added,
+                       "move_added"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/moves-scan-log/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd (original)
+++ subversion/branches/moves-scan-log/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd Wed Jan  4 10:30:16 2012
@@ -32,7 +32,7 @@ IF NOT EXIST "imports\" (
 )
 IF NOT EXIST build\imports.done (
   copy /y imports\dev-default.build default.build
-  nant build %NANTARGS%
+  nant prep-dev %NANTARGS%
   IF ERRORLEVEL 1 (
     exit /B 1
   )
@@ -54,6 +54,7 @@ taskkill /im svnserve.exe /f 2> nul:
 taskkill /im svnrdump.exe /f 2> nul:
 taskkill /im svnsync.exe /f 2> nul:
 taskkill /im httpd.exe /f 2> nul:
+taskkill /im op-depth-test.exe /f 2> nul:
 IF EXIST "%TESTDIR%\tests\subversion\tests\cmdline\httpd\" (
   rmdir /s /q  "%TESTDIR%\tests\subversion\tests\cmdline\httpd"
 )

Modified: subversion/branches/moves-scan-log/tools/client-side/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/client-side/svnmucc/svnmucc.c?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/client-side/svnmucc/svnmucc.c (original)
+++ subversion/branches/moves-scan-log/tools/client-side/svnmucc/svnmucc.c Wed Jan  4 10:30:16 2012
@@ -109,6 +109,7 @@ create_ra_callbacks(svn_ra_callbacks2_t 
                     const char *username,
                     const char *password,
                     const char *config_dir,
+                    svn_config_t *cfg_config,
                     svn_boolean_t non_interactive,
                     svn_boolean_t no_auth_cache,
                     apr_pool_t *pool)
@@ -119,7 +120,8 @@ create_ra_callbacks(svn_ra_callbacks2_t 
                                         non_interactive,
                                         username, password, config_dir,
                                         no_auth_cache,
-                                        FALSE, NULL, NULL, NULL, pool));
+                                        FALSE /* trust_server_certs */,
+                                        cfg_config, NULL, NULL, pool));
 
   (*callbacks)->open_tmp_file = open_tmp_file;
 
@@ -629,13 +631,17 @@ execute(const apr_array_header_t *action
   struct operation root;
   svn_error_t *err;
   apr_hash_t *config;
+  svn_config_t *cfg_config;
   int i;
 
   SVN_ERR(svn_config_get_config(&config, config_dir, pool));
   SVN_ERR(svn_cmdline__apply_config_options(config, config_options,
                                             "svnmucc: ", "--config-option"));
+  cfg_config = apr_hash_get(config, SVN_CONFIG_CATEGORY_CONFIG,
+                            APR_HASH_KEY_STRING);
   SVN_ERR(create_ra_callbacks(&ra_callbacks, username, password, config_dir,
-                              non_interactive, no_auth_cache, pool));
+                              cfg_config, non_interactive, no_auth_cache,
+                              pool));
   SVN_ERR(svn_ra_open4(&session, NULL, anchor, NULL, ra_callbacks,
                        NULL, config, pool));
 

Modified: subversion/branches/moves-scan-log/tools/dev/po-merge.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/dev/po-merge.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/dev/po-merge.py (original)
+++ subversion/branches/moves-scan-log/tools/dev/po-merge.py Wed Jan  4 10:30:16 2012
@@ -52,7 +52,7 @@ def parse_translation(f):
         line = f.readline()
         if line[0] != '"':
             break
-        msgid += '\n' + line[:-1]
+        msgid = msgid[:-1] + line[1:-1]
 
     # Parse optional msgid_plural
     msgid_plural = None
@@ -64,7 +64,7 @@ def parse_translation(f):
             line = f.readline()
             if line[0] != '"':
                 break
-            msgid_plural += '\n' + line[:-1]
+            msgid_plural = msgid_plural[:-1] + line[1:-1]
 
     # Parse msgstr
     msgstr = []
@@ -117,9 +117,9 @@ def main(argv):
         argv0 = os.path.basename(argv[0])
         sys.exit('Usage: %s <lang.po>\n'
                  '\n'
-                 'This script will replace the translations and flags in lang.po with\n'
-                 'the translations and flags in the source po file read from standard\n'
-                 'input.  Strings that are not found in the source file are left untouched.\n'
+                 'This script will replace the translations and flags in lang.po (LF line endings)\n'
+                 'with the translations and flags in the source po file read from standard input.\n'
+                 'Strings that are not found in the source file are left untouched.\n'
                  'A backup copy of lang.po is saved as lang.po.bak.\n'
                  '\n'
                  'Example:\n'

Modified: subversion/branches/moves-scan-log/tools/dist/backport.pl
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/dist/backport.pl?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/dist/backport.pl (original)
+++ subversion/branches/moves-scan-log/tools/dist/backport.pl Wed Jan  4 10:30:16 2012
@@ -68,12 +68,12 @@ sub merge {
 
   if ($entry{branch}) {
     # NOTE: This doesn't escape the branch into the pattern.
-    $pattern = printf '^ [*] %s branch\|Branch:\n *%s', $entry{branch}, $entry{branch};
+    $pattern = sprintf '\V\(%s branch\|branches\/%s\|Branch:\n *%s\)', $entry{branch}, $entry{branch}, $entry{branch};
     $mergeargs = "--reintegrate $BRANCHES/$entry{branch}";
     print $logmsg_fh "Reintergrate the $entry{header}:";
     print $logmsg_fh "";
   } elsif (@{$entry{revisions}}) {
-    $pattern = 'r' . $entry{revisions}->[0];
+    $pattern = '^ [*] \V' . 'r' . $entry{revisions}->[0];
     $mergeargs = join " ", (map { "-c$_" } @{$entry{revisions}}), '^/subversion/trunk';
     if (@{$entry{revisions}} > 1) {
       print $logmsg_fh "Merge the $entry{header} from trunk:";
@@ -88,7 +88,6 @@ sub merge {
   print $logmsg_fh $_ for @{$entry{entry}};
   close $logmsg_fh or die "Can't close $logmsg_filename: $!";
 
-  $pattern = '\V'.$pattern;
   my $script = <<"EOF";
 #!/bin/sh
 set -e
@@ -96,7 +95,7 @@ $SVN diff > $backupfile
 $SVN revert -R .
 $SVN up
 $SVN merge $mergeargs
-$VIM -e -s -n -N -i NONE -u NONE -c '/^ [*] $pattern/normal! dap' -c wq $STATUS
+$VIM -e -s -n -N -i NONE -u NONE -c '/$pattern/normal! dap' -c wq $STATUS
 if $WET_RUN; then
   $SVN commit -F $logmsg_filename
 else
@@ -109,8 +108,7 @@ EOF
   $script .= <<"EOF" if $entry{branch};
 reinteg_rev=\`$SVN info $STATUS | sed -ne 's/Last Changed Rev: //p'\`
 if $WET_RUN; then
-  $SVN rm $BRANCHES/$entry{branch}\
-          -m "Remove the '$entry{branch}' branch, reintegrated in r\$reinteg_rev."
+  $SVN rm $BRANCHES/$entry{branch} -m "Remove the '$entry{branch}' branch, reintegrated in r\$reinteg_rev."
 else
   echo "Removing reintegrated '$entry{branch}' branch"
 fi
@@ -205,15 +203,17 @@ sub main {
   usage, exit 0 if @ARGV;
   usage, exit 1 unless -r $STATUS;
 
+  my $sawapproved;
   @ARGV = $STATUS;
   while (<>) {
     my @lines = split /\n/;
 
     # Section header?
+    next unless $sawapproved ||= /^Approved changes/;
     print "\n\n=== $lines[0]" and next if $lines[0] =~ /^[A-Z].*:$/i;
 
     # Backport entry?
-    handle_entry @lines and next if $lines[0] =~ /^ \*/;
+    handle_entry @lines and next if $lines[0] =~ /^ \*/ and $sawapproved;
 
     warn "Unknown entry '$lines[0]' at $ARGV:$.\n";
   }

Modified: subversion/branches/moves-scan-log/tools/dist/dist.sh
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/dist/dist.sh?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/dist/dist.sh (original)
+++ subversion/branches/moves-scan-log/tools/dist/dist.sh Wed Jan  4 10:30:16 2012
@@ -260,28 +260,12 @@ find "$DISTPATH" -name config.nice -prin
 # on end-user's systems, when they should just be compiled by the
 # Release Manager and left at that.
 
-if [ "$VERSION" = nightly ]; then
-  # ### FIXME Gross hack.
-  #
-  # release.py sets Version().base = 'nightly'; which causes this to
-  # be called as 'dist.sh -v nightly', rather than 'dist.sh -v 1.8.0';
-  # which causes the sed below to write '#define SVN_VER_MAJOR nightly'
-  # into subversion/include/svn_version.h; which chokes build/getversion.py,
-  # called by build/generator/gen_base.py during './autogen.sh --release'.
-  #
-  # Setting this to ampersand should fool sed and peace the kingdom.
-  ver_major="&"
-  ver_minor="&"
-  ver_patch="&"
-else
-  ver_major=`echo $VERSION | cut -d '.' -f 1`
-  ver_minor=`echo $VERSION | cut -d '.' -f 2`
-  ver_patch=`echo $VERSION | cut -d '.' -f 3`
-fi
+ver_major=`echo $VERSION | cut -d '.' -f 1`
+ver_minor=`echo $VERSION | cut -d '.' -f 2`
+ver_patch=`echo $VERSION | cut -d '.' -f 3`
 
 vsn_file="$DISTPATH/subversion/include/svn_version.h"
-
-if [ "$VERSION" != "trunk" ]; then
+if [ "$VERSION" != "trunk" ] && [ "$VERSION" != "nightly" ]; then
   sed \
    -e "/#define *SVN_VER_MAJOR/s/[0-9][0-9]*/$ver_major/" \
    -e "/#define *SVN_VER_MINOR/s/[0-9][0-9]*/$ver_minor/" \
@@ -298,7 +282,6 @@ else
    -e "/#define *SVN_VER_REVISION/s/[0-9]\\+/$REVISION/" \
     < "$vsn_file" > "$vsn_file.tmp"
 fi
-
 mv -f "$vsn_file.tmp" "$vsn_file"
 
 echo "Creating svn_version.h.dist, for use in tagging matching tarball..."

Modified: subversion/branches/moves-scan-log/tools/server-side/svnpredumpfilter.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/server-side/svnpredumpfilter.py?rev=1227105&r1=1227104&r2=1227105&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/server-side/svnpredumpfilter.py (original)
+++ subversion/branches/moves-scan-log/tools/server-side/svnpredumpfilter.py Wed Jan  4 10:30:16 2012
@@ -33,6 +33,7 @@ log -vq' when run against the root of th
 will be filtered by a user with universal read access to the
 repository's data.  Do not use the --use-merge-history (-g) or
 --stop-on-copy when generating this revision log stream.
+Use the default ordering of revisions (that is, '-r HEAD:0').
 
 Return errorcode 0 if there are no additional dependencies found, 1 if
 there were; any other errorcode indicates a fatal error.



Mime
View raw message