You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2012/08/02 21:09:24 UTC

svn commit: r1368653 [1/4] - in /subversion/branches/master-passphrase: ./ contrib/client-side/svn-push/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/swig/ subversion/bindings/swig/...

Author: cmpilato
Date: Thu Aug  2 19:09:21 2012
New Revision: 1368653

URL: http://svn.apache.org/viewvc?rev=1368653&view=rev
Log:
Merge recent trunk changes to the 'master-passphrase' branch.
(Merged /subversion/trunk:r1365672-1368648.)

Modified:
    subversion/branches/master-passphrase/   (props changed)
    subversion/branches/master-passphrase/CHANGES
    subversion/branches/master-passphrase/contrib/client-side/svn-push/svn-push.c
    subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.cpp
    subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.h
    subversion/branches/master-passphrase/subversion/bindings/javahl/native/JNIUtil.cpp
    subversion/branches/master-passphrase/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/master-passphrase/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
    subversion/branches/master-passphrase/subversion/bindings/swig/core.i
    subversion/branches/master-passphrase/subversion/bindings/swig/include/svn_containers.swg
    subversion/branches/master-passphrase/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/branches/master-passphrase/subversion/include/private/svn_mergeinfo_private.h
    subversion/branches/master-passphrase/subversion/include/svn_client.h
    subversion/branches/master-passphrase/subversion/include/svn_mergeinfo.h
    subversion/branches/master-passphrase/subversion/include/svn_ra.h
    subversion/branches/master-passphrase/subversion/include/svn_wc.h
    subversion/branches/master-passphrase/subversion/libsvn_client/diff.c
    subversion/branches/master-passphrase/subversion/libsvn_client/externals.c
    subversion/branches/master-passphrase/subversion/libsvn_client/merge.c
    subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.c
    subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.h
    subversion/branches/master-passphrase/subversion/libsvn_client/ra.c
    subversion/branches/master-passphrase/subversion/libsvn_client/relocate.c
    subversion/branches/master-passphrase/subversion/libsvn_client/switch.c
    subversion/branches/master-passphrase/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/master-passphrase/subversion/libsvn_fs_fs/tree.c
    subversion/branches/master-passphrase/subversion/libsvn_fs_util/fs-util.c
    subversion/branches/master-passphrase/subversion/libsvn_repos/load-fs-vtable.c
    subversion/branches/master-passphrase/subversion/libsvn_repos/log.c
    subversion/branches/master-passphrase/subversion/libsvn_repos/rev_hunt.c
    subversion/branches/master-passphrase/subversion/libsvn_subr/deprecated.c
    subversion/branches/master-passphrase/subversion/libsvn_subr/mergeinfo.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/adm_files.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/adm_ops.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/cleanup.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/conflicts.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/crop.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/externals.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/merge.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/node.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/props.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/update_editor.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/master-passphrase/subversion/libsvn_wc/wc.h
    subversion/branches/master-passphrase/subversion/libsvn_wc/wc_db.c
    subversion/branches/master-passphrase/subversion/libsvn_wc/wc_db.h
    subversion/branches/master-passphrase/subversion/libsvn_wc/wc_db_pristine.c
    subversion/branches/master-passphrase/subversion/svn/main.c
    subversion/branches/master-passphrase/subversion/svn/merge-cmd.c
    subversion/branches/master-passphrase/subversion/svn/notify.c
    subversion/branches/master-passphrase/subversion/svnadmin/main.c
    subversion/branches/master-passphrase/subversion/svndumpfilter/main.c
    subversion/branches/master-passphrase/subversion/svnlook/main.c
    subversion/branches/master-passphrase/subversion/svnmucc/svnmucc.c
    subversion/branches/master-passphrase/subversion/svnrdump/load_editor.c
    subversion/branches/master-passphrase/subversion/svnserve/main.c
    subversion/branches/master-passphrase/subversion/svnsync/main.c
    subversion/branches/master-passphrase/subversion/svnversion/main.c
    subversion/branches/master-passphrase/subversion/tests/cmdline/merge_symmetric_tests.py
    subversion/branches/master-passphrase/subversion/tests/cmdline/merge_tests.py
    subversion/branches/master-passphrase/subversion/tests/cmdline/update_tests.py
    subversion/branches/master-passphrase/subversion/tests/libsvn_client/client-test.c
    subversion/branches/master-passphrase/subversion/tests/libsvn_subr/dirent_uri-test.c
    subversion/branches/master-passphrase/subversion/tests/libsvn_subr/mergeinfo-test.c
    subversion/branches/master-passphrase/tools/dev/gdb-py/svndbg/printers.py
    subversion/branches/master-passphrase/tools/dev/svnraisetreeconflict/main.c
    subversion/branches/master-passphrase/tools/dev/unix-build/Makefile.svn
    subversion/branches/master-passphrase/tools/server-side/svn-rep-sharing-stats.c

Propchange: subversion/branches/master-passphrase/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1365672-1368648

Modified: subversion/branches/master-passphrase/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/CHANGES?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/CHANGES (original)
+++ subversion/branches/master-passphrase/CHANGES Thu Aug  2 19:09:21 2012
@@ -67,16 +67,23 @@ http://svn.apache.org/repos/asf/subversi
     * allow 'file:///C:\repos' style arguments on Windows, like 1.6 (r1346765)
     * fix ra_serf against Subversion 1.2 servers (r1349367)
     * fix 'svn upgrade' on working copies with certain tree conflicts (r1345482)
+    * avoid workqueue references to system temp dir (r1367854)
+    * allow non-existant canonical paths (r1367853)
+    * fix 'svn revert --depth files' to operate on files (r1365554)
+    * fix ra_serf XML namespace handling against malicious server (r1337441)
 
   - Server-side bugfixes:
     * partial sync drops properties when converting to adds (issue #4184)
     * replaying a copy and delete of an unreadable child fails (issue #4121)
+    * allow svnlook to operate on r0 (r1362508)
+    * make FSFS revision files independent of APR hash order (r1367498)
 
   - Other tool improvements and bugfixes:
 
  Developer-visible changes:
   - General:
     * fix running tests against httpd 2.4 (r1291594)
+    * use constant struct initialisers for C89 compatibility (r1352068)
 
   - Bindings:
     * JavaHL: Don't assert on some invalid input (r1354626, r1354652)

Modified: subversion/branches/master-passphrase/contrib/client-side/svn-push/svn-push.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/contrib/client-side/svn-push/svn-push.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/contrib/client-side/svn-push/svn-push.c (original)
+++ subversion/branches/master-passphrase/contrib/client-side/svn-push/svn-push.c Thu Aug  2 19:09:21 2012
@@ -147,8 +147,8 @@ check_lib_versions (void)
       { "svn_ra",     svn_ra_version },
       { NULL, NULL }
     };
-
   SVN_VERSION_DEFINE (my_version);
+
   return svn_ver_check_list (&my_version, checklist);
 }
 

Modified: subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.cpp?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.cpp Thu Aug  2 19:09:21 2012
@@ -911,7 +911,7 @@ CreateJ::CommitInfo(const svn_commit_inf
 }
 
 jobject
-CreateJ::RevisionRangeList(apr_array_header_t *ranges)
+CreateJ::RevisionRangeList(svn_rangelist_t *ranges)
 {
   JNIEnv *env = JNIUtil::getEnv();
 

Modified: subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/master-passphrase/subversion/bindings/javahl/native/CreateJ.h Thu Aug  2 19:09:21 2012
@@ -74,7 +74,7 @@ class CreateJ
   CommitInfo(const svn_commit_info_t *info);
 
   static jobject
-  RevisionRangeList(apr_array_header_t *ranges);
+  RevisionRangeList(svn_rangelist_t *ranges);
 
   static jobject
   StringSet(apr_array_header_t *strings);

Modified: subversion/branches/master-passphrase/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/master-passphrase/subversion/bindings/javahl/native/JNIUtil.cpp Thu Aug  2 19:09:21 2012
@@ -37,9 +37,13 @@
 #include <apr_lib.h>
 
 #include "svn_pools.h"
+#include "svn_fs.h"
+#include "svn_ra.h"
+#include "svn_utf.h"
 #include "svn_wc.h"
 #include "svn_dso.h"
 #include "svn_path.h"
+#include "svn_cache_config.h"
 #include <apr_file_info.h>
 #include "svn_private_config.h"
 #ifdef WIN32
@@ -175,6 +179,19 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
       apr_allocator_max_free_set(allocator, 1);
     }
 
+  svn_utf_initialize(g_pool); /* Optimize character conversions */
+  svn_fs_initialize(g_pool); /* Avoid some theoretical issues */
+  svn_ra_initialize(g_pool);
+
+  /* We shouldn't fill the JVMs memory with FS cache data unless explictly
+     requested. */
+  {
+    svn_cache_config_t settings = *svn_cache_config_get();
+    settings.cache_size = 0;
+    settings.file_handle_count = 0;
+    settings.single_threaded = FALSE;
+    svn_cache_config_set(&settings);
+  }
 
 #ifdef ENABLE_NLS
 #ifdef WIN32
@@ -240,6 +257,8 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
     }
 #endif
 
+  svn_error_set_malfunction_handler(svn_error_raise_on_malfunction);
+
   // Build all mutexes.
   g_finalizedObjectsMutex = new JNIMutex(g_pool);
   if (isExceptionThrown())

Modified: subversion/branches/master-passphrase/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/javahl/native/SVNClient.cpp?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/master-passphrase/subversion/bindings/javahl/native/SVNClient.cpp Thu Aug  2 19:09:21 2012
@@ -760,7 +760,7 @@ SVNClient::getMergeinfo(const char *targ
 
         jstring jpath = JNIUtil::makeJString((const char *) path);
         jobject jranges =
-            CreateJ::RevisionRangeList((apr_array_header_t *) val);
+            CreateJ::RevisionRangeList((svn_rangelist_t *) val);
 
         env->CallVoidMethod(jmergeinfo, addRevisions, jpath, jranges);
 

Modified: subversion/branches/master-passphrase/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java (original)
+++ subversion/branches/master-passphrase/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java Thu Aug  2 19:09:21 2012
@@ -552,9 +552,14 @@ public class ClientNotifyInformation ext
         /** Operation failed because a node is obstructed */
         failed_obstructed ("failed by obstruction"),
 
-        /** Conflict resolver is starting/ending. */
+        /** Conflict resolver is starting. */
         conflict_resolver_starting ("conflict resolver starting"),
-        conflict_resolver_done ("conflict resolver done");
+
+        /** Conflict resolver is done. */
+        conflict_resolver_done ("conflict resolver done"),
+
+        /** Operation left local modifications. */
+        left_local_modifications ("left local modifications");
 
         /**
          * The description of the action.

Modified: subversion/branches/master-passphrase/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/swig/core.i?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/swig/core.i (original)
+++ subversion/branches/master-passphrase/subversion/bindings/swig/core.i Thu Aug  2 19:09:21 2012
@@ -259,34 +259,34 @@
 /* -----------------------------------------------------------------------
    input rangelist
 */
-%apply apr_array_header_t *RANGELIST {
-  apr_array_header_t *rangeinput,
-  const apr_array_header_t *rangelist,
-  apr_array_header_t *from,
-  apr_array_header_t *to,
-  apr_array_header_t *changes,
-  apr_array_header_t *eraser,
-  apr_array_header_t *whiteboard,
-  apr_array_header_t *rangelist1,
-  apr_array_header_t *rangelist2
+%apply svn_rangelist_t *RANGELIST {
+  svn_rangelist_t *rangeinput,
+  const svn_rangelist_t *rangelist,
+  svn_rangelist_t *from,
+  svn_rangelist_t *to,
+  svn_rangelist_t *changes,
+  svn_rangelist_t *eraser,
+  svn_rangelist_t *whiteboard,
+  svn_rangelist_t *rangelist1,
+  svn_rangelist_t *rangelist2
 }
 
 /* -----------------------------------------------------------------------
    output rangelist
 */
-%apply apr_array_header_t **RANGELIST {
-  apr_array_header_t **rangelist,
-  apr_array_header_t **inheritable_rangelist,
-  apr_array_header_t **deleted,
-  apr_array_header_t **added,
-  apr_array_header_t **output
+%apply svn_rangelist_t **RANGELIST {
+  svn_rangelist_t **rangelist,
+  svn_rangelist_t **inheritable_rangelist,
+  svn_rangelist_t **deleted,
+  svn_rangelist_t **added,
+  svn_rangelist_t **output
 }
 
 /* -----------------------------------------------------------------------
    input and output rangelist
 */
-%apply apr_array_header_t **RANGELIST_INOUT {
-  apr_array_header_t **rangelist_inout
+%apply svn_rangelist_t **RANGELIST_INOUT {
+  svn_rangelist_t **rangelist_inout
 }
 
 /* -----------------------------------------------------------------------
@@ -1145,15 +1145,15 @@ svn_swig_mergeinfo_sort(apr_hash_t **mer
 }
 
 static svn_error_t *
-svn_swig_rangelist_merge(apr_array_header_t **rangelist_inout,
-                         apr_array_header_t *changes,
+svn_swig_rangelist_merge(svn_rangelist_t **rangelist_inout,
+                         svn_rangelist_t *changes,
                          apr_pool_t *pool)
 {
   return svn_rangelist_merge(rangelist_inout, changes, pool);
 }
 
 static svn_error_t *
-svn_swig_rangelist_reverse(apr_array_header_t **rangelist_inout,
+svn_swig_rangelist_reverse(svn_rangelist_t **rangelist_inout,
                            apr_pool_t *pool)
 {
   return svn_rangelist_reverse(*rangelist_inout, pool);

Modified: subversion/branches/master-passphrase/subversion/bindings/swig/include/svn_containers.swg
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/swig/include/svn_containers.swg?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/swig/include/svn_containers.swg (original)
+++ subversion/branches/master-passphrase/subversion/bindings/swig/include/svn_containers.swg Thu Aug  2 19:09:21 2012
@@ -692,10 +692,11 @@
 
 /* -----------------------------------------------------------------------
    Input of apr_array_header_t * <svn_merge_range_t *>
+   (that is: svn_rangelist_t *)
 */
 #ifdef SWIGPYTHON
-%typemap(in) apr_array_header_t *RANGELIST {
-    $1 = (apr_array_header_t *) svn_swig_py_seq_to_array($input,
+%typemap(in) svn_rangelist_t *RANGELIST {
+    $1 = (svn_rangelist_t *) svn_swig_py_seq_to_array($input,
       sizeof(const svn_merge_range_t *),
       svn_swig_py_unwrap_struct_ptr,
       $descriptor(svn_merge_range_t *),
@@ -707,7 +708,7 @@
 #endif
 
 #ifdef SWIGRUBY
-%typemap(in) apr_array_header_t *RANGELIST {
+%typemap(in) svn_rangelist_t *RANGELIST {
   $1 = svn_swig_rb_array_to_apr_array_merge_range($input, _global_pool);
 }
 #endif
@@ -809,7 +810,7 @@
    Output of
    apr_hash_t * <const char *,
                  apr_hash_t * <const char *,
-                               array_header_t * <svn_merge_range_t *>>>
+                               apr_array_header_t * <svn_merge_range_t *>>>
 */
 #ifdef SWIGRUBY
 %typemap(argout) apr_hash_t **MERGEINFO_CATALOG
@@ -831,9 +832,10 @@
 
 /* -----------------------------------------------------------------------
    Output of apr_array_header_t * <svn_merge_range_t *>
+   (that is: svn_rangelist_t *)
 */
 #ifdef SWIGPYTHON
-%typemap(argout) apr_array_header_t **RANGELIST {
+%typemap(argout) svn_rangelist_t **RANGELIST {
   %append_output
     (svn_swig_py_pointerlist_to_list(*$1, $descriptor(svn_merge_range_t *),
                                      _global_py_pool));
@@ -842,10 +844,10 @@
   }
 }
 
-%typemap(in) apr_array_header_t **RANGELIST_INOUT ($*1_ltype temp)
+%typemap(in) svn_rangelist_t **RANGELIST_INOUT ($*1_ltype temp)
 {
   $1 = &temp;
-  *$1 = (apr_array_header_t *) svn_swig_py_seq_to_array($input,
+  *$1 = (svn_rangelist_t *) svn_swig_py_seq_to_array($input,
     sizeof(const svn_merge_range_t *),
     svn_swig_py_unwrap_struct_ptr,
     $descriptor(svn_merge_range_t *),
@@ -858,11 +860,11 @@
 #endif
 
 #ifdef SWIGRUBY
-%typemap(argout) apr_array_header_t **RANGELIST {
+%typemap(argout) svn_rangelist_t **RANGELIST {
   %append_output(svn_swig_rb_apr_array_to_array_merge_range(*$1));
 }
 
-%typemap(in) apr_array_header_t **RANGELIST_INOUT ($*1_ltype temp)
+%typemap(in) svn_rangelist_t **RANGELIST_INOUT ($*1_ltype temp)
 {
   $1 = &temp;
   *$1 = svn_swig_rb_array_to_apr_array_merge_range($input, _global_pool);
@@ -870,8 +872,8 @@
 #endif
 
 #if defined(SWIGPYTHON) || defined(SWIGRUBY)
-%typemap(argout) apr_array_header_t **RANGELIST_INOUT =
-   apr_array_header_t **RANGELIST;
+%typemap(argout) svn_rangelist_t **RANGELIST_INOUT =
+   svn_rangelist_t **RANGELIST;
 #endif
 
 /* -----------------------------------------------------------------------

Modified: subversion/branches/master-passphrase/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/master-passphrase/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Thu Aug  2 19:09:21 2012
@@ -988,7 +988,7 @@ apr_hash_t *svn_swig_py_mergeinfo_from_d
       PyObject *key = PyList_GetItem(keys, i);
       PyObject *value = PyDict_GetItem(dict, key);
       const char *pathname = make_string_from_ob(key, pool);
-      const apr_array_header_t *ranges = svn_swig_py_seq_to_array(value,
+      const svn_rangelist_t *ranges = svn_swig_py_seq_to_array(value,
         sizeof(const svn_merge_range_t *),
         svn_swig_py_unwrap_struct_ptr,
         svn_swig_TypeQuery("svn_merge_range_t *"),

Modified: subversion/branches/master-passphrase/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/private/svn_mergeinfo_private.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/branches/master-passphrase/subversion/include/private/svn_mergeinfo_private.h Thu Aug  2 19:09:21 2012
@@ -41,7 +41,7 @@ extern "C" {
 /* Set inheritability of all ranges in RANGELIST to INHERITABLE.
    If RANGELIST is NULL do nothing. */
 void
-svn_rangelist__set_inheritance(apr_array_header_t *rangelist,
+svn_rangelist__set_inheritance(svn_rangelist_t *rangelist,
                                svn_boolean_t inheritable);
 
 /* Parse a rangelist from the string STR. Set *RANGELIST to the result,
@@ -52,7 +52,7 @@ svn_rangelist__set_inheritance(apr_array
  * Unlike svn_mergeinfo_parse(), this does not sort the ranges into order
  * or combine adjacent and overlapping ranges. */
 svn_error_t *
-svn_rangelist__parse(apr_array_header_t **rangelist,
+svn_rangelist__parse(svn_rangelist_t **rangelist,
                      const char *str,
                      apr_pool_t *result_pool);
 
@@ -239,7 +239,7 @@ svn_mergeinfo__is_noninheritable(svn_mer
 /* Return a rangelist with one svn_merge_range_t * element defined by START,
    END, and INHERITABLE.  The rangelist and its contents are allocated in
    RESULT_POOL. */
-apr_array_header_t *
+svn_rangelist_t *
 svn_rangelist__initialize(svn_revnum_t start,
                           svn_revnum_t end,
                           svn_boolean_t inheritable,
@@ -277,7 +277,7 @@ svn_mergeinfo__mergeinfo_from_segments(s
  * RESULT_POOL. See svn_rangelist_merge2() for details of inheritability
  * etc. */
 svn_error_t *
-svn_rangelist__merge_many(apr_array_header_t *merged_rangelist,
+svn_rangelist__merge_many(svn_rangelist_t *merged_rangelist,
                           svn_mergeinfo_t mergeinfo,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool);

Modified: subversion/branches/master-passphrase/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_client.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_client.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_client.h Thu Aug  2 19:09:21 2012
@@ -3676,9 +3676,8 @@ svn_client_suggest_merge_sources(apr_arr
 /**
  * Get the mergeinfo for a single target node (ignoring any subtrees).
  *
- * Set @a *mergeinfo to a hash mapping <tt>const char *</tt> merge
- * source URLs to <tt>apr_array_header_t *</tt> rangelists (arrays of
- * <tt>svn_merge_range_t *</tt> ranges) describing the ranges which
+ * Set @a *mergeinfo to a hash mapping <tt>const char *</tt> merge source
+ * URLs to <tt>svn_rangelist_t *</tt> rangelists describing the ranges which
  * have been merged into @a path_or_url as of @a peg_revision, per
  * @a path_or_url's explicit mergeinfo or inherited mergeinfo if no
  * explicit mergeinfo if found.  If no explicit or inherited mergeinfo

Modified: subversion/branches/master-passphrase/subversion/include/svn_mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_mergeinfo.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_mergeinfo.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_mergeinfo.h Thu Aug  2 19:09:21 2012
@@ -113,8 +113,8 @@ extern "C" {
  *
  * (a) Strings (@c svn_string_t *) containing "unparsed mergeinfo".
  *
- * (b) A "rangelist".  An array (@c apr_array_header_t *) of non-overlapping
- *     merge ranges (@c svn_merge_range_t *), sorted as said by
+ * (b) @c svn_rangelist_t, called a "rangelist".  An array of non-
+ *     overlapping merge ranges (@c svn_merge_range_t *), sorted as said by
  *     @c svn_sort_compare_ranges().  An empty range list is represented by
  *     an empty array.  Unless specifically noted otherwise, all APIs require
  *     rangelists that describe only forward ranges, i.e. the range's start
@@ -139,6 +139,7 @@ extern "C" {
  * else, such as an RA session root.
  */
 
+typedef apr_array_header_t svn_rangelist_t;
 typedef apr_hash_t *svn_mergeinfo_t;
 typedef apr_hash_t *svn_mergeinfo_catalog_t;
 
@@ -295,8 +296,8 @@ svn_mergeinfo_remove2(svn_mergeinfo_t *m
  * @since New in 1.5.
  */
 svn_error_t *
-svn_rangelist_diff(apr_array_header_t **deleted, apr_array_header_t **added,
-                   const apr_array_header_t *from, const apr_array_header_t *to,
+svn_rangelist_diff(svn_rangelist_t **deleted, svn_rangelist_t **added,
+                   const svn_rangelist_t *from, const svn_rangelist_t *to,
                    svn_boolean_t consider_inheritance,
                    apr_pool_t *pool);
 
@@ -319,8 +320,8 @@ svn_rangelist_diff(apr_array_header_t **
  * @since New in 1.8.
  */
 svn_error_t *
-svn_rangelist_merge2(apr_array_header_t *rangelist,
-                     const apr_array_header_t *changes,
+svn_rangelist_merge2(svn_rangelist_t *rangelist,
+                     const svn_rangelist_t *changes,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool);
 
@@ -334,8 +335,8 @@ svn_rangelist_merge2(apr_array_header_t 
  */
 SVN_DEPRECATED
 svn_error_t *
-svn_rangelist_merge(apr_array_header_t **rangelist,
-                    const apr_array_header_t *changes,
+svn_rangelist_merge(svn_rangelist_t **rangelist,
+                    const svn_rangelist_t *changes,
                     apr_pool_t *pool);
 
 /** Removes @a eraser (the subtrahend) from @a whiteboard (the
@@ -352,8 +353,8 @@ svn_rangelist_merge(apr_array_header_t *
  * @since New in 1.5.
  */
 svn_error_t *
-svn_rangelist_remove(apr_array_header_t **output, const apr_array_header_t *eraser,
-                     const apr_array_header_t *whiteboard,
+svn_rangelist_remove(svn_rangelist_t **output, const svn_rangelist_t *eraser,
+                     const svn_rangelist_t *whiteboard,
                      svn_boolean_t consider_inheritance,
                      apr_pool_t *pool);
 
@@ -406,9 +407,9 @@ svn_mergeinfo_intersect(svn_mergeinfo_t 
  * @since New in 1.5.
  */
 svn_error_t *
-svn_rangelist_intersect(apr_array_header_t **rangelist,
-                        const apr_array_header_t *rangelist1,
-                        const apr_array_header_t *rangelist2,
+svn_rangelist_intersect(svn_rangelist_t **rangelist,
+                        const svn_rangelist_t *rangelist1,
+                        const svn_rangelist_t *rangelist2,
                         svn_boolean_t consider_inheritance,
                         apr_pool_t *pool);
 
@@ -423,7 +424,7 @@ svn_rangelist_intersect(apr_array_header
  * @since New in 1.5.
  */
 svn_error_t *
-svn_rangelist_reverse(apr_array_header_t *rangelist, apr_pool_t *pool);
+svn_rangelist_reverse(svn_rangelist_t *rangelist, apr_pool_t *pool);
 
 /** Take an array of svn_merge_range_t *'s in @a rangelist, and convert it
  * back to a text format rangelist in @a output.  If @a rangelist contains
@@ -433,7 +434,7 @@ svn_rangelist_reverse(apr_array_header_t
  */
 svn_error_t *
 svn_rangelist_to_string(svn_string_t **output,
-                        const apr_array_header_t *rangelist,
+                        const svn_rangelist_t *rangelist,
                         apr_pool_t *pool);
 
 /** Return a deep copy of @c svn_merge_range_t *'s in @a rangelist excluding
@@ -448,8 +449,8 @@ svn_rangelist_to_string(svn_string_t **o
  * @since New in 1.7.
  */
 svn_error_t *
-svn_rangelist_inheritable2(apr_array_header_t **inheritable_rangelist,
-                           const apr_array_header_t *rangelist,
+svn_rangelist_inheritable2(svn_rangelist_t **inheritable_rangelist,
+                           const svn_rangelist_t *rangelist,
                            svn_revnum_t start,
                            svn_revnum_t end,
                            svn_boolean_t inheritable,
@@ -463,8 +464,8 @@ svn_rangelist_inheritable2(apr_array_hea
  */
 SVN_DEPRECATED
 svn_error_t *
-svn_rangelist_inheritable(apr_array_header_t **inheritable_rangelist,
-                          const apr_array_header_t *rangelist,
+svn_rangelist_inheritable(svn_rangelist_t **inheritable_rangelist,
+                          const svn_rangelist_t *rangelist,
                           svn_revnum_t start,
                           svn_revnum_t end,
                           apr_pool_t *pool);
@@ -551,8 +552,8 @@ svn_mergeinfo_dup(svn_mergeinfo_t mergei
  *
  * @since New in 1.5.
  */
-apr_array_header_t *
-svn_rangelist_dup(const apr_array_header_t *rangelist, apr_pool_t *pool);
+svn_rangelist_t *
+svn_rangelist_dup(const svn_rangelist_t *rangelist, apr_pool_t *pool);
 
 
 /**

Modified: subversion/branches/master-passphrase/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_ra.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_ra.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_ra.h Thu Aug  2 19:09:21 2012
@@ -613,6 +613,17 @@ typedef struct svn_ra_session_t svn_ra_s
  * corrected_url is NULL, return an #SVN_ERR_RA_SESSION_URL_MISMATCH
  * error.  Allocate all returned items in @a pool.
  *
+ * The @a repos_URL need not point to the root of the repository: subject
+ * to authorization, it may point to any path within the repository, even
+ * a path at which no node exists in the repository.  The session will
+ * remember this URL as its "session URL" (also called "session root URL"),
+ * until changed by svn_ra_reparent().  Many RA functions take or return
+ * paths that are relative to the session URL.
+ *
+ * If a @a corrected_url is returned, it will point to the same path
+ * within the new repository root URL that @a repos_URL pointed to within
+ * the old repository root URL.
+ *
  * Return @c SVN_ERR_RA_UUID_MISMATCH if @a uuid is non-NULL and not equal
  * to the UUID of the repository at @c repos_URL.
  *
@@ -702,7 +713,7 @@ svn_ra_reparent(svn_ra_session_t *ra_ses
                 const char *url,
                 apr_pool_t *pool);
 
-/** Set @a *url to the repository URL to which @a ra_session was
+/** Set @a *url to the session URL -- the URL to which @a ra_session was
  * opened or most recently reparented.
  *
  * @since New in 1.5.
@@ -713,8 +724,8 @@ svn_ra_get_session_url(svn_ra_session_t 
                        apr_pool_t *pool);
 
 
-/** Convert @a url into a path relative to the URL at which @a ra_session
- * is parented, setting @a *rel_path to that value.  If @a url is not
+/** Convert @a url into a path relative to the session URL of @a ra_session,
+ * setting @a *rel_path to that value.  If @a url is not
  * a child of the session URL, return @c SVN_ERR_RA_ILLEGAL_URL.
  *
  * The returned path is uri decoded to allow using it with the ra or other

Modified: subversion/branches/master-passphrase/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/include/svn_wc.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/include/svn_wc.h (original)
+++ subversion/branches/master-passphrase/subversion/include/svn_wc.h Thu Aug  2 19:09:21 2012
@@ -1229,12 +1229,22 @@ typedef enum svn_wc_notify_action_t
    * @since New in 1.8. */
   svn_wc_notify_failed_obstruction,
 
-  /** Conflict resolver is starting or done.
+  /** Conflict resolver is starting.
    * This can be used by clients to detect when to display conflict summary
    * information, for example.
    * @since New in 1.8. */
   svn_wc_notify_conflict_resolver_starting,
-  svn_wc_notify_conflict_resolver_done
+
+  /** Conflict resolver is done.
+   * This can be used by clients to detect when to display conflict summary
+   * information, for example.
+   * @since New in 1.8. */
+  svn_wc_notify_conflict_resolver_done,
+
+  /** The current operation left local changes of something that was deleted
+   * The changes are available on (and below) the notified path
+   * @since New in 1.8. */
+  svn_wc_notify_left_local_modifications
 
 } svn_wc_notify_action_t;
 

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/diff.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/diff.c Thu Aug  2 19:09:21 2012
@@ -103,7 +103,7 @@ display_mergeinfo_diff(const char *old_m
        hi; hi = apr_hash_next(hi))
     {
       const char *from_path = svn__apr_hash_index_key(hi);
-      apr_array_header_t *merge_revarray = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
       svn_string_t *merge_revstr;
 
       svn_pool_clear(iterpool);
@@ -120,7 +120,7 @@ display_mergeinfo_diff(const char *old_m
        hi; hi = apr_hash_next(hi))
     {
       const char *from_path = svn__apr_hash_index_key(hi);
-      apr_array_header_t *merge_revarray = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *merge_revarray = svn__apr_hash_index_val(hi);
       svn_string_t *merge_revstr;
 
       svn_pool_clear(iterpool);

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/externals.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/externals.c Thu Aug  2 19:09:21 2012
@@ -59,10 +59,15 @@ relegate_dir_external(svn_wc_context_t *
                       const char *local_abspath,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
+                      svn_wc_notify_func2_t notify_func,
+                      void *notify_baton,
                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err = SVN_NO_ERROR;
 
+  SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, local_abspath,
+                                     FALSE, scratch_pool, scratch_pool));
+
   err = svn_wc__external_remove(wc_ctx, wri_abspath, local_abspath, FALSE,
                                 cancel_func, cancel_baton, scratch_pool);
   if (err && (err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
@@ -103,8 +108,33 @@ relegate_dir_external(svn_wc_context_t *
       /* Do our best, but no biggy if it fails. The rename will fail. */
       svn_error_clear(svn_io_remove_file2(new_path, TRUE, scratch_pool));
 
-      /* Rename. */
-      SVN_ERR(svn_io_file_rename(local_abspath, new_path, scratch_pool));
+      /* Rename. If this is still a working copy we should use the working
+         copy rename function (to release open handles) */
+      err = svn_wc__rename_wc(wc_ctx, local_abspath, new_path,
+                              scratch_pool);
+
+      if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+        {
+          svn_error_clear(err);
+
+          /* And if it is no longer a working copy, we should just rename
+             it */
+          err = svn_io_file_rename(local_abspath, new_path, scratch_pool);
+        }
+
+      /* ### TODO: We should notify the user about the rename */
+      if (notify_func)
+        {
+          svn_wc_notify_t *notify;
+
+          notify = svn_wc_create_notify(err ? local_abspath : new_path,
+                                        svn_wc_notify_left_local_modifications,
+                                        scratch_pool);
+          notify->kind = svn_node_dir;
+          notify->err = err;
+
+          notify_func(notify_baton, notify, scratch_pool);
+        }
     }
 
   return svn_error_trace(err);
@@ -174,31 +204,45 @@ switch_dir_external(const char *local_ab
               goto cleanup;
             }
 
+          /* We'd really prefer not to have to do a brute-force
+             relegation -- blowing away the current external working
+             copy and checking it out anew -- so we'll first see if we
+             can get away with a generally cheaper relocation (if
+             required) and switch-style update.
+
+             To do so, we need to know the repository root URL of the
+             external working copy as it currently sits. */
           SVN_ERR(svn_wc__node_get_repos_info(&repos_root_url, &repos_uuid,
                                               ctx->wc_ctx, local_abspath,
                                               pool, subpool));
           if (repos_root_url)
             {
-              /* URLs don't match.  Try to relocate (if necessary) and then
-                 switch. */
+              /* If the new external target URL is not obviously a
+                 child of the external working copy's current
+                 repository root URL... */
               if (! svn_uri__is_ancestor(repos_root_url, url))
                 {
                   const char *repos_root;
                   svn_ra_session_t *ra_session;
 
-                  /* Get the repos root of the new URL. */
-                  SVN_ERR(svn_client__open_ra_session_internal
-                          (&ra_session, NULL, url, NULL, NULL,
-                           FALSE, TRUE, ctx, subpool));
+                  /* ... then figure out precisely which repository
+                      root URL that target URL *is* a child of ... */
+                  SVN_ERR(svn_client__open_ra_session_internal(&ra_session,
+                                                               NULL, url, NULL,
+                                                               NULL, FALSE,
+                                                               TRUE, ctx,
+                                                               subpool));
                   SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root,
                                                  subpool));
 
+                  /* ... and use that to try to relocate the external
+                     working copy to the target location.  */
                   err = svn_client_relocate2(local_abspath, repos_root_url,
-                                             repos_root,
-                                             FALSE, ctx, subpool);
-                  /* If the relocation failed because the new URL points
-                     to another repository, then we need to relegate and
-                     check out a new WC. */
+                                             repos_root, FALSE, ctx, subpool);
+
+                  /* If the relocation failed because the new URL
+                     points to a totally different repository, we've
+                     no choice but to relegate and check out a new WC. */
                   if (err
                       && (err->apr_err == SVN_ERR_WC_INVALID_RELOCATION
                           || (err->apr_err
@@ -209,6 +253,10 @@ switch_dir_external(const char *local_ab
                     }
                   else if (err)
                     return svn_error_trace(err);
+
+                  /* If the relocation went without a hitch, we should
+                     have a new repository root URL. */
+                  repos_root_url = repos_root;
                 }
 
               SVN_ERR(svn_client__switch_internal(NULL, local_abspath, url,
@@ -247,12 +295,10 @@ switch_dir_external(const char *local_ab
   if (kind == svn_node_dir)
     {
       /* Buh-bye, old and busted ... */
-      SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, local_abspath,
-                                         FALSE, pool, pool));
-
       SVN_ERR(relegate_dir_external(ctx->wc_ctx, defining_abspath,
                                     local_abspath,
                                     ctx->cancel_func, ctx->cancel_baton,
+                                    ctx->notify_func2, ctx->notify_baton2,
                                     pool));
     }
   else
@@ -547,6 +593,17 @@ handle_external_item_removal(const svn_c
       notify->err = err;
 
       (ctx->notify_func2)(ctx->notify_baton2, notify, scratch_pool);
+
+      if (err && err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)
+        {
+          notify = svn_wc_create_notify(local_abspath,
+                                      svn_wc_notify_left_local_modifications,
+                                      scratch_pool);
+          notify->kind = svn_node_dir;
+          notify->err = err;
+
+          (ctx->notify_func2)(ctx->notify_baton2, notify, scratch_pool);
+        }
     }
 
   if (err && err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/merge.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/merge.c Thu Aug  2 19:09:21 2012
@@ -27,6 +27,7 @@
 
 /*** Includes ***/
 
+#include <assert.h>
 #include <apr_strings.h>
 #include <apr_tables.h>
 #include <apr_hash.h>
@@ -273,7 +274,7 @@ typedef struct merge_cmd_baton_t {
      See http://subversion.tigris.org/issues/show_bug.cgi?id=3432.
      Updated during each call to do_directory_merge().  May be NULL if there
      is no gap. */
-  apr_array_header_t *implicit_src_gap;
+  svn_rangelist_t *implicit_src_gap;
 
   svn_client_ctx_t *ctx;              /* Client context for callbacks, etc. */
 
@@ -363,6 +364,21 @@ typedef struct merge_cmd_baton_t {
 
 /*** Utilities ***/
 
+/* Return TRUE iff the session URL of RA_SESSION is equal to URL.  Useful in
+ * asserting preconditions. */
+static svn_boolean_t
+session_url_is(svn_ra_session_t *ra_session,
+               const char *url,
+               apr_pool_t *scratch_pool)
+{
+  const char *session_url;
+  svn_error_t *err
+    = svn_ra_get_session_url(ra_session, &session_url, scratch_pool);
+
+  SVN_ERR_ASSERT_NO_RETURN(! err);
+  return strcmp(url, session_url) == 0;
+}
+
 /* Return a new merge_source_t structure, allocated in RESULT_POOL,
  * initialized with deep copies of LOC1 and LOC2 and ANCESTRAL. */
 static merge_source_t *
@@ -807,7 +823,7 @@ split_mergeinfo_on_revision(svn_mergeinf
     {
       int i;
       const char *merge_source_path = svn__apr_hash_index_key(hi);
-      apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi);
 
       svn_pool_clear(iterpool);
 
@@ -829,7 +845,7 @@ split_mergeinfo_on_revision(svn_mergeinf
                  than REVISION.  Remove the younger rangelists from
                  *MERGEINFO and put them in *YOUNGER_MERGEINFO. */
               int j;
-              apr_array_header_t *younger_rangelist =
+              svn_rangelist_t *younger_rangelist =
                 apr_array_make(pool, 1, sizeof(svn_merge_range_t *));
 
               for (j = i; j < rangelist->nelts; j++)
@@ -1032,9 +1048,9 @@ filter_self_referential_mergeinfo(apr_ar
             {
               int j;
               const char *source_path = svn__apr_hash_index_key(hi);
-              apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+              svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi);
               const char *merge_source_url;
-              apr_array_header_t *adjusted_rangelist =
+              svn_rangelist_t *adjusted_rangelist =
                 apr_array_make(iterpool, 0, sizeof(svn_merge_range_t *));
 
               merge_source_url =
@@ -3194,8 +3210,8 @@ notification_receiver(void *baton, const
  * effect is to discard any non-inheritable input ranges.  Therefore the
  * ranges in *OUT_RANGELIST will always be inheritable. */
 static svn_error_t *
-rangelist_intersect_range(apr_array_header_t **out_rangelist,
-                          const apr_array_header_t *in_rangelist,
+rangelist_intersect_range(svn_rangelist_t **out_rangelist,
+                          const svn_rangelist_t *in_rangelist,
                           svn_revnum_t rev1,
                           svn_revnum_t rev2,
                           svn_boolean_t consider_inheritance,
@@ -3206,7 +3222,7 @@ rangelist_intersect_range(apr_array_head
 
   if (rev1 < rev2)
     {
-      apr_array_header_t *simple_rangelist =
+      svn_rangelist_t *simple_rangelist =
         svn_rangelist__initialize(rev1, rev2, TRUE, scratch_pool);
 
       SVN_ERR(svn_rangelist_intersect(out_rangelist,
@@ -3366,7 +3382,7 @@ adjust_deleted_subtree_ranges(svn_client
             }
           else
             {
-              apr_array_header_t *deleted_rangelist;
+              svn_rangelist_t *deleted_rangelist;
               svn_revnum_t rev_primary_url_deleted;
 
               /* PRIMARY_URL@older_rev exists, so it was deleted at some
@@ -3435,7 +3451,7 @@ adjust_deleted_subtree_ranges(svn_client
     }
   else /* PRIMARY_URL@peg_rev exists. */
     {
-      apr_array_header_t *non_existent_rangelist;
+      svn_rangelist_t *non_existent_rangelist;
       svn_location_segment_t *segment =
         APR_ARRAY_IDX(segments, (segments->nelts - 1),
                       svn_location_segment_t *);
@@ -3526,6 +3542,10 @@ fix_deleted_subtree_ranges(const merge_s
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_boolean_t is_rollback = source->loc2->rev < source->loc1->rev;
 
+  assert(session_url_is(ra_session,
+                        (is_rollback ? source->loc1 : source->loc2)->url,
+                        scratch_pool));
+
   /* CHILDREN_WITH_MERGEINFO is sorted in depth-first order, so
      start at index 1 to examine only subtrees. */
   for (i = 1; i < children_with_mergeinfo->nelts; i++)
@@ -3533,7 +3553,7 @@ fix_deleted_subtree_ranges(const merge_s
       svn_client__merge_path_t *child =
         APR_ARRAY_IDX(children_with_mergeinfo, i, svn_client__merge_path_t *);
       svn_client__merge_path_t *parent;
-      apr_array_header_t *deleted_rangelist, *added_rangelist;
+      svn_rangelist_t *deleted_rangelist, *added_rangelist;
 
       SVN_ERR_ASSERT(child);
       if (child->absent)
@@ -3885,7 +3905,7 @@ static svn_error_t *
 filter_merged_revisions(svn_client__merge_path_t *parent,
                         svn_client__merge_path_t *child,
                         const char *mergeinfo_path,
-                        apr_array_header_t *target_rangelist,
+                        svn_rangelist_t *target_rangelist,
                         svn_revnum_t revision1,
                         svn_revnum_t revision2,
                         svn_boolean_t child_inherits_implicit,
@@ -3894,7 +3914,7 @@ filter_merged_revisions(svn_client__merg
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *requested_rangelist,
+  svn_rangelist_t *requested_rangelist,
     *target_implicit_rangelist, *explicit_rangelist;
 
   /* Convert REVISION1 and REVISION2 to a rangelist.
@@ -3913,7 +3933,7 @@ filter_merged_revisions(svn_client__merg
 
   if (revision1 > revision2) /* This is a reverse merge. */
     {
-      apr_array_header_t *added_rangelist, *deleted_rangelist;
+      svn_rangelist_t *added_rangelist, *deleted_rangelist;
 
       /* The revert range and will need to be reversed for
          our svn_rangelist_* APIs to work properly. */
@@ -3969,7 +3989,7 @@ filter_merged_revisions(svn_client__merg
         }
       else /* We need to check CHILD's implicit mergeinfo. */
         {
-          apr_array_header_t *implicit_rangelist;
+          svn_rangelist_t *implicit_rangelist;
 
           SVN_ERR(ensure_implicit_mergeinfo(parent,
                                             child,
@@ -4146,7 +4166,7 @@ calculate_remaining_ranges(svn_client__m
                                                           scratch_pool);
   /* Intersection of TARGET_MERGEINFO and the merge history
      described by SOURCE. */
-  apr_array_header_t *target_rangelist;
+  svn_rangelist_t *target_rangelist;
   svn_revnum_t child_base_revision;
 
   /* Since this function should only be called when honoring mergeinfo and
@@ -4302,7 +4322,7 @@ find_gaps_in_merge_source_history(svn_re
     = (source->loc1->rev < source->loc2->rev) ? source->loc2 : source->loc1;
   const char *merge_src_fspath = svn_client__pathrev_fspath(primary_src,
                                                             scratch_pool);
-  apr_array_header_t *rangelist;
+  svn_rangelist_t *rangelist;
 
   SVN_ERR_ASSERT(source->ancestral);
 
@@ -4357,13 +4377,13 @@ find_gaps_in_merge_source_history(svn_re
     }
   else if (apr_hash_count(implicit_src_mergeinfo) > 1) /* Rename */
     {
-      apr_array_header_t *requested_rangelist =
+      svn_rangelist_t *requested_rangelist =
         svn_rangelist__initialize(MIN(source->loc1->rev, source->loc2->rev),
                                   MAX(source->loc1->rev, source->loc2->rev),
                                   TRUE, scratch_pool);
-      apr_array_header_t *implicit_rangelist =
+      svn_rangelist_t *implicit_rangelist =
         apr_array_make(scratch_pool, 2, sizeof(svn_merge_range_t *));
-      apr_array_header_t *gap_rangelist;
+      svn_rangelist_t *gap_rangelist;
 
       SVN_ERR(svn_rangelist__merge_many(implicit_rangelist,
                                         implicit_src_mergeinfo,
@@ -4693,8 +4713,8 @@ update_wc_mergeinfo(svn_mergeinfo_catalo
   for (hi = apr_hash_first(scratch_pool, merges); hi; hi = apr_hash_next(hi))
     {
       const char *local_abspath = svn__apr_hash_index_key(hi);
-      apr_array_header_t *ranges = svn__apr_hash_index_val(hi);
-      apr_array_header_t *rangelist;
+      svn_rangelist_t *ranges = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *rangelist;
       svn_error_t *err;
       const char *local_abspath_rel_to_target;
       const char *fspath;
@@ -4826,7 +4846,7 @@ update_wc_mergeinfo(svn_mergeinfo_catalo
    MERGEINFO_PATH to MERGE_B->target. */
 static svn_error_t *
 record_skips(const char *mergeinfo_path,
-             const apr_array_header_t *rangelist,
+             const svn_rangelist_t *rangelist,
              svn_boolean_t is_rollback,
              apr_hash_t *skipped_abspaths,
              merge_cmd_baton_t *merge_b,
@@ -6239,7 +6259,7 @@ log_changed_revs(void *baton,
 static void
 merge_range_find_extremes(svn_revnum_t *min_rev_p,
                           svn_revnum_t *max_rev_p,
-                          const apr_array_header_t *rangelist)
+                          const svn_rangelist_t *rangelist)
 {
   int i;
 
@@ -6305,16 +6325,16 @@ get_log(svn_ra_session_t *ra_session,
 
    Use POOL for temporary allocations.  */
 static svn_error_t *
-remove_noop_merge_ranges(apr_array_header_t **operative_ranges_p,
+remove_noop_merge_ranges(svn_rangelist_t **operative_ranges_p,
                          svn_ra_session_t *ra_session,
-                         const apr_array_header_t *ranges,
+                         const svn_rangelist_t *ranges,
                          apr_pool_t *pool)
 {
   int i;
   svn_revnum_t oldest_rev, youngest_rev;
   apr_array_header_t *changed_revs =
     apr_array_make(pool, ranges->nelts, sizeof(svn_revnum_t));
-  apr_array_header_t *operative_ranges =
+  svn_rangelist_t *operative_ranges =
     apr_array_make(ranges->pool, ranges->nelts, ranges->elt_size);
 
   /* Find the revision extremes of the RANGES we have. */
@@ -6502,7 +6522,7 @@ combine_range_with_segments(apr_array_he
 static svn_error_t *
 normalize_merge_sources_internal(apr_array_header_t **merge_sources_p,
                                  const svn_client__pathrev_t *source_loc,
-                                 const apr_array_header_t *merge_range_ts,
+                                 const svn_rangelist_t *merge_range_ts,
                                  svn_ra_session_t *ra_session,
                                  svn_client_ctx_t *ctx,
                                  apr_pool_t *result_pool,
@@ -6679,7 +6699,7 @@ static svn_error_t *
 normalize_merge_sources(apr_array_header_t **merge_sources_p,
                         const char *source_path_or_url,
                         const svn_client__pathrev_t *source_loc,
-                        const apr_array_header_t *ranges_to_merge,
+                        const svn_rangelist_t *ranges_to_merge,
                         svn_ra_session_t *ra_session,
                         svn_client_ctx_t *ctx,
                         apr_pool_t *result_pool,
@@ -6687,7 +6707,7 @@ normalize_merge_sources(apr_array_header
 {
   const char *source_abspath_or_url;
   svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
-  apr_array_header_t *merge_range_ts;
+  svn_rangelist_t *merge_range_ts;
   int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
@@ -6766,14 +6786,14 @@ normalize_merge_sources(apr_array_header
 
    Allocate *FILTERED_RANGELIST in POOL. */
 static svn_error_t *
-filter_natural_history_from_mergeinfo(apr_array_header_t **filtered_rangelist,
+filter_natural_history_from_mergeinfo(svn_rangelist_t **filtered_rangelist,
                                       const char *source_rel_path,
                                       svn_mergeinfo_t implicit_mergeinfo,
                                       svn_merge_range_t *requested_range,
                                       apr_pool_t *pool)
 {
   /* Make the REQUESTED_RANGE into a rangelist. */
-  apr_array_header_t *requested_rangelist =
+  svn_rangelist_t *requested_rangelist =
     svn_rangelist__initialize(requested_range->start, requested_range->end,
                               requested_range->inheritable, pool);
 
@@ -6784,7 +6804,7 @@ filter_natural_history_from_mergeinfo(ap
   if (implicit_mergeinfo
       && (requested_range->start < requested_range->end))
     {
-      apr_array_header_t *implied_rangelist =
+      svn_rangelist_t *implied_rangelist =
         apr_hash_get(implicit_mergeinfo, source_rel_path,
                      APR_HASH_KEY_STRING);
 
@@ -6871,7 +6891,7 @@ do_file_merge(svn_mergeinfo_catalog_t re
               merge_cmd_baton_t *merge_b,
               apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *remaining_ranges;
+  svn_rangelist_t *remaining_ranges;
   svn_client_ctx_t *ctx = merge_b->ctx;
   svn_merge_range_t range;
   svn_mergeinfo_t target_mergeinfo;
@@ -6948,7 +6968,7 @@ do_file_merge(svn_mergeinfo_catalog_t re
 
   if (!merge_b->record_only)
     {
-      apr_array_header_t *ranges_to_merge = remaining_ranges;
+      svn_rangelist_t *ranges_to_merge = remaining_ranges;
       const char *target_relpath = "";  /* relative to root of merge */
       int i;
 
@@ -7095,7 +7115,7 @@ do_file_merge(svn_mergeinfo_catalog_t re
     {
       const char *mergeinfo_path = svn_client__pathrev_fspath(primary_src,
                                                               scratch_pool);
-      apr_array_header_t *filtered_rangelist;
+      svn_rangelist_t *filtered_rangelist;
 
       /* Filter any ranges from TARGET_WCPATH's own history, there is no
          need to record this explicitly in mergeinfo, it is already part
@@ -7846,7 +7866,7 @@ record_mergeinfo_for_dir_merge(svn_merge
     {
       const char *child_repos_path;
       const char *child_merge_src_fspath;
-      apr_array_header_t *child_merge_rangelist;
+      svn_rangelist_t *child_merge_rangelist;
       apr_hash_t *child_merges;
       svn_client__merge_path_t *child =
                      APR_ARRAY_IDX(notify_b->children_with_mergeinfo, i,
@@ -7952,7 +7972,7 @@ record_mergeinfo_for_dir_merge(svn_merge
             {
               svn_error_t *err;
               svn_mergeinfo_t subtree_history_as_mergeinfo;
-              apr_array_header_t *child_merge_src_rangelist;
+              svn_rangelist_t *child_merge_src_rangelist;
               svn_client__pathrev_t *subtree_mergeinfo_pathrev
                 = svn_client__pathrev_create_with_relpath(
                     merge_b->target->loc.repos_root_url,
@@ -8113,7 +8133,7 @@ record_mergeinfo_for_added_subtrees(
           svn_node_kind_t added_path_kind;
           svn_mergeinfo_t merge_mergeinfo;
           svn_mergeinfo_t adds_history_as_mergeinfo;
-          apr_array_header_t *rangelist;
+          svn_rangelist_t *rangelist;
           const char *rel_added_path;
           const char *added_path_mergeinfo_fspath;
           svn_client__pathrev_t *added_path_pathrev;
@@ -8202,8 +8222,8 @@ typedef struct log_noop_baton_t
 
   /* Initially empty rangelists allocated in POOL. The rangelists are
    * populated across multiple invocations of log_noop_revs(). */
-  apr_array_header_t *operative_ranges;
-  apr_array_header_t *merged_ranges;
+  svn_rangelist_t *operative_ranges;
+  svn_rangelist_t *merged_ranges;
 
   /* Pool to store the rangelists. */
   apr_pool_t *pool;
@@ -8220,7 +8240,7 @@ typedef struct log_noop_baton_t
    This turns the special case of a single incoming younger range into O(1).
    */
 static svn_error_t *
-rangelist_merge_revision(apr_array_header_t *rangelist,
+rangelist_merge_revision(svn_rangelist_t *rangelist,
                          svn_revnum_t revision,
                          apr_pool_t *result_pool)
 {
@@ -8296,7 +8316,7 @@ log_noop_revs(void *baton,
       const char *fspath = svn__apr_hash_index_key(hi);
       const char *rel_path;
       const char *cwmi_abspath;
-      apr_array_header_t *paths_explicit_rangelist = NULL;
+      svn_rangelist_t *paths_explicit_rangelist = NULL;
       svn_boolean_t mergeinfo_inherited = FALSE;
 
       /* Adjust REL_PATH so it is relative to the merge source then use it to
@@ -8346,8 +8366,8 @@ log_noop_revs(void *baton,
 
       if (paths_explicit_rangelist)
         {
-          apr_array_header_t *intersecting_range;
-          apr_array_header_t *rangelist;
+          svn_rangelist_t *intersecting_range;
+          svn_rangelist_t *rangelist;
 
           rangelist = svn_rangelist__initialize(revision - 1, revision, TRUE,
                                                 scratch_pool);
@@ -8404,15 +8424,16 @@ remove_noop_subtree_ranges(const merge_s
   int i;
   svn_client__merge_path_t *root_child =
     APR_ARRAY_IDX(children_with_mergeinfo, 0, svn_client__merge_path_t *);
-  apr_array_header_t *requested_ranges;
-  apr_array_header_t *subtree_gap_ranges;
-  apr_array_header_t *subtree_remaining_ranges;
+  svn_rangelist_t *requested_ranges;
+  svn_rangelist_t *subtree_gap_ranges;
+  svn_rangelist_t *subtree_remaining_ranges;
   log_noop_baton_t log_gap_baton;
   svn_merge_range_t *oldest_gap_rev;
   svn_merge_range_t *youngest_gap_rev;
-  apr_array_header_t *inoperative_ranges;
+  svn_rangelist_t *inoperative_ranges;
   apr_pool_t *iterpool;
 
+  assert(session_url_is(ra_session, source->loc2->url, scratch_pool));
 
   /* This function is only intended to work with forward merges. */
   if (source->loc1->rev > source->loc2->rev)
@@ -9276,6 +9297,9 @@ merge_cousins_and_supplement_mergeinfo(c
      subtree mergeinfo, then this will help keep memory use in check. */
   apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
+  assert(session_url_is(URL1_ra_session, source->loc1->url, scratch_pool));
+  assert(session_url_is(URL2_ra_session, source->loc2->url, scratch_pool));
+
   SVN_ERR_ASSERT(svn_dirent_is_absolute(target->abspath));
   SVN_ERR_ASSERT(! source->ancestral);
 
@@ -10046,7 +10070,7 @@ find_unsynced_ranges(const svn_client__p
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *potentially_unmerged_ranges = NULL;
+  svn_rangelist_t *potentially_unmerged_ranges = NULL;
 
   /* Convert all the unmerged history to a rangelist. */
   if (apr_hash_count(unmerged_catalog))
@@ -10150,6 +10174,9 @@ find_youngest_merged_rev(svn_revnum_t *y
  * place, to include the natural history (implicit mergeinfo) of
  * SOURCE_PATHREV.  ### But make these additions in SCRATCH_POOL.
  *
+ * SOURCE_RA_SESSION is an RA session open to the repository containing
+ * SOURCE_PATHREV; it may be temporarily reparented within this function.
+ *
  * ### [JAF] This function is named '..._subroutine' simply because I
  *     factored it out based on code similarity, without knowing what it's
  *     purpose is.  We should clarify its purpose and choose a better name.
@@ -10252,6 +10279,9 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
   svn_mergeinfo_catalog_t new_catalog = apr_hash_make(result_pool);
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
+  assert(session_url_is(source_ra_session, source_loc->url, scratch_pool));
+  assert(session_url_is(target_ra_session, target->loc.url, scratch_pool));
+
   *youngest_merged_rev = SVN_INVALID_REVNUM;
 
   /* Examine the natural history of each path in the reintegrate target
@@ -10483,6 +10513,9 @@ calculate_left_hand_side(svn_client__pat
   svn_revnum_t youngest_merged_rev;
   svn_client__pathrev_t *yc_ancestor;
 
+  assert(session_url_is(source_ra_session, source_loc->url, scratch_pool));
+  assert(session_url_is(target_ra_session, target->loc.url, scratch_pool));
+
   /* Initialize our return variables. */
   *left_p = NULL;
 
@@ -10607,7 +10640,7 @@ calculate_left_hand_side(svn_client__pat
  * from SOURCE_LOC into the working copy at TARGET.
  *
  * SOURCE_RA_SESSION and TARGET_RA_SESSION are RA sessions opened to the
- * source and target branches respectively.
+ * URLs of SOURCE_LOC and TARGET->loc respectively.
  *
  * Set *SOURCE_P to
  * the source-left and source-right locations of the required merge.  Set
@@ -10635,6 +10668,9 @@ find_reintegrate_merge(merge_source_t **
   svn_error_t *err;
   apr_hash_t *subtrees_with_mergeinfo;
 
+  assert(session_url_is(source_ra_session, source_loc->url, scratch_pool));
+  assert(session_url_is(target_ra_session, target->loc.url, scratch_pool));
+
   /* As the WC tree is "pure", use its last-updated-to revision as
      the default revision for the left side of our merge, since that's
      what the repository sub-tree is required to be up to date with
@@ -10957,7 +10993,7 @@ svn_client_merge_reintegrate(const char 
 static svn_error_t *
 merge_peg_locked(const char *source_path_or_url,
                  const svn_opt_revision_t *source_peg_revision,
-                 const apr_array_header_t *ranges_to_merge,
+                 const svn_rangelist_t *ranges_to_merge,
                  const char *target_abspath,
                  svn_depth_t depth,
                  svn_boolean_t ignore_ancestry,
@@ -11095,7 +11131,7 @@ location_on_branch_at_rev(const branch_h
        hi = apr_hash_next(hi))
     {
       const char *fspath = svn__apr_hash_index_key(hi);
-      apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi);
       int i;
 
       for (i = 0; i < rangelist->nelts; i++)
@@ -11614,22 +11650,25 @@ do_symmetric_merge_locked(const svn_clie
   if (merge->mid)
     {
       merge_source_t source;
-      svn_ra_session_t *ra_session = NULL;
+      svn_ra_session_t *base_ra_session = NULL;
+      svn_ra_session_t *right_ra_session = NULL;
+      svn_ra_session_t *target_ra_session = NULL;
+
+      SVN_ERR(ensure_ra_session_url(&base_ra_session, merge->base->url,
+                                    ctx, scratch_pool));
+      SVN_ERR(ensure_ra_session_url(&right_ra_session, merge->right->url,
+                                    ctx, scratch_pool));
+      SVN_ERR(ensure_ra_session_url(&target_ra_session, target->loc.url,
+                                    ctx, scratch_pool));
 
       /* Check for and reject any abnormalities -- such as revisions that
        * have not yet been merged in the opposite direction -- that a
        * 'reintegrate' merge would have rejected. */
       {
         merge_source_t *source2;
-        svn_ra_session_t *source_ra_session = NULL;
-        svn_ra_session_t *target_ra_session = NULL;
 
-        SVN_ERR(ensure_ra_session_url(&source_ra_session, merge->right->url,
-                                      ctx, scratch_pool));
-        SVN_ERR(ensure_ra_session_url(&target_ra_session, target->loc.url,
-                                      ctx, scratch_pool));
         SVN_ERR(find_reintegrate_merge(&source2, NULL,
-                                       source_ra_session, merge->right,
+                                       right_ra_session, merge->right,
                                        target_ra_session, target,
                                        ctx, scratch_pool, scratch_pool));
       }
@@ -11638,11 +11677,9 @@ do_symmetric_merge_locked(const svn_clie
       source.loc2 = merge->right;
       source.ancestral = (merge->mid == NULL);
 
-      SVN_ERR(ensure_ra_session_url(&ra_session, source.loc1->url,
-                                    ctx, scratch_pool));
-
       err = merge_cousins_and_supplement_mergeinfo(target,
-                                                   ra_session, ra_session,
+                                                   base_ra_session,
+                                                   right_ra_session,
                                                    &source, merge->yca,
                                                    TRUE /* same_repos */,
                                                    depth, ignore_ancestry,

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.c Thu Aug  2 19:09:21 2012
@@ -1258,7 +1258,7 @@ struct filter_log_entry_baton_t
   /* A rangelist describing all the revisions potentially merged or
      potentially eligible for merging (see FILTERING_MERGED) based on
      the target's explicit or inherited mergeinfo. */
-  const apr_array_header_t *rangelist;
+  const svn_rangelist_t *rangelist;
 
   /* The wrapped svn_log_entry_receiver_t callback and baton which
      filter_log_entry_with_rangelist() is acting as a filter for. */
@@ -1290,7 +1290,7 @@ filter_log_entry_with_rangelist(void *ba
                                 apr_pool_t *pool)
 {
   struct filter_log_entry_baton_t *fleb = baton;
-  apr_array_header_t *intersection, *this_rangelist;
+  svn_rangelist_t *intersection, *this_rangelist;
 
   if (fleb->ctx->cancel_func)
     SVN_ERR(fleb->ctx->cancel_func(fleb->ctx->cancel_baton));
@@ -1331,7 +1331,7 @@ filter_log_entry_with_rangelist(void *ba
     {
       apr_hash_index_t *hi;
       svn_boolean_t all_subtrees_have_this_rev = TRUE;
-      apr_array_header_t *this_rev_rangelist =
+      svn_rangelist_t *this_rev_rangelist =
         svn_rangelist__initialize(log_entry->revision - 1,
                                   log_entry->revision, TRUE, pool);
       apr_pool_t *iterpool = svn_pool_create(pool);
@@ -1404,7 +1404,7 @@ filter_log_entry_with_rangelist(void *ba
           if (ancestor_is_self /* Explicit mergeinfo on TARGET_PATH_AFFECTED */
               && (change->action != 'M'))
             {
-              apr_array_header_t *rangelist = apr_hash_get(
+              svn_rangelist_t *rangelist = apr_hash_get(
                 nearest_ancestor_mergeinfo, path, APR_HASH_KEY_STRING);
               svn_merge_range_t *youngest_range = APR_ARRAY_IDX(
                 rangelist, rangelist->nelts - 1, svn_merge_range_t *);
@@ -1423,7 +1423,7 @@ filter_log_entry_with_rangelist(void *ba
                    hi2 = apr_hash_next(hi2))
                 {
                   const char *mergeinfo_path = svn__apr_hash_index_key(hi2);
-                  apr_array_header_t *rangelist = svn__apr_hash_index_val(hi2);
+                  svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi2);
 
                   /* Does the mergeinfo for PATH reflect if
                      LOG_ENTRY->REVISION was previously merged
@@ -1497,7 +1497,7 @@ static svn_error_t *
 logs_for_mergeinfo_rangelist(const char *source_url,
                              const apr_array_header_t *merge_source_fspaths,
                              svn_boolean_t filtering_merged,
-                             const apr_array_header_t *rangelist,
+                             const svn_rangelist_t *rangelist,
                              svn_mergeinfo_catalog_t target_mergeinfo_catalog,
                              const char *target_fspath,
                              svn_boolean_t discover_changed_paths,
@@ -1648,8 +1648,8 @@ svn_client_mergeinfo_log2(svn_boolean_t 
 
   svn_mergeinfo_t source_history;
   svn_mergeinfo_t target_history;
-  apr_array_header_t *master_noninheritable_rangelist;
-  apr_array_header_t *master_inheritable_rangelist;
+  svn_rangelist_t *master_noninheritable_rangelist;
+  svn_rangelist_t *master_inheritable_rangelist;
   apr_array_header_t *merge_source_fspaths =
     apr_array_make(scratch_pool, 1, sizeof(const char *));
   apr_hash_index_t *hi_catalog;
@@ -1884,7 +1884,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
         {
           /* The inheritable rangelist merged from SUBTREE_SOURCE_HISTORY
              to SUBTREE_PATH. */
-          apr_array_header_t *subtree_merged_rangelist =
+          svn_rangelist_t *subtree_merged_rangelist =
             apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));
 
           SVN_ERR(svn_rangelist__merge_many(master_inheritable_rangelist,
@@ -1921,9 +1921,9 @@ svn_client_mergeinfo_log2(svn_boolean_t 
            hi;
            hi = apr_hash_next(hi))
         {
-          apr_array_header_t *deleted_rangelist;
-          apr_array_header_t *added_rangelist;
-          apr_array_header_t *subtree_merged_rangelist =
+          svn_rangelist_t *deleted_rangelist;
+          svn_rangelist_t *added_rangelist;
+          svn_rangelist_t *subtree_merged_rangelist =
             svn__apr_hash_index_val(hi);
 
           svn_pool_clear(iterpool);
@@ -1959,7 +1959,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
   else
     {
       /* Create the starting rangelist for what might be eligible. */
-      apr_array_header_t *source_master_rangelist =
+      svn_rangelist_t *source_master_rangelist =
         apr_array_make(scratch_pool, 1, sizeof(svn_merge_range_t *));
 
       SVN_ERR(svn_rangelist__merge_many(source_master_rangelist,
@@ -1996,7 +1996,7 @@ svn_client_mergeinfo_log2(svn_boolean_t 
         = APR_ARRAY_IDX(master_inheritable_rangelist,
                         master_inheritable_rangelist->nelts - 1,
                         svn_merge_range_t *);
-      apr_array_header_t *youngest_rangelist =
+      svn_rangelist_t *youngest_rangelist =
         svn_rangelist__initialize(youngest_range->end - 1,
                                   youngest_range->end,
                                   youngest_range->inheritable,
@@ -2007,9 +2007,9 @@ svn_client_mergeinfo_log2(svn_boolean_t 
            hi = apr_hash_next(hi))
         {
           const char *key = svn__apr_hash_index_key(hi);
-          apr_array_header_t *subtree_merged_rangelist =
+          svn_rangelist_t *subtree_merged_rangelist =
             svn__apr_hash_index_val(hi);
-          apr_array_header_t *intersecting_rangelist;
+          svn_rangelist_t *intersecting_rangelist;
 
           svn_pool_clear(iterpool);
           SVN_ERR(svn_rangelist_intersect(&intersecting_rangelist,

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.h?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/mergeinfo.h Thu Aug  2 19:09:21 2012
@@ -65,7 +65,7 @@ typedef struct svn_client__merge_path_t
      with the youngest start revisions come first.  In both the forward and
      reverse merge cases the ranges should never overlap.  This rangelist
      may be empty but should never be NULL unless ABSENT is true. */
-  apr_array_header_t *remaining_ranges;
+  svn_rangelist_t *remaining_ranges;
 
   svn_mergeinfo_t pre_merge_mergeinfo;  /* Explicit or inherited mergeinfo
                                            on ABSPATH prior to a merge.

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/ra.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/ra.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/ra.c Thu Aug  2 19:09:21 2012
@@ -896,8 +896,8 @@ svn_client__get_youngest_common_ancestor
     {
       const char *path = svn__apr_hash_index_key(hi);
       apr_ssize_t path_len = svn__apr_hash_index_klen(hi);
-      apr_array_header_t *ranges1 = svn__apr_hash_index_val(hi);
-      apr_array_header_t *ranges2, *common;
+      svn_rangelist_t *ranges1 = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *ranges2, *common;
 
       ranges2 = apr_hash_get(history2, path, path_len);
       if (ranges2)

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/relocate.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/relocate.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/relocate.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/relocate.c Thu Aug  2 19:09:21 2012
@@ -139,7 +139,6 @@ relocate_externals(const char *local_abs
                    apr_array_header_t *ext_desc,
                    const char *old_parent_repos_root_url,
                    const char *new_parent_repos_root_url,
-                   svn_boolean_t ignore_externals,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
 {
@@ -199,7 +198,7 @@ relocate_externals(const char *local_abs
         SVN_ERR(svn_client_relocate2(target_abspath,
                                      old_parent_repos_root_url,
                                      new_parent_repos_root_url,
-                                     ignore_externals, ctx, iterpool));
+                                     FALSE, ctx, iterpool));
     }
 
   svn_pool_destroy(iterpool);
@@ -281,8 +280,7 @@ svn_client_relocate2(const char *wcroot_
                                                   iterpool));
       if (ext_desc->nelts)
         SVN_ERR(relocate_externals(this_abspath, ext_desc, old_repos_root_url,
-                                   new_repos_root_url, ignore_externals, ctx,
-                                   iterpool));
+                                   new_repos_root_url, ctx, iterpool));
     }
 
   svn_pool_destroy(iterpool);

Modified: subversion/branches/master-passphrase/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_client/switch.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_client/switch.c Thu Aug  2 19:09:21 2012
@@ -226,7 +226,7 @@ switch_internal(svn_revnum_t *result_rev
                                 SVN_RA_CAPABILITY_DEPTH, pool));
 
   dfb.ra_session = ra_session;
-  SVN_ERR(svn_ra_get_session_url(ra_session, &dfb.anchor_url, pool));
+  dfb.anchor_url = anchor_url;
   dfb.target_revision = switch_loc->rev;
 
   SVN_ERR(svn_wc__get_switch_editor(&switch_editor, &switch_edit_baton,

Modified: subversion/branches/master-passphrase/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_fs_fs/fs_fs.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_fs_fs/fs_fs.c Thu Aug  2 19:09:21 2012
@@ -1836,22 +1836,30 @@ open_pack_or_rev_file(apr_file_t **file,
         err = svn_io_file_open(file, path,
                               APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
 
-      if (err && APR_STATUS_IS_ENOENT(err->apr_err)
-          && ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+      if (err && APR_STATUS_IS_ENOENT(err->apr_err))
         {
-          /* Could not open the file. This may happen if the
-           * file once existed but got packed later. */
-          svn_error_clear(err);
+          if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+            {
+              /* Could not open the file. This may happen if the
+               * file once existed but got packed later. */
+              svn_error_clear(err);
 
-          /* if that was our 2nd attempt, leave it at that. */
-          if (retry)
-            return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
-                                    _("No such revision %ld"), rev);
+              /* if that was our 2nd attempt, leave it at that. */
+              if (retry)
+                return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                                         _("No such revision %ld"), rev);
 
-          /* We failed for the first time. Refresh cache & retry. */
-          SVN_ERR(update_min_unpacked_rev(fs, pool));
+              /* We failed for the first time. Refresh cache & retry. */
+              SVN_ERR(update_min_unpacked_rev(fs, pool));
 
-          retry = TRUE;
+              retry = TRUE;
+            }
+          else
+            {
+              svn_error_clear(err);
+              return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                                       _("No such revision %ld"), rev);
+            }
         }
       else
         {
@@ -7367,16 +7375,23 @@ write_final_rev(const svn_fs_id_t **new_
     {
       apr_pool_t *subpool;
       apr_hash_t *entries, *str_entries;
-      apr_hash_index_t *hi;
+      apr_array_header_t *sorted_entries;
+      int i;
 
       /* This is a directory.  Write out all the children first. */
       subpool = svn_pool_create(pool);
 
       SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, noderev, pool));
-
-      for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+      /* For the sake of the repository administrator sort the entries
+         so that the final file is deterministic and repeatable,
+         however the rest of the FSFS code doesn't require any
+         particular order here. */
+      sorted_entries = svn_sort__hash(entries, svn_sort_compare_items_lexically,
+                                      pool);
+      for (i = 0; i < sorted_entries->nelts; ++i)
         {
-          svn_fs_dirent_t *dirent = svn__apr_hash_index_val(hi);
+          svn_fs_dirent_t *dirent = APR_ARRAY_IDX(sorted_entries, i,
+                                                  svn_sort__item_t).value;
 
           svn_pool_clear(subpool);
           SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
@@ -7546,19 +7561,25 @@ write_final_changed_path_info(apr_off_t 
 {
   apr_hash_t *changed_paths;
   apr_off_t offset;
-  apr_hash_index_t *hi;
   apr_pool_t *iterpool = svn_pool_create(pool);
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_boolean_t include_node_kinds =
       ffd->format >= SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT;
+  apr_array_header_t *sorted_changed_paths;
+  int i;
 
   SVN_ERR(get_file_offset(&offset, file, pool));
 
   SVN_ERR(svn_fs_fs__txn_changes_fetch(&changed_paths, fs, txn_id, pool));
+  /* For the sake of the repository administrator sort the changes so
+     that the final file is deterministic and repeatable, however the
+     rest of the FSFS code doesn't require any particular order here. */
+  sorted_changed_paths = svn_sort__hash(changed_paths,
+                                        svn_sort_compare_items_lexically, pool);
 
   /* Iterate through the changed paths one at a time, and convert the
      temporary node-id into a permanent one for each change entry. */
-  for (hi = apr_hash_first(pool, changed_paths); hi; hi = apr_hash_next(hi))
+  for (i = 0; i < sorted_changed_paths->nelts; ++i)
     {
       node_revision_t *noderev;
       const svn_fs_id_t *id;
@@ -7567,8 +7588,8 @@ write_final_changed_path_info(apr_off_t 
 
       svn_pool_clear(iterpool);
 
-      change = svn__apr_hash_index_val(hi);
-      path = svn__apr_hash_index_key(hi);
+      change = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).value;
+      path = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).key;
 
       id = change->node_rev_id;
 
@@ -8597,9 +8618,17 @@ recover_body(void *baton, apr_pool_t *po
                                max_rev);
     }
 
-  /* Prune younger-than-(newfound-youngest) revisions from the rep cache. */
-  if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
-    SVN_ERR(svn_fs_fs__del_rep_reference(fs, max_rev, pool));
+  /* Prune younger-than-(newfound-youngest) revisions from the rep
+     cache if sharing is enabled taking care not to create the cache
+     if it does not exist. */
+  if (ffd->rep_sharing_allowed)
+    {
+      svn_boolean_t rep_cache_exists;
+
+      SVN_ERR(svn_fs_fs__exists_rep_cache(&rep_cache_exists, fs, pool));
+      if (rep_cache_exists)
+        SVN_ERR(svn_fs_fs__del_rep_reference(fs, max_rev, pool));
+    }
 
   /* Now store the discovered youngest revision, and the next IDs if
      relevant, in a new 'current' file. */

Modified: subversion/branches/master-passphrase/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_fs_fs/tree.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_fs_fs/tree.c Thu Aug  2 19:09:21 2012
@@ -3881,7 +3881,6 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
     const svn_fs_id_t *pred_id;
     dag_node_t *pred;
     svn_revnum_t pred_rev;
-    svn_revnum_t delta;
 
     /* Only r0 should have no predecessor. */
     SVN_ERR(svn_fs_fs__dag_get_predecessor_id(&pred_id, frd->root_dir));
@@ -3899,28 +3898,12 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
       {
         SVN_ERR(svn_fs_fs__dag_get_node(&pred, root->fs, pred_id, pool));
         SVN_ERR(svn_fs_fs__dag_get_revision(&pred_rev, pred, pool));
-
-        /* Issue #4129: bogus predecessors. */
-        /* Check 1: predecessor must be an earlier revision.
-         */
-        if (pred_rev >= root->rev)
-          return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                                   "r%ld's root node's predecessor is r%ld"
-                                   " but must be earlier revision",
-                                   root->rev, pred_rev);
-
-        /* Check 2: distances must be a power of 2.
-         * Note that this condition is not defined by the FSFS format but
-         * merely a byproduct of the current implementation. Therefore,
-         * it may help to spot corruptions for the time being but might
-         * need to be removed / relaxed in later versions.
-         */
-        delta = root->rev - pred_rev;
-        if (delta & (delta - 1))
+        if (pred_rev+1 != root->rev)
+          /* Issue #4129. */
           return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                    "r%ld's root node's predecessor is r%ld"
-                                   " but the delta must be a power of 2",
-                                   root->rev, pred_rev);
+                                   " but should be r%ld",
+                                   root->rev, pred_rev, root->rev - 1);
       }
   }
 

Modified: subversion/branches/master-passphrase/subversion/libsvn_fs_util/fs-util.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_fs_util/fs-util.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_fs_util/fs-util.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_fs_util/fs-util.c Thu Aug  2 19:09:21 2012
@@ -163,7 +163,7 @@ svn_fs__append_to_merged_froms(svn_merge
   for (hi = apr_hash_first(pool, input); hi; hi = apr_hash_next(hi))
     {
       const char *path = svn__apr_hash_index_key(hi);
-      apr_array_header_t *rangelist = svn__apr_hash_index_val(hi);
+      svn_rangelist_t *rangelist = svn__apr_hash_index_val(hi);
 
       apr_hash_set(*output, svn_fspath__join(path, rel_path, pool),
                    APR_HASH_KEY_STRING, svn_rangelist_dup(rangelist, pool));

Modified: subversion/branches/master-passphrase/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/libsvn_repos/load-fs-vtable.c?rev=1368653&r1=1368652&r2=1368653&view=diff
==============================================================================
--- subversion/branches/master-passphrase/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/master-passphrase/subversion/libsvn_repos/load-fs-vtable.c Thu Aug  2 19:09:21 2012
@@ -264,7 +264,7 @@ renumber_mergeinfo_revs(svn_string_t **f
   for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
     {
       const char *merge_source;
-      apr_array_header_t *rangelist;
+      svn_rangelist_t *rangelist;
       struct parse_baton *pb = rb->pb;
       int i;
       const void *key;