subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1238422 [1/2] - in /subversion/branches/ev2-export: ./ subversion/bindings/javahl/ subversion/bindings/swig/python/libsvn_swig_py/ subversion/bindings/swig/python/tests/ subversion/include/ subversion/include/private/ subversion/libsvn_cli...
Date Tue, 31 Jan 2012 12:07:07 GMT
Author: hwright
Date: Tue Jan 31 12:07:06 2012
New Revision: 1238422

URL: http://svn.apache.org/viewvc?rev=1238422&view=rev
Log:
On the ev2-export branch:
Bring up-to-date with trunk.

Added:
    subversion/branches/ev2-export/subversion/bindings/javahl/Manifest.in
      - copied unchanged from r1238417, subversion/trunk/subversion/bindings/javahl/Manifest.in
    subversion/branches/ev2-export/tools/dev/gdb-py/
      - copied from r1238417, subversion/trunk/tools/dev/gdb-py/
Modified:
    subversion/branches/ev2-export/   (props changed)
    subversion/branches/ev2-export/CHANGES
    subversion/branches/ev2-export/Makefile.in
    subversion/branches/ev2-export/subversion/bindings/javahl/   (props changed)
    subversion/branches/ev2-export/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/branches/ev2-export/subversion/bindings/swig/python/tests/mergeinfo.py
    subversion/branches/ev2-export/subversion/include/private/svn_repos_private.h
    subversion/branches/ev2-export/subversion/include/svn_editor.h
    subversion/branches/ev2-export/subversion/include/svn_io.h
    subversion/branches/ev2-export/subversion/libsvn_client/copy.c
    subversion/branches/ev2-export/subversion/libsvn_client/merge.c
    subversion/branches/ev2-export/subversion/libsvn_delta/compat.c
    subversion/branches/ev2-export/subversion/libsvn_delta/editor.c
    subversion/branches/ev2-export/subversion/libsvn_ra_neon/session.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
    subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
    subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/ev2-export/subversion/libsvn_repos/commit.c
    subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c
    subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c
    subversion/branches/ev2-export/subversion/libsvn_subr/ssl_server_trust_providers.c
    subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c
    subversion/branches/ev2-export/subversion/mod_dav_svn/liveprops.c
    subversion/branches/ev2-export/subversion/mod_dav_svn/reports/update.c
    subversion/branches/ev2-export/subversion/svnrdump/dump_editor.c
    subversion/branches/ev2-export/subversion/svnrdump/svnrdump.c
    subversion/branches/ev2-export/subversion/svnrdump/svnrdump.h
    subversion/branches/ev2-export/subversion/tests/cmdline/externals_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/log_tests_data/merge_history_repo.png
    subversion/branches/ev2-export/subversion/tests/cmdline/merge_tests.py
    subversion/branches/ev2-export/subversion/tests/cmdline/svntest/factory.py
    subversion/branches/ev2-export/tools/client-side/svnmucc/svnmucc.c
    subversion/branches/ev2-export/tools/dev/gdb-py/svndbg/   (props changed)
    subversion/branches/ev2-export/tools/dist/backport.pl

Propchange: subversion/branches/ev2-export/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jan 31 12:07:06 2012
@@ -57,4 +57,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1231319-1233566
+/subversion/trunk:1231319-1238417

Modified: subversion/branches/ev2-export/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/CHANGES?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/CHANGES (original)
+++ subversion/branches/ev2-export/CHANGES Tue Jan 31 12:07:06 2012
@@ -37,6 +37,30 @@ http://svn.apache.org/repos/asf/subversi
     *
 
 
+Version 1.7.3
+(XX XXX 2012, from /branches/1.7.x)
+http://svn.apache.org/repos/asf/subversion/tags/1.7.3
+
+  User-visible changes:
+    * fix segfault on 'svn rm $ROOT_URL' (issue #4074)
+    * replace a couple of assertions in favor of errors (r1207858, -949)
+    * fix a server assert after being upgraded (r1210195)
+    * fix segfault on 'svn mkdir svn://localhost' (r1211483)
+    * make 'svnadmin recover' prune the rep cache (r1213331, et al)
+    * make svnmucc use values from --config-dir option
+    * update and clarify the merge help text (r1154121, et al)
+    * replace wc assertion with informative error (r1222521, -693)
+    * copy permissions correctly for FSFS dirs (r1229252)
+    * improve 'svn log --with-all-revprops' over ra-dav (issue #4082)
+    * fix segfault when remapping a file external (issue #4093)
+    * fix segfault caused by obstructing unversioned dir (r1229677)
+    * fix regression on first update of external dir with '-r' (issue #4053) 
+
+  Developer-visible changes:
+    * JavaHL: Add missing notify action, fixing an exception (r1221793)
+    * fix spurious test suite failure (r1220742, -50)
+
+
 Version 1.7.2
 (02 Dec 2011, from /branches/1.7.x)
 http://svn.apache.org/repos/asf/subversion/tags/1.7.2

Modified: subversion/branches/ev2-export/Makefile.in
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/Makefile.in?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/Makefile.in (original)
+++ subversion/branches/ev2-export/Makefile.in Tue Jan 31 12:07:06 2012
@@ -297,8 +297,11 @@ SWIG_RB_SRC_DIR = $(abs_srcdir)/subversi
 
 ### Automate JAR creation using Makefile generator's javahl-java.jar
 ### property.  Enhance generator to support JAR installation.
+JAVAHL_MANIFEST_IN = $(abs_srcdir)/subversion/bindings/javahl/Manifest.in
+JAVAHL_MANIFEST = subversion/bindings/javahl/Manifest
 INSTALL_EXTRA_JAVAHL_JAVA=\
-	$(JAR) cf $(JAVAHL_JAR) -C subversion/bindings/javahl/classes org; \
+	sed s/%bundleVersion/$(PACKAGE_VERSION)/ $(JAVAHL_MANIFEST_IN) > $(JAVAHL_MANIFEST); \
+	$(JAR) cfm $(JAVAHL_JAR) $(JAVAHL_MANIFEST) -C subversion/bindings/javahl/classes org; \
 	$(INSTALL_DATA) $(JAVAHL_JAR) $(DESTDIR)$(javahl_javadir);
 
 INSTALL_EXTRA_JAVAHL_LIB=@INSTALL_EXTRA_JAVAHL_LIB@

Propchange: subversion/branches/ev2-export/subversion/bindings/javahl/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Jan 31 12:07:06 2012
@@ -3,3 +3,4 @@ classes
 include
 svn-javahl.jar
 test-work
+Manifest

Modified: subversion/branches/ev2-export/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/ev2-export/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Tue Jan 31 12:07:06 2012
@@ -657,10 +657,22 @@ static PyObject *convert_rangelist(void 
   apr_array_header_t *array = value;
 
   list = PyList_New(0);
+  if (list == NULL)
+    return NULL;
+
   for (i = 0; i < array->nelts; i++)
     {
       svn_merge_range_t *range = APR_ARRAY_IDX(array, i, svn_merge_range_t *);
-      if (PyList_Append(list, convert_to_swigtype(range, ctx, py_pool)) == -1)
+      PyObject *obj;
+      int result;
+
+      obj = convert_to_swigtype(range, ctx, py_pool);
+      if (obj == NULL)
+        goto error;
+
+      result = PyList_Append(list, obj);
+      Py_DECREF(obj);
+      if (result == -1)
         goto error;
     }
   return list;

Modified: subversion/branches/ev2-export/subversion/bindings/swig/python/tests/mergeinfo.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/bindings/swig/python/tests/mergeinfo.py?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/bindings/swig/python/tests/mergeinfo.py (original)
+++ subversion/branches/ev2-export/subversion/bindings/swig/python/tests/mergeinfo.py Tue Jan 31 12:07:06 2012
@@ -18,7 +18,7 @@
 # under the License.
 #
 #
-import unittest, os
+import unittest, os, sys, gc
 from svn import core, repos, fs
 import utils
 
@@ -29,6 +29,15 @@ class RevRange:
     self.start = start
     self.end = end
 
+def get_svn_merge_range_t_objects():
+  """Returns a list 'svn_merge_range_t' objects being tracked by the
+     garbage collector, used for detecting memory leaks."""
+  return [
+    o for o in gc.get_objects()
+      if hasattr(o, '__class__') and
+        o.__class__.__name__ == 'svn_merge_range_t'
+  ]
+
 class SubversionMergeinfoTestCase(unittest.TestCase):
   """Test cases for mergeinfo"""
 
@@ -116,6 +125,53 @@ class SubversionMergeinfoTestCase(unitte
       }
     self.compare_mergeinfo_catalogs(mergeinfo, expected_mergeinfo)
 
+  def test_mergeinfo_leakage__incorrect_range_t_refcounts(self):
+    """Ensure that the ref counts on svn_merge_range_t objects returned by
+       svn_mergeinfo_parse() are correct."""
+    # When reference counting is working properly, each svn_merge_range_t in
+    # the returned mergeinfo will have a ref count of 1...
+    mergeinfo = core.svn_mergeinfo_parse(self.TEXT_MERGEINFO1)
+    for (path, rangelist) in mergeinfo.items():
+      # ....and now 2 (incref during iteration of rangelist)
+
+      for (i, r) in enumerate(rangelist):
+        # ....and now 3 (incref during iteration of each range object)
+
+        refcount = sys.getrefcount(r)
+        # ....and finally, 4 (getrefcount() also increfs)
+        expected = 4
+
+        # Note: if path and index are not '/trunk' and 0 respectively, then
+        # only some of the range objects are leaking, which is, as far as
+        # leaks go, even more impressive.
+        self.assertEquals(refcount, expected, (
+          "Memory leak!  Expected a ref count of %d for svn_merge_range_t "
+          "object, but got %d instead (path: %s, index: %d).  Probable "
+          "cause: incorrect Py_INCREF/Py_DECREF usage in libsvn_swig_py/"
+          "swigutil_py.c." % (expected, refcount, path, i)))
+
+    del mergeinfo
+    gc.collect()
+
+  def test_mergeinfo_leakage__lingering_range_t_objects_after_del(self):
+    """Ensure that there are no svn_merge_range_t objects being tracked by
+       the garbage collector after we explicitly `del` the results returned
+       by svn_mergeinfo_parse().  We call gc.collect() to force an explicit
+       garbage collection cycle after the `del`;
+       if our reference counts are correct, the allocated svn_merge_range_t
+       objects will be garbage collected and thus, not appear in the list of
+       objects returned by gc.get_objects()."""
+    mergeinfo = core.svn_mergeinfo_parse(self.TEXT_MERGEINFO1)
+    del mergeinfo
+    gc.collect()
+    lingering = get_svn_merge_range_t_objects()
+    self.assertEquals(lingering, list(), (
+      "Memory leak!  Found lingering svn_merge_range_t objects left over from "
+      "our call to svn_mergeinfo_parse(), even though we explicitly deleted "
+      "the returned mergeinfo object.  Probable cause: incorrect Py_INCREF/"
+      "Py_DECREF usage in libsvn_swig_py/swigutil_py.c.  Lingering objects:\n"
+      "%s" % lingering))
+
   def inspect_mergeinfo_dict(self, mergeinfo, merge_source, nbr_rev_ranges):
     rangelist = mergeinfo.get(merge_source)
     self.inspect_rangelist_tuple(rangelist, nbr_rev_ranges)

Modified: subversion/branches/ev2-export/subversion/include/private/svn_repos_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/private/svn_repos_private.h?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/private/svn_repos_private.h (original)
+++ subversion/branches/ev2-export/subversion/include/private/svn_repos_private.h Tue Jan 31 12:07:06 2012
@@ -44,6 +44,14 @@ extern "C" {
  *
  * Use @a pool for temporary allocations.
  *
+ * @note This function is used to implement server-side validation.
+ * Consequently, if you make this function stricter in what it accepts, you
+ * (a) break svnsync'ing of existing repositories that contain now-invalid
+ * properties, (b) do not preclude such invalid values from entering the
+ * repository via tools that use the svn_fs_* API directly (possibly
+ * including svnadmin and svnlook).  This has happened before and there
+ * are known (documented, but unsupported) upgrade paths in some cases.
+ * 
  * @since New in 1.7.
  */
 svn_error_t *

Modified: subversion/branches/ev2-export/subversion/include/svn_editor.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_editor.h?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_editor.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_editor.h Tue Jan 31 12:07:06 2012
@@ -182,6 +182,7 @@ extern "C" {
  *      svn_editor_setcb_delete() \n
  *      svn_editor_setcb_copy() \n
  *      svn_editor_setcb_move() \n
+ *      svn_editor_setcb_rotate() \n
  *      svn_editor_setcb_complete() \n
  *      svn_editor_setcb_abort()
  *
@@ -203,7 +204,8 @@ extern "C" {
  *      svn_editor_set_target() \n
  *      svn_editor_delete() \n
  *      svn_editor_copy() \n
- *      svn_editor_move()
+ *      svn_editor_move() \n
+ *      svn_editor_rotate()
  *    \n\n
  *    Just before each callback invocation is carried out, the @a cancel_func
  *    that was passed to svn_editor_create() is invoked to poll any
@@ -260,15 +262,17 @@ extern "C" {
  *   its children, if a directory) may be copied many times, and are
  *   otherwise subject to the Once Rule. The destination path of a copy
  *   or move may have set_* operations applied, but not add_* or delete.
- *   If the destination path of a copy or move is a directory, then its
- *   children are subject to the Once Rule. The source path of a move
- *   (and its child paths) may be referenced in add_*, or as the
- *   destination of a copy (where these new, copied nodes are subject to
- *   the Once Rule).
- *
- * - The ancestor of an added, copied-here, moved-here or modified node may
- *   not be deleted. The ancestor may not be moved (instead: perform the
- *   move, *then* the edits).
+ *   If the destination path of a copy, move, or rotate is a directory,
+ *   then its children are subject to the Once Rule. The source path of
+ *   a move (and its child paths) may be referenced in add_*, or as the
+ *   destination of a copy (where these new or copied nodes are subject
+ *   to the Once Rule). Paths listed in a rotation are both sources and
+ *   destinations, so they may not be referenced again in an add_* or a
+ *   deletion; these paths may have set_* operations applied.
+ *
+ * - The ancestor of an added, copied-here, moved-here, rotated, or
+ *   modified node may not be deleted. The ancestor may not be moved
+ *   (instead: perform the move, *then* the edits).
  *
  * - svn_editor_delete() must not be used to replace a path -- i.e.
  *   svn_editor_delete() must not be followed by an svn_editor_add_*() on
@@ -289,6 +293,10 @@ extern "C" {
  *   by a delete... that is fine. It is simply that svn_editor_move()
  *   should be used to describe a semantic move.
  *
+ * - Paths mentioned in svn_editor_rotate() may have their properties
+ *   and contents edited (via set_* calls) by a previous or later call,
+ *   but they may not be subject to a later move, rotate, or deletion.
+ *
  * - One of svn_editor_complete() or svn_editor_abort() must be called
  *   exactly once, which must be the final call the driver invokes.
  *   Invoking svn_editor_complete() must imply that the set of changes has
@@ -321,6 +329,19 @@ extern "C" {
  * for these items are invoked.
  * \n\n
  *
+ * <h3>Timing and State</h3>
+ * The calls made by the driver to alter the state in the receiver are
+ * based on the receiver's *current* state, which includes all prior changes
+ * made during the edit.
+ *
+ * Example: copy A to B; set-props on A; copy A to C. The props on C
+ * should reflect the updated properties of A.
+ *
+ * Example: mv A@N to B; mv C@M to A. The second move cannot be marked as
+ * a "replacing" move since it is not replacing A. The node at A was moved
+ * away. The second operation is simply moving C to the now-empty path
+ * known as A.
+ *
  * <h3>Paths</h3>
  * Each driver/receiver implementation of this editor interface must
  * establish the expected root path for the paths sent and received via the
@@ -505,6 +526,15 @@ typedef svn_error_t *(*svn_editor_cb_mov
   svn_revnum_t replaces_rev,
   apr_pool_t *scratch_pool);
 
+/** @see svn_editor_rotate(), svn_editor_t.
+ * @since New in 1.8.
+ */
+typedef svn_error_t *(*svn_editor_cb_rotate_t)(
+  void *baton,
+  const apr_array_header_t *relpaths,
+  const apr_array_header_t *revisions,
+  apr_pool_t *scratch_pool);
+
 /** @see svn_editor_complete(), svn_editor_t.
  * @since New in 1.8.
  */
@@ -655,6 +685,17 @@ svn_editor_setcb_move(svn_editor_t *edit
                       svn_editor_cb_move_t callback,
                       apr_pool_t *scratch_pool);
 
+/** Sets the #svn_editor_cb_rotate_t callback in @a editor
+ * to @a callback.
+ * @a scratch_pool is used for temporary allocations (if any).
+ * @see also svn_editor_setcb_many().
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_editor_setcb_rotate(svn_editor_t *editor,
+                        svn_editor_cb_rotate_t callback,
+                        apr_pool_t *scratch_pool);
+
 /** Sets the #svn_editor_cb_complete_t callback in @a editor
  * to @a callback.
  * @a scratch_pool is used for temporary allocations (if any).
@@ -695,6 +736,7 @@ typedef struct svn_editor_cb_many_t
   svn_editor_cb_delete_t cb_delete;
   svn_editor_cb_copy_t cb_copy;
   svn_editor_cb_move_t cb_move;
+  svn_editor_cb_rotate_t cb_rotate;
   svn_editor_cb_complete_t cb_complete;
   svn_editor_cb_abort_t cb_abort;
 
@@ -929,6 +971,33 @@ svn_editor_move(svn_editor_t *editor,
                 const char *dst_relpath,
                 svn_revnum_t replaces_rev);
 
+/** Drive @a editor's #svn_editor_cb_rotate_t callback.
+ *
+ * Perform a rotation among multiple nodes in the target tree.
+ *
+ * The @relpaths and @revisions arrays (pair-wise) specify nodes in the
+ * tree which are located at a path and expected to be at a specific
+ * revision. These nodes are simultaneously moved in a rotation pattern.
+ * For example, the node at index 0 of @a relpaths and @a revisions will
+ * be moved to the relpath specified at index 1 of @a relpaths. The node
+ * at index 1 will be moved to the location at index 2. The node at index
+ * N-1 will be moved to the relpath specifed at index 0.
+ *
+ * The simplest form of this operation is to swap nodes A and B. One may
+ * think to move A to a temporary location T, then move B to A, then move
+ * T to B. However, this last move violations the Once Rule by moving T
+ * (which had already by edited by the move from A). In order to keep the
+ * restrictions against multiple moves of a single node, the rotation
+ * operation is needed for certain types of tree edits.
+ *
+ * For all restrictions on driving the editor, see #svn_editor_t.
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_editor_rotate(svn_editor_t *editor,
+                  const apr_array_header_t *relpaths,
+                  const apr_array_header_t *revisions);
+
 /** Drive @a editor's #svn_editor_cb_complete_t callback.
  *
  * Send word that the edit has been completed successfully.

Modified: subversion/branches/ev2-export/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/include/svn_io.h?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/include/svn_io.h (original)
+++ subversion/branches/ev2-export/subversion/include/svn_io.h Tue Jan 31 12:07:06 2012
@@ -990,6 +990,8 @@ svn_stream_from_string(const svn_string_
                        apr_pool_t *pool);
 
 /** Return a generic stream which implements buffered reads and writes.
+ *  The stream will preferentially store data in-memory, but may use
+ *  disk storage as backup if the amount of data is large.
  *  Allocate the stream in @a result_pool
  *
  * @since New in 1.8.

Modified: subversion/branches/ev2-export/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/copy.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/copy.c Tue Jan 31 12:07:06 2012
@@ -1558,27 +1558,18 @@ repos_to_wc_copy_single(svn_client__copy
 
   else if (pair->src_kind == svn_node_file)
     {
-      svn_stream_t *fstream;
-      const char *new_text_path;
       apr_hash_t *new_props;
       const char *src_rel;
-      svn_stream_t *new_base_contents;
-
-      SVN_ERR(svn_stream_open_unique(&fstream, &new_text_path, NULL,
-                                     svn_io_file_del_on_pool_cleanup, pool,
-                                     pool));
+      svn_stream_t *new_base_contents = svn_stream_buffered(pool);
 
       SVN_ERR(svn_ra_get_path_relative_to_session(ra_session, &src_rel,
                                                   pair->src_abspath_or_url,
                                                   pool));
       /* Fetch the file content. While doing so, resolve pair->src_revnum
        * to an actual revision number if it's 'invalid' meaning 'head'. */
-      SVN_ERR(svn_ra_get_file(ra_session, src_rel, pair->src_revnum, fstream,
+      SVN_ERR(svn_ra_get_file(ra_session, src_rel, pair->src_revnum,
+                              new_base_contents,
                               &pair->src_revnum, &new_props, pool));
-      SVN_ERR(svn_stream_close(fstream));
-
-      SVN_ERR(svn_stream_open_readonly(&new_base_contents, new_text_path,
-                                       pool, pool));
       SVN_ERR(svn_wc_add_repos_file4(
          ctx->wc_ctx, dst_abspath,
          new_base_contents, NULL, new_props, NULL,

Modified: subversion/branches/ev2-export/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/merge.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/merge.c Tue Jan 31 12:07:06 2012
@@ -9842,6 +9842,85 @@ find_unsynced_ranges(const char *source_
 }
 
 
+/* Find the youngest revision that has been merged from target to source.
+ *
+ * If any location in TARGET_HISTORY_AS_MERGEINFO is mentioned in
+ * SOURCE_MERGEINFO, then we know that at least one merge was done from the
+ * target to the source.  In that case, set *YOUNGEST_MERGED_REV to the
+ * youngest revision of that intersection (unless *YOUNGEST_MERGED_REV is
+ * already younger than that).  Otherwise, leave *YOUNGEST_MERGED_REV alone.
+ */
+static svn_error_t *
+find_youngest_merged_rev(svn_revnum_t *youngest_merged_rev,
+                         svn_mergeinfo_t target_history_as_mergeinfo,
+                         svn_mergeinfo_t source_mergeinfo,
+                         apr_pool_t *scratch_pool)
+{
+  svn_mergeinfo_t explicit_source_target_history_intersection;
+
+  SVN_ERR(svn_mergeinfo_intersect2(
+            &explicit_source_target_history_intersection,
+            source_mergeinfo, target_history_as_mergeinfo, TRUE,
+            scratch_pool, scratch_pool));
+  if (apr_hash_count(explicit_source_target_history_intersection))
+    {
+      svn_revnum_t old_rev, young_rev;
+
+      /* Keep track of the youngest revision merged from target to source. */
+      SVN_ERR(svn_mergeinfo__get_range_endpoints(
+                &young_rev, &old_rev,
+                explicit_source_target_history_intersection, scratch_pool));
+      if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
+          || (young_rev > *youngest_merged_rev))
+        *youngest_merged_rev = young_rev;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Set *FILTERED_MERGEINFO_P to the parts of TARGET_HISTORY_AS_MERGEINFO
+ * that are not present in the source branch.
+ *
+ * SOURCE_MERGEINFO is the explicit or inherited mergeinfo of the source
+ * branch SOURCE_URL@SOURCE_REV.  Extend SOURCE_MERGEINFO, modifying it in
+ * place, to include the natural history (implicit mergeinfo) of
+ * SOURCE_URL@SOURCE_REV.  ### But make these additions in SCRATCH_POOL.
+ */
+static svn_error_t *
+find_unmerged_mergeinfo_subroutine(svn_mergeinfo_t *filtered_mergeinfo_p,
+                                   svn_mergeinfo_t target_history_as_mergeinfo,
+                                   svn_mergeinfo_t source_mergeinfo,
+                                   const char *source_url,
+                                   svn_revnum_t source_rev,
+                                   svn_ra_session_t *source_ra_session,
+                                   svn_client_ctx_t *ctx,
+                                   apr_pool_t *result_pool,
+                                   apr_pool_t *scratch_pool)
+{
+  svn_mergeinfo_t source_history_as_mergeinfo;
+
+  /* Get the source path's natural history and merge it into source
+     path's explicit or inherited mergeinfo. */
+  SVN_ERR(svn_client__get_history_as_mergeinfo(
+            &source_history_as_mergeinfo, NULL /* has_rev_zero_history */,
+            source_url, source_rev, source_rev, SVN_INVALID_REVNUM,
+            source_ra_session, ctx, scratch_pool));
+  SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
+                               source_history_as_mergeinfo,
+                               scratch_pool, scratch_pool));
+
+  /* Now source_mergeinfo represents everything we know about
+     source_path's history.  Now we need to know what part, if any, of the
+     corresponding target's history is *not* part of source_path's total
+     history; because it is neither shared history nor was it ever merged
+     from the target to the source. */
+  SVN_ERR(svn_mergeinfo_remove2(filtered_mergeinfo_p,
+                                source_mergeinfo,
+                                target_history_as_mergeinfo, TRUE,
+                                result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
 /* Helper for calculate_left_hand_side() which produces a mergeinfo catalog
    describing what parts of of the reintegrate target have not previously been
    merged to the reintegrate source.
@@ -9884,8 +9963,7 @@ find_unsynced_ranges(const char *source_
    TARGET_HISTORY_HASH.
 
    If no part of TARGET_HISTORY_HASH is found in SOURCE_CATALOG set
-   *NEVER_SYNCHED to TRUE and set *YOUNGEST_MERGED_REV to SVN_INVALID_REVNUM.
-   Otherwise set *NEVER_SYNCHED to FALSE, *YOUNGEST_MERGED_REV to the youngest
+   *YOUNGEST_MERGED_REV to SVN_INVALID_REVNUM; otherwise set it to the youngest
    revision previously merged from the target to the source, and filter
    *UNMERGED_TO_SOURCE_CATALOG so that it contains no ranges greater than
    *YOUNGEST_MERGED_REV.
@@ -9894,7 +9972,6 @@ find_unsynced_ranges(const char *source_
    SCRATCH_POOL is used for all temporary allocations.  */
 static svn_error_t *
 find_unmerged_mergeinfo(svn_mergeinfo_catalog_t *unmerged_to_source_catalog,
-                        svn_boolean_t *never_synched,
                         svn_revnum_t *youngest_merged_rev,
                         svn_revnum_t yc_ancestor_rev,
                         svn_mergeinfo_catalog_t source_catalog,
@@ -9914,9 +9991,7 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
   apr_hash_index_t *hi;
   svn_mergeinfo_catalog_t new_catalog = apr_hash_make(result_pool);
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  svn_revnum_t old_rev, young_rev;
 
-  *never_synched = TRUE;
   *youngest_merged_rev = SVN_INVALID_REVNUM;
 
   SVN_ERR(svn_ra_get_session_url(target_ra_session, &target_session_url,
@@ -9932,12 +10007,11 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
     {
       const char *target_path = svn__apr_hash_index_key(hi);
       svn_mergeinfo_t target_history_as_mergeinfo = svn__apr_hash_index_val(hi);
-      svn_mergeinfo_t source_history_as_mergeinfo;
       const char *path_rel_to_session
         = svn_relpath_skip_ancestor(target_repos_rel_path, target_path);
       const char *source_path;
       const char *source_url;
-      svn_mergeinfo_t source_mergeinfo, filtered_mergeinfo, common_mergeinfo;
+      svn_mergeinfo_t source_mergeinfo, filtered_mergeinfo;
 
       svn_pool_clear(iterpool);
 
@@ -9966,31 +10040,13 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
                                       APR_HASH_KEY_STRING);
       if (source_mergeinfo)
         {
-          svn_mergeinfo_t explicit_source_target_history_intersection;
-
           apr_hash_set(source_catalog, source_path, APR_HASH_KEY_STRING,
                        NULL);
-          /* If there is an intersection between the *explicit* mergeinfo on
-             this source path and the corresponding target's history then we
-             know that at least one merge was done from the target to the
-             source. */
-          SVN_ERR(svn_mergeinfo_intersect2(
-            &explicit_source_target_history_intersection,
-            source_mergeinfo, target_history_as_mergeinfo, TRUE,
-            iterpool, iterpool));
-          if (apr_hash_count(explicit_source_target_history_intersection))
-            {
-              *never_synched = FALSE;
-              /* Keep track of the youngest revision merged from the
-                 target to the source. */
-              SVN_ERR(svn_mergeinfo__get_range_endpoints(
-                &young_rev, &old_rev,
-                explicit_source_target_history_intersection,
-                iterpool));
-              if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
-                  || (young_rev > *youngest_merged_rev))
-                *youngest_merged_rev = young_rev;
-            }
+
+          SVN_ERR(find_youngest_merged_rev(youngest_merged_rev,
+                                           target_history_as_mergeinfo,
+                                           source_mergeinfo,
+                                           iterpool));
         }
       else
         {
@@ -10027,40 +10083,13 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
             source_mergeinfo = apr_hash_make(iterpool);
         }
 
-      /* Get the source path's natural history and convert it to mergeinfo.
-         Then merge that natural history into source path's explicit
-         or inherited mergeinfo. */
-      SVN_ERR(svn_client__get_history_as_mergeinfo(&source_history_as_mergeinfo,
-                                                   NULL /* has_rev_zero_history */,
-                                                   source_url,
-                                                   source_rev, source_rev,
-                                                   SVN_INVALID_REVNUM,
-                                                   source_ra_session,
-                                                   ctx, iterpool));
-      SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
-                                   source_history_as_mergeinfo, iterpool,
-                                   iterpool));
-
-      /* Now source_mergeinfo represents everything we know about
-         source_path's history.  Now we need to know what part, if any, of the
-         corresponding target's history is *not* part of source_path's total
-         history; because it is neither shared history nor was it ever merged
-         from the target to the source. */
-      SVN_ERR(svn_mergeinfo_intersect2(&common_mergeinfo,
-                                       source_mergeinfo,
-                                       target_history_as_mergeinfo, TRUE,
-                                       iterpool, iterpool));
-
-      /* Use scratch_pool rather than iterpool because filtered_mergeinfo is
-         going into new_catalog below and needs to last to the end of
+      /* Use scratch_pool rather than iterpool because filtered_mergeinfo
+         is going into new_catalog below and needs to last to the end of
          this function. */
-      SVN_ERR(svn_mergeinfo_remove2(&filtered_mergeinfo,
-                                    common_mergeinfo,
-                                    target_history_as_mergeinfo, TRUE,
-                                    scratch_pool, iterpool));
-
-      /* As with svn_mergeinfo_intersect above, we need to use scratch_pool
-         rather than iterpool. */
+      SVN_ERR(find_unmerged_mergeinfo_subroutine(
+                &filtered_mergeinfo, target_history_as_mergeinfo,
+                source_mergeinfo, source_url, source_rev,
+                source_ra_session, ctx, scratch_pool, iterpool));
       apr_hash_set(new_catalog,
                    apr_pstrdup(scratch_pool, source_path),
                    APR_HASH_KEY_STRING,
@@ -10081,9 +10110,9 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
         svn_relpath_skip_ancestor(source_repos_rel_path, source_path);
       const char *source_url;
       svn_mergeinfo_t source_mergeinfo = svn__apr_hash_index_val(hi);
-      svn_mergeinfo_t filtered_mergeinfo, common_mergeinfo;
+      svn_mergeinfo_t filtered_mergeinfo;
       const char *target_url;
-      svn_mergeinfo_t target_history_as_mergeinfo, source_history_as_mergeinfo;
+      svn_mergeinfo_t target_history_as_mergeinfo;
       svn_error_t *err;
 
       svn_pool_clear(iterpool);
@@ -10116,56 +10145,19 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
         }
       else
         {
-          svn_mergeinfo_t explicit_source_target_history_intersection;
-
-          /* If there is an intersection between the *explicit* mergeinfo
-             on this source path and the corresponding target's history
-             then we know that at least one merge was done from the target
-             to the source. */
-          SVN_ERR(svn_mergeinfo_intersect2(
-            &explicit_source_target_history_intersection,
-            source_mergeinfo, target_history_as_mergeinfo, TRUE,
-            iterpool, iterpool));
-
-          if (apr_hash_count(explicit_source_target_history_intersection))
-            {
-              *never_synched = FALSE;
-              /* Keep track of the youngest revision merged from the
-                 target to the source. */
-              SVN_ERR(svn_mergeinfo__get_range_endpoints(
-                &young_rev, &old_rev,
-                explicit_source_target_history_intersection, iterpool));
-              if (!SVN_IS_VALID_REVNUM(*youngest_merged_rev)
-                  || (young_rev > *youngest_merged_rev))
-                *youngest_merged_rev = young_rev;
-            }
-
-          /* Get the source path's natural history and convert it to
-             mergeinfo.  Then merge that natural history into source
-             path's explicit or inherited mergeinfo. */
-          SVN_ERR(svn_client__get_history_as_mergeinfo(
-            &source_history_as_mergeinfo,
-            NULL /* has_rev_zero_history */,
-            source_url,
-            target_rev,
-            target_rev,
-            SVN_INVALID_REVNUM,
-            source_ra_session,
-            ctx, iterpool));
-          SVN_ERR(svn_mergeinfo_merge2(source_mergeinfo,
-                                       source_history_as_mergeinfo,
-                                       iterpool, iterpool));
-          SVN_ERR(svn_mergeinfo_intersect2(&common_mergeinfo,
-                                           source_mergeinfo,
+          SVN_ERR(find_youngest_merged_rev(youngest_merged_rev,
                                            target_history_as_mergeinfo,
-                                           TRUE, iterpool, iterpool));
-          /* Use subpool rather than iterpool because filtered_mergeinfo
-             is  going into new_catalog below and needs to last to the
-             end of this function. */
-          SVN_ERR(svn_mergeinfo_remove2(&filtered_mergeinfo,
-                                        common_mergeinfo,
-                                        target_history_as_mergeinfo,
-                                        TRUE, scratch_pool, iterpool));
+                                           source_mergeinfo,
+                                           iterpool));
+
+          /* Use scratch_pool rather than iterpool because filtered_mergeinfo
+             is going into new_catalog below and needs to last to the end of
+             this function. */
+          /* ### Why looking at SOURCE_url at TARGET_rev? */
+          SVN_ERR(find_unmerged_mergeinfo_subroutine(
+                    &filtered_mergeinfo, target_history_as_mergeinfo,
+                    source_mergeinfo, source_url, target_rev,
+                    source_ra_session, ctx, scratch_pool, iterpool));
           if (apr_hash_count(filtered_mergeinfo))
             apr_hash_set(new_catalog,
                          apr_pstrdup(scratch_pool, source_path),
@@ -10251,7 +10243,6 @@ calculate_left_hand_side(const char **ur
   apr_hash_index_t *hi;
   /* hash of paths mapped to arrays of svn_mergeinfo_t. */
   apr_hash_t *target_history_hash = apr_hash_make(scratch_pool);
-  svn_boolean_t never_synced;
   svn_revnum_t youngest_merged_rev;
   const char *yc_ancestor_url;
   svn_revnum_t yc_ancestor_rev;
@@ -10359,7 +10350,6 @@ calculate_left_hand_side(const char **ur
      mergeinfo that describes what has *not* previously been merged from
      TARGET_REPOS_REL_PATH@TARGET_REV to SOURCE_REPOS_REL_PATH@SOURCE_REV. */
   SVN_ERR(find_unmerged_mergeinfo(&unmerged_catalog,
-                                  &never_synced,
                                   &youngest_merged_rev,
                                   yc_ancestor_rev,
                                   mergeinfo_catalog,
@@ -10379,7 +10369,7 @@ calculate_left_hand_side(const char **ur
   *unmerged_to_source_catalog = svn_mergeinfo_catalog_dup(unmerged_catalog,
                                                           result_pool);
 
-  if (never_synced)
+  if (youngest_merged_rev == SVN_INVALID_REVNUM)
     {
       /* We never merged to the source.  Just return the branch point. */
       *url_left = apr_pstrdup(result_pool, yc_ancestor_url);

Modified: subversion/branches/ev2-export/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_delta/compat.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_delta/compat.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_delta/compat.c Tue Jan 31 12:07:06 2012
@@ -245,10 +245,13 @@ process_actions(void *edit_baton,
                 {
                   /* Fetch the original props. We can then apply each of
                      the modifications to it.  */
-                  SVN_ERR(eb->fetch_props_func(&props,
-                                               eb->fetch_props_baton,
-                                               path, props_base_revision,
-                                               scratch_pool, scratch_pool));
+                  if (need_delete && need_add)
+                    props = apr_hash_make(scratch_pool);
+                  else
+                    SVN_ERR(eb->fetch_props_func(&props,
+                                                 eb->fetch_props_baton,
+                                                 path, props_base_revision,
+                                                 scratch_pool, scratch_pool));
                 }
 
               /* Note that p_args->value may be NULL.  */
@@ -879,7 +882,6 @@ struct editor_baton
   void *fetch_props_baton;
 
   struct operation root;
-  svn_boolean_t root_opened;
   svn_boolean_t *make_abs_paths;
 
   apr_hash_t *paths;
@@ -913,6 +915,11 @@ get_operation(const char *path,
       apr_hash_set(operation->children, apr_pstrdup(result_pool, path),
                    APR_HASH_KEY_STRING, child);
     }
+
+  /* If an operation has a child, it must of necessity be a directory,
+     so ensure this fact. */
+  operation->kind = svn_kind_dir;
+
   return child;
 }
 
@@ -970,14 +977,23 @@ build(struct editor_baton *eb,
       apr_hash_t *current_props;
       apr_array_header_t *propdiffs;
 
-      if (kind == svn_kind_unknown)
-        SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
-                                    relpath, rev, scratch_pool));
-      else
-        operation->kind = kind;
+      /* Only fetch the kind if operating on something other than the root,
+         as we already know the kind on the root. */
+      if (operation->path)
+        {
+          if (kind == svn_kind_unknown)
+            SVN_ERR(eb->fetch_kind_func(&operation->kind, eb->fetch_kind_baton,
+                                        relpath, rev, scratch_pool));
+          else
+            operation->kind = kind;
+        }
 
-      SVN_ERR(eb->fetch_props_func(&current_props, eb->fetch_props_baton,
-                                   relpath, rev, scratch_pool, scratch_pool));
+      if (operation->operation == OP_REPLACE)
+        current_props = apr_hash_make(scratch_pool);
+      else
+        SVN_ERR(eb->fetch_props_func(&current_props, eb->fetch_props_baton,
+                                     relpath, rev, scratch_pool,
+                                     scratch_pool));
 
       SVN_ERR(svn_prop_diffs(&propdiffs, props, current_props, scratch_pool));
 
@@ -990,7 +1006,9 @@ build(struct editor_baton *eb,
             APR_ARRAY_PUSH(operation->prop_dels, const char *) = 
                                         apr_pstrdup(eb->edit_pool, prop->name);
           else
-            apr_hash_set(operation->prop_mods, prop->name, APR_HASH_KEY_STRING,
+            apr_hash_set(operation->prop_mods,
+                         apr_pstrdup(eb->edit_pool, prop->name),
+                         APR_HASH_KEY_STRING,
                          svn_string_dup(prop->value, eb->edit_pool));
         }
 
@@ -1008,7 +1026,10 @@ build(struct editor_baton *eb,
     }
 
   if (action == ACTION_DELETE)
-    operation->operation = OP_DELETE;
+    {
+      operation->operation = OP_DELETE;
+      operation->base_revision = rev;
+    }
 
   else if (action == ACTION_ADD_ABSENT)
     operation->operation = OP_ADD_ABSENT;
@@ -1063,19 +1084,6 @@ build(struct editor_baton *eb,
   return SVN_NO_ERROR;
 }
 
-static svn_error_t *
-ensure_root_opened(struct editor_baton *eb)
-{
-  if (!eb->root_opened)
-    {
-      SVN_ERR(eb->deditor->open_root(eb->dedit_baton, eb->root.base_revision,
-                                     eb->edit_pool, &eb->root.baton));
-      eb->root_opened = TRUE;
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* This implements svn_editor_cb_add_directory_t */
 static svn_error_t *
 add_directory_cb(void *baton,
@@ -1087,8 +1095,6 @@ add_directory_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   if (SVN_IS_VALID_REVNUM(replaces_rev))
     {
       /* We need to add the delete action. */
@@ -1124,8 +1130,6 @@ add_file_cb(void *baton,
   const char *tmp_filename;
   svn_stream_t *tmp_stream;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   if (SVN_IS_VALID_REVNUM(replaces_rev))
     {
       /* We need to add the delete action. */
@@ -1165,8 +1169,6 @@ add_symlink_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   if (SVN_IS_VALID_REVNUM(replaces_rev))
     {
       /* We need to add the delete action. */
@@ -1189,8 +1191,6 @@ add_absent_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   SVN_ERR(build(eb, ACTION_ADD_ABSENT, relpath, kind,
                 NULL, SVN_INVALID_REVNUM,
                 NULL, NULL, SVN_INVALID_REVNUM, scratch_pool));
@@ -1209,8 +1209,6 @@ set_props_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   SVN_ERR(build(eb, ACTION_PROPSET, relpath, svn_kind_unknown,
                 NULL, SVN_INVALID_REVNUM,
                 props, NULL, revision, scratch_pool));
@@ -1231,8 +1229,6 @@ set_text_cb(void *baton,
   const char *tmp_filename;
   svn_stream_t *tmp_stream;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   /* Spool the contents to a tempfile, and provide that to the driver. */
   SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_filename, NULL,
                                  svn_io_file_del_on_pool_cleanup,
@@ -1257,8 +1253,6 @@ set_target_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   return SVN_NO_ERROR;
 }
 
@@ -1271,10 +1265,8 @@ delete_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   SVN_ERR(build(eb, ACTION_DELETE, relpath, svn_kind_unknown,
-                NULL, SVN_INVALID_REVNUM, NULL, NULL, SVN_INVALID_REVNUM,
+                NULL, revision, NULL, NULL, SVN_INVALID_REVNUM,
                 scratch_pool));
 
   return SVN_NO_ERROR;
@@ -1291,8 +1283,6 @@ copy_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   if (SVN_IS_VALID_REVNUM(replaces_rev))
     {
       /* We need to add the delete action. */
@@ -1320,7 +1310,17 @@ move_cb(void *baton,
 {
   struct editor_baton *eb = baton;
 
-  SVN_ERR(ensure_root_opened(eb));
+  return SVN_NO_ERROR;
+}
+
+/* This implements svn_editor_cb_rotate_t */
+static svn_error_t *
+rotate_cb(void *baton,
+          const apr_array_header_t *relpaths,
+          const apr_array_header_t *revisions,
+          apr_pool_t *scratch_pool)
+{
+  struct editor_baton *eb = baton;
 
   return SVN_NO_ERROR;
 }
@@ -1387,7 +1387,7 @@ drive_tree(struct operation *op,
   /* Deletes and replacements are simple -- just delete the thing. */
   if (op->operation == OP_DELETE || op->operation == OP_REPLACE)
     {
-      SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
+      SVN_ERR(editor->delete_entry(path, op->base_revision,
                                    parent_op->baton, scratch_pool));
     }
 
@@ -1395,8 +1395,7 @@ drive_tree(struct operation *op,
     {
       /* Open or create our baton. */
       if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
-        SVN_ERR(editor->open_directory(path, parent_op->baton,
-                                       parent_op->base_revision,
+        SVN_ERR(editor->open_directory(path, parent_op->baton, op->base_revision,
                                        scratch_pool, &op->baton));
 
       else if (op->operation == OP_ADD || op->operation == OP_REPLACE)
@@ -1524,8 +1523,6 @@ complete_cb(void *baton,
   struct editor_baton *eb = baton;
   svn_error_t *err;
 
-  SVN_ERR(ensure_root_opened(eb));
-
   /* Drive the tree we've created. */
   err = drive_root(&eb->root, eb->deditor, *eb->make_abs_paths, scratch_pool);
   if (!err)
@@ -1576,7 +1573,8 @@ start_edit_func(void *baton,
   struct editor_baton *eb = baton;
 
   eb->root.base_revision = base_revision;
-  SVN_ERR(ensure_root_opened(eb));
+  SVN_ERR(eb->deditor->open_root(eb->dedit_baton, eb->root.base_revision,
+                                 eb->edit_pool, &eb->root.baton));
 
   return SVN_NO_ERROR;
 }
@@ -1621,6 +1619,7 @@ svn_delta__editor_from_delta(svn_editor_
       delete_cb,
       copy_cb,
       move_cb,
+      rotate_cb,
       complete_cb,
       abort_cb
     };
@@ -1646,7 +1645,6 @@ svn_delta__editor_from_delta(svn_editor_
   eb->root.prop_dels = apr_array_make(result_pool, 1, sizeof(const char *));
   eb->root.copyfrom_revision = SVN_INVALID_REVNUM;
 
-  eb->root_opened = FALSE;
   eb->make_abs_paths = send_abs_paths;
 
   SVN_ERR(svn_editor_create(&editor, eb, cancel_func, cancel_baton,

Modified: subversion/branches/ev2-export/subversion/libsvn_delta/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_delta/editor.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_delta/editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_delta/editor.c Tue Jan 31 12:07:06 2012
@@ -192,6 +192,16 @@ svn_editor_setcb_move(svn_editor_t *edit
 
 
 svn_error_t *
+svn_editor_setcb_rotate(svn_editor_t *editor,
+                        svn_editor_cb_rotate_t callback,
+                        apr_pool_t *scratch_pool)
+{
+  editor->funcs.cb_rotate = callback;
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
 svn_editor_setcb_complete(svn_editor_t *editor,
                           svn_editor_cb_complete_t callback,
                           apr_pool_t *scratch_pool)
@@ -228,6 +238,7 @@ svn_editor_setcb_many(svn_editor_t *edit
   COPY_CALLBACK(cb_delete);
   COPY_CALLBACK(cb_copy);
   COPY_CALLBACK(cb_move);
+  COPY_CALLBACK(cb_rotate);
   COPY_CALLBACK(cb_complete);
   COPY_CALLBACK(cb_abort);
 
@@ -592,6 +603,32 @@ svn_editor_move(svn_editor_t *editor,
 
 
 svn_error_t *
+svn_editor_rotate(svn_editor_t *editor,
+                  const apr_array_header_t *relpaths,
+                  const apr_array_header_t *revisions)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+
+#ifdef ENABLE_ORDERING_CHECK
+  SVN_ERR_ASSERT(!editor->finished);
+  /* ### something more  */
+#endif
+
+  if (editor->cancel_func)
+    SVN_ERR(editor->cancel_func(editor->cancel_baton));
+
+  if (editor->funcs.cb_rotate)
+    err = editor->funcs.cb_rotate(editor->baton, relpaths, revisions,
+                                  editor->scratch_pool);
+#ifdef ENABLE_ORDERING_CHECK
+  /* ### something more  */
+#endif
+  svn_pool_clear(editor->scratch_pool);
+  return err;
+}
+
+
+svn_error_t *
 svn_editor_complete(svn_editor_t *editor)
 {
   svn_error_t *err = SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_neon/session.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_neon/session.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_neon/session.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_neon/session.c Tue Jan 31 12:07:06 2012
@@ -985,12 +985,15 @@ svn_ra_neon__open(svn_ra_session_t *sess
 
       if (authorities != NULL)
         {
-          char *files, *file;
-          files = apr_pstrdup(pool, authorities);
+          int i;
+          apr_array_header_t *files = svn_cstring_split(authorities, ";", TRUE,
+                                                        pool);
 
-          while ((file = svn_cstring_tokenize(";", &files)) != NULL)
+          for (i = 0; i < files->nelts; ++i)
             {
               ne_ssl_certificate *ca_cert;
+              const char *file = APR_ARRAY_IDX(files, i, const char *);
+
               ca_cert = ne_ssl_cert_read(file);
               if (ca_cert == NULL)
                 {

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Tue Jan 31 12:07:06 2012
@@ -988,32 +988,33 @@ svn_ra_serf__get_baseline_info(const cha
      revision (if needed) with an OPTIONS request.  */
   if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
     {
-      basecoll_url = apr_psprintf(pool, "%s/%ld",
-                                  session->rev_root_stub, revision);
+      svn_revnum_t actual_revision;
 
-      if (latest_revnum)
+      if (SVN_IS_VALID_REVNUM(revision))
         {
-          if (SVN_IS_VALID_REVNUM(revision))
-            {
-              *latest_revnum = revision;
-            }
-          else
-           {
-              svn_ra_serf__options_context_t *opt_ctx;
+          actual_revision = revision;
+        }
+      else
+        {
+          svn_ra_serf__options_context_t *opt_ctx;
 
-              SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
+          SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
                                                   session->session_url.path,
                                                   pool));
-              SVN_ERR(svn_ra_serf__context_run_wait(
+          SVN_ERR(svn_ra_serf__context_run_wait(
                 svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
 
-             *latest_revnum = svn_ra_serf__options_get_youngest_rev(opt_ctx);
-             if (! SVN_IS_VALID_REVNUM(*latest_revnum))
-               return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
-                                       _("The OPTIONS response did not include "
-                                         "the youngest revision"));
-          }
+          actual_revision = svn_ra_serf__options_get_youngest_rev(opt_ctx);
+          if (! SVN_IS_VALID_REVNUM(actual_revision))
+            return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
+                                    _("The OPTIONS response did not include "
+                                      "the youngest revision"));
         }
+
+      basecoll_url = apr_psprintf(pool, "%s/%ld",
+                                  session->rev_root_stub, actual_revision);
+      if (latest_revnum)
+        *latest_revnum = actual_revision;
     }
 
   /* Otherwise, we fall back to the old VCC_URL PROPFIND hunt.  */
@@ -1021,7 +1022,7 @@ svn_ra_serf__get_baseline_info(const cha
     {
       SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, conn, pool));
 
-      if (revision != SVN_INVALID_REVNUM)
+      if (SVN_IS_VALID_REVNUM(revision))
         {
           /* First check baseline information cache. */
           SVN_ERR(svn_ra_serf__blncache_get_bc_url(&basecoll_url,

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Tue Jan 31 12:07:06 2012
@@ -386,20 +386,23 @@ static svn_error_t *
 load_authorities(svn_ra_serf__connection_t *conn, const char *authorities,
                  apr_pool_t *pool)
 {
-  char *files, *file;
-  files = apr_pstrdup(pool, authorities);
+  apr_array_header_t *files = svn_cstring_split(authorities, ";",
+                                                TRUE /* chop_whitespace */,
+                                                pool);
+  int i;
 
-  while ((file = svn_cstring_tokenize(";", &files)) != NULL)
+  for (i = 0; i < files->nelts; ++i)
     {
+      const char *file = APR_ARRAY_IDX(files, i, const char *);
       serf_ssl_certificate_t *ca_cert;
       apr_status_t status = serf_ssl_load_cert_file(&ca_cert, file, pool);
+
       if (status == APR_SUCCESS)
         status = serf_ssl_trust_cert(conn->ssl_context, ca_cert);
 
       if (status != APR_SUCCESS)
         {
-          return svn_error_createf
-            (SVN_ERR_BAD_CONFIG_VALUE, NULL,
+          return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL,
              _("Invalid config: unable to load certificate file '%s'"),
              svn_dirent_local_style(file, pool));
         }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_svn/cyrus_auth.c Tue Jan 31 12:07:06 2012
@@ -186,12 +186,64 @@ svn_ra_svn__sasl_common_init(apr_pool_t 
   return SVN_NO_ERROR;
 }
 
+/* We are going to look at errno when we get SASL_FAIL but we don't
+   know for sure whether SASL always sets errno.  Clearing errno
+   before calling SASL functions helps in cases where SASL does
+   nothing to set errno. */
+#ifdef apr_set_os_error
+#define clear_sasl_errno() apr_set_os_error(APR_SUCCESS)
+#else
+#define clear_sasl_errno() (void)0
+#endif
+
+/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
+ * SASL_FAIL translates to "generic error" which is quite unhelpful.
+ * Try to append a more informative error message based on errno so
+ * should be called before doing anything that may change errno. */
+static const char *
+get_sasl_errno_msg(int result, apr_pool_t *result_pool)
+{
+#ifdef apr_get_os_error
+  char buf[1024];
+
+  if (result == SASL_FAIL && apr_get_os_error() != 0)
+    return apr_psprintf(result_pool, ": %s",
+                        svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
+#endif
+  return "";
+}
+
+/* Wrap an error message from SASL with a prefix that allows users
+ * to tell that the error message came from SASL.  Queries errno and
+ * so should be called before doing anything that may change errno. */
+static const char *
+get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
+{
+  const char *sasl_errno_msg = get_sasl_errno_msg(result, result_pool);
+
+  return apr_psprintf(result_pool,
+                      _("SASL authentication error: %s%s"),
+                      sasl_errdetail(sasl_ctx), sasl_errno_msg);
+}
+
 static svn_error_t *sasl_init_cb(void *baton, apr_pool_t *pool)
 {
+  int result;
+
   SVN_ERR(svn_ra_svn__sasl_common_init(pool));
-  if (sasl_client_init(NULL) != SASL_OK)
-    return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                            _("Could not initialize the SASL library"));
+  clear_sasl_errno();
+  result = sasl_client_init(NULL);
+  if (result != SASL_OK)
+    {
+      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
+
+      return svn_error_createf
+        (SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+         _("Could not initialized the SASL library: %s%s"),
+         sasl_errstring(result, NULL, NULL),
+         sasl_errno_msg);
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -338,31 +390,6 @@ get_password_cb(sasl_conn_t *conn, void 
   return SASL_FAIL;
 }
 
-/* Sometimes SASL returns SASL_FAIL as RESULT and sets errno.
- * SASL_FAIL translates to "generic error" which is quite unhelpful.
- * Try to append a more informative error message based on errno. */
-static const char *
-get_sasl_errno_msg(int result, apr_pool_t *result_pool)
-{
-  char buf[1024];
-
-  if (result == SASL_FAIL && apr_get_os_error() != 0)
-    return apr_psprintf(result_pool, ": %s",
-                        svn_strerror(apr_get_os_error(), buf, sizeof(buf)));
-  return "";
-}
-
-/* Wrap an error message from SASL with a prefix that allows users
- * to tell that the error message came from SASL. */
-static const char *
-get_sasl_error(sasl_conn_t *sasl_ctx, int result, apr_pool_t *result_pool)
-{
-  return apr_psprintf(result_pool,
-                      _("SASL authentication error: %s%s"),
-                      sasl_errdetail(sasl_ctx),
-                      get_sasl_errno_msg(result, result_pool));
-}
-
 /* Create a new SASL context. */
 static svn_error_t *new_sasl_ctx(sasl_conn_t **sasl_ctx,
                                  svn_boolean_t is_tunneled,
@@ -375,15 +402,20 @@ static svn_error_t *new_sasl_ctx(sasl_co
   sasl_security_properties_t secprops;
   int result;
 
+  clear_sasl_errno();
   result = sasl_client_new(SVN_RA_SVN_SASL_NAME,
                            hostname, local_addrport, remote_addrport,
                            callbacks, SASL_SUCCESS_DATA,
                            sasl_ctx);
   if (result != SASL_OK)
-    return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
-                             _("Could not create SASL context: %s%s"),
-                             sasl_errstring(result, NULL, NULL),
-                             get_sasl_errno_msg(result, pool));
+    {
+      const char *sasl_errno_msg = get_sasl_errno_msg(result, pool);
+
+      return svn_error_createf(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
+                               _("Could not create SASL context: %s%s"),
+                               sasl_errstring(result, NULL, NULL),
+                               sasl_errno_msg);
+    }
   svn_atomic_inc(&sasl_ctx_count);
   apr_pool_cleanup_register(pool, *sasl_ctx, sasl_dispose_cb,
                             apr_pool_cleanup_null);
@@ -394,6 +426,7 @@ static svn_error_t *new_sasl_ctx(sasl_co
          otherwise it will ignore EXTERNAL. The third parameter
          should be the username, but since SASL doesn't seem
          to use it on the client side, any non-empty string will do. */
+      clear_sasl_errno();
       result = sasl_setprop(*sasl_ctx,
                             SASL_AUTH_EXTERNAL, " ");
       if (result != SASL_OK)
@@ -426,6 +459,7 @@ static svn_error_t *try_auth(svn_ra_svn_
   do
     {
       again = FALSE;
+      clear_sasl_errno();
       result = sasl_client_start(sasl_ctx,
                                  mechstring,
                                  &client_interact,
@@ -496,6 +530,7 @@ static svn_error_t *try_auth(svn_ra_svn_
       if (strcmp(mech, "CRAM-MD5") != 0)
         in = svn_base64_decode_string(in, pool);
 
+      clear_sasl_errno();
       result = sasl_client_step(sasl_ctx,
                                 in->data,
                                 in->len,
@@ -584,6 +619,7 @@ static svn_error_t *sasl_read_cb(void *b
           *len = 0;
           return SVN_NO_ERROR;
         }
+      clear_sasl_errno();
       result = sasl_decode(sasl_baton->ctx, buffer, len2,
                            &sasl_baton->read_buf,
                            &sasl_baton->read_len);
@@ -625,6 +661,7 @@ sasl_write_cb(void *baton, const char *b
     {
       /* Make sure we don't write too much. */
       *len = (*len > sasl_baton->maxsize) ? sasl_baton->maxsize : *len;
+      clear_sasl_errno();
       result = sasl_encode(sasl_baton->ctx, buffer, *len,
                            &sasl_baton->write_buf,
                            &sasl_baton->write_len);
@@ -685,6 +722,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
       int result;
 
       /* Get the strength of the security layer. */
+      clear_sasl_errno();
       result = sasl_getprop(sasl_ctx, SASL_SSF, (void*) &ssfp);
       if (result != SASL_OK)
         return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
@@ -704,6 +742,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
           sasl_baton->scratch_pool = conn->pool;
 
           /* Find out the maximum input size for sasl_encode. */
+          clear_sasl_errno();
           result = sasl_getprop(sasl_ctx, SASL_MAXOUTBUF, &maxsize);
           if (result != SASL_OK)
             return svn_error_create(SVN_ERR_RA_NOT_AUTHORIZED, NULL,
@@ -714,6 +753,7 @@ svn_error_t *svn_ra_svn__enable_sasl_enc
              we need to decrypt it. */
           if (conn->read_end > conn->read_ptr)
             {
+              clear_sasl_errno();
               result = sasl_decode(sasl_ctx, conn->read_ptr,
                                    conn->read_end - conn->read_ptr,
                                    &sasl_baton->read_buf,

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/commit.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/commit.c Tue Jan 31 12:07:06 2012
@@ -823,6 +823,7 @@ kind_fetch_func(svn_kind_t *kind,
 {
   struct edit_baton *eb = baton;
   svn_node_kind_t node_kind;
+  svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
     base_revision = svn_fs_txn_base_revision(eb->txn);
@@ -831,6 +832,7 @@ kind_fetch_func(svn_kind_t *kind,
     {
       /* This is a copyfrom URL. */
       path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      path = svn_fspath__canonicalize(path, scratch_pool);
     }
   else
     {
@@ -840,7 +842,9 @@ kind_fetch_func(svn_kind_t *kind,
         path = svn_fspath__join(eb->base_path, path, scratch_pool);
     }
 
-  SVN_ERR(svn_fs_check_path(&node_kind, eb->txn_root, path, scratch_pool));
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+  SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
 
   return SVN_NO_ERROR;
@@ -868,6 +872,7 @@ fetch_base_func(const char **filename,
     {
       /* This is a copyfrom URL. */
       path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      path = svn_fspath__canonicalize(path, scratch_pool);
     }
   else
     {

Modified: subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_repos/load-fs-vtable.c Tue Jan 31 12:07:06 2012
@@ -160,12 +160,12 @@ change_rev_prop(svn_repos_t *repos,
                 apr_pool_t *pool)
 {
   if (validate_props)
-    return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
-                                   NULL, value, pool);
-  else
     return svn_repos_fs_change_rev_prop4(repos, revision, NULL, name,
                                          NULL, value, FALSE, FALSE,
                                          NULL, NULL, pool);
+  else
+    return svn_fs_change_rev_prop2(svn_repos_fs(repos), revision, name,
+                                   NULL, value, pool);
 }
 
 /* Change property NAME to VALUE for PATH in TXN_ROOT.  If

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/config_file.c Tue Jan 31 12:07:06 2012
@@ -1050,7 +1050,7 @@ svn_config_ensure(const char *config_dir
         "### path separator.  A single backslash will be treated as an"      NL
         "### escape for the following character."                            NL
         ""                                                                   NL
-        "### Section for configuring miscelleneous Subversion options."      NL
+        "### Section for configuring miscellaneous Subversion options."      NL
         "[miscellany]"                                                       NL
         "### Set global-ignores to a set of whitespace-delimited globs"      NL
         "### which Subversion will ignore in its 'status' output, and"       NL

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/ssl_server_trust_providers.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/ssl_server_trust_providers.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/ssl_server_trust_providers.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/ssl_server_trust_providers.c Tue Jan 31 12:07:06 2012
@@ -208,11 +208,12 @@ ssl_server_trust_prompt_first_cred(void 
     apr_hash_get(parameters,
                  SVN_AUTH_PARAM_SSL_SERVER_CERT_INFO,
                  APR_HASH_KEY_STRING);
+  svn_boolean_t may_save = (!no_auth_cache
+                            && !(*failures & SVN_AUTH_SSL_OTHER));
 
-  SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_server_trust_t **)
-                          credentials_p, pb->prompt_baton, realmstring,
-                          *failures, cert_info, ! no_auth_cache &&
-                          ! (*failures & SVN_AUTH_SSL_OTHER), pool));
+  SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_server_trust_t **)credentials_p,
+                          pb->prompt_baton, realmstring, *failures, cert_info,
+                          may_save, pool));
 
   *iter_baton = NULL;
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/diff_editor.c Tue Jan 31 12:07:06 2012
@@ -1937,7 +1937,7 @@ svn_wc_get_diff_editor6(const svn_delta_
   sfb = apr_palloc(result_pool, sizeof(*sfb));
   sfb->db = wc_ctx->db;
   sfb->base_abspath = eb->anchor_abspath;
-  sfb->fetch_base = FALSE;
+  sfb->fetch_base = TRUE;
 
   shim_callbacks->fetch_kind_func = svn_wc__fetch_kind_func;
   shim_callbacks->fetch_props_func = svn_wc__fetch_props_func;

Modified: subversion/branches/ev2-export/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/liveprops.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/liveprops.c Tue Jan 31 12:07:06 2012
@@ -25,6 +25,7 @@
 
 #include <httpd.h>
 #include <http_core.h>
+#include <http_log.h>
 #include <util_xml.h>
 #include <mod_dav.h>
 
@@ -377,7 +378,12 @@ insert_prop_internal(const dav_resource 
                                            scratch_pool);
             if (serr != NULL)
               {
-                /* ### what to do? */
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                              resource->info->r,
+                              "Can't get created-rev of '%s': "
+                              "%s",
+                              resource->info->repos_path,
+                              serr->message);
                 svn_error_clear(serr);
                 value = "###error###";
                 break;
@@ -395,7 +401,12 @@ insert_prop_internal(const dav_resource 
                                 scratch_pool);
         if (serr)
           {
-            /* ### what to do? */
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                          resource->info->r,
+                          "Can't get author of r%ld: "
+                          "%s",
+                          committed_rev,
+                          serr->message);
             svn_error_clear(serr);
             value = "###error###";
             break;
@@ -538,7 +549,13 @@ insert_prop_internal(const dav_resource 
                                      scratch_pool);
           if (serr != NULL)
             {
-              /* ### what to do? */
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                            resource->info->r,
+                            "Can't get youngest revision in '%s': "
+                            "%s",
+                            svn_fs_path(resource->info->repos->fs,
+                                        scratch_pool),
+                            serr->message);
               svn_error_clear(serr);
               value = "###error###";
               break;
@@ -612,7 +629,12 @@ insert_prop_internal(const dav_resource 
                                          scratch_pool);
           if (serr != NULL)
             {
-              /* ### what to do? */
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                            resource->info->r,
+                            "Can't get created-rev of '%s': "
+                            "%s",
+                            resource->info->repos_path,
+                            serr->message);
               svn_error_clear(serr);
               value = "###error###";
               break;
@@ -651,7 +673,12 @@ insert_prop_internal(const dav_resource 
                                       scratch_pool);
           if (serr != NULL)
             {
-              /* ### what to do? */
+              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                            resource->info->r,
+                            "Can't get fetch or compute md5 checksum of '%s': "
+                            "%s",
+                            resource->info->repos_path,
+                            serr->message);
               svn_error_clear(serr);
               value = "###error###";
               break;
@@ -671,7 +698,12 @@ insert_prop_internal(const dav_resource 
       serr = svn_fs_get_uuid(resource->info->repos->fs, &value, scratch_pool);
       if (serr != NULL)
         {
-          /* ### what to do? */
+          ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                        resource->info->r,
+                        "Can't fetch UUID of '%s': "
+                        "%s",
+                        svn_fs_path(resource->info->repos->fs, scratch_pool),
+                        serr->message);
           svn_error_clear(serr);
           value = "###error###";
           break;
@@ -691,7 +723,12 @@ insert_prop_internal(const dav_resource 
                                     resource->info->repos_path, scratch_pool);
         if (serr != NULL)
           {
-            /* ### what to do? */
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
+                          resource->info->r,
+                          "Can't fetch proplist of '%s': "
+                          "%s",
+                          resource->info->repos_path,
+                          serr->message);
             svn_error_clear(serr);
             value = "###error###";
             break;

Modified: subversion/branches/ev2-export/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/mod_dav_svn/reports/update.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/ev2-export/subversion/mod_dav_svn/reports/update.c Tue Jan 31 12:07:06 2012
@@ -955,8 +955,8 @@ dav_svn__update_report(const dav_resourc
           cdata = dav_xml_get_cdata(child, resource->pool, 0);
           if (! *cdata)
             return malformed_element_error(child->name, resource->pool);
-          if ((derr = dav_svn__test_canonical(cdata, resource->pool)))
-            return derr;
+          if (svn_path_is_url(cdata))
+            cdata = svn_uri_canonicalize(cdata, resource->pool);
           if ((serr = dav_svn__simple_parse_uri(&this_info, resource,
                                                 cdata, resource->pool)))
             return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
@@ -970,8 +970,8 @@ dav_svn__update_report(const dav_resourc
           cdata = dav_xml_get_cdata(child, resource->pool, 0);
           if (! *cdata)
             return malformed_element_error(child->name, resource->pool);
-          if ((derr = dav_svn__test_canonical(cdata, resource->pool)))
-            return derr;
+          if (svn_path_is_url(cdata))
+            cdata = svn_uri_canonicalize(cdata, resource->pool);
           if ((serr = dav_svn__simple_parse_uri(&this_info, resource,
                                                 cdata, resource->pool)))
             return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,

Modified: subversion/branches/ev2-export/subversion/svnrdump/dump_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnrdump/dump_editor.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnrdump/dump_editor.c (original)
+++ subversion/branches/ev2-export/subversion/svnrdump/dump_editor.c Tue Jan 31 12:07:06 2012
@@ -81,6 +81,9 @@ struct dump_edit_baton {
   /* The output stream we write the dumpfile to */
   svn_stream_t *stream;
 
+  /* A backdoor ra session to fetch additional information during the edit. */
+  svn_ra_session_t *ra_session;
+
   /* Pool for per-revision allocations */
   apr_pool_t *pool;
 
@@ -854,7 +857,32 @@ fetch_base_func(const char **filename,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
 {
-  *filename = NULL;
+  struct dump_edit_baton *eb = baton;
+  svn_stream_t *fstream;
+  svn_error_t *err;
+
+  if (path[0] == '/')
+    path += 1;
+
+  SVN_ERR(svn_stream_open_unique(&fstream, filename, NULL,
+                                 svn_io_file_del_on_pool_cleanup,
+                                 result_pool, scratch_pool));
+
+  err = svn_ra_get_file(eb->ra_session, path, base_revision,
+                        fstream, NULL, NULL, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+    {
+      svn_error_clear(err);
+      SVN_ERR(svn_stream_close(fstream));
+
+      *filename = NULL;
+      return SVN_NO_ERROR;
+    }
+  else if (err)
+    return svn_error_trace(err);
+  
+  SVN_ERR(svn_stream_close(fstream));
+
   return SVN_NO_ERROR;
 }
 
@@ -862,6 +890,7 @@ svn_error_t *
 svn_rdump__get_dump_editor(const svn_delta_editor_t **editor,
                            void **edit_baton,
                            svn_stream_t *stream,
+                           svn_ra_session_t *ra_session,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            apr_pool_t *pool)
@@ -873,6 +902,7 @@ svn_rdump__get_dump_editor(const svn_del
 
   eb = apr_pcalloc(pool, sizeof(struct dump_edit_baton));
   eb->stream = stream;
+  eb->ra_session = ra_session;
 
   /* Create a special per-revision pool */
   eb->pool = svn_pool_create(pool);

Modified: subversion/branches/ev2-export/subversion/svnrdump/svnrdump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnrdump/svnrdump.c?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnrdump/svnrdump.c (original)
+++ subversion/branches/ev2-export/subversion/svnrdump/svnrdump.c Tue Jan 31 12:07:06 2012
@@ -343,6 +343,7 @@ dump_revision_header(svn_ra_session_t *s
  */
 static svn_error_t *
 replay_revisions(svn_ra_session_t *session,
+                 svn_ra_session_t *extra_ra_session,
                  const char *url,
                  svn_revnum_t start_revision,
                  svn_revnum_t end_revision,
@@ -359,7 +360,8 @@ replay_revisions(svn_ra_session_t *sessi
   SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
 
   SVN_ERR(svn_rdump__get_dump_editor(&dump_editor, &dump_baton, stdout_stream,
-                                     check_cancel, NULL, pool));
+                                     extra_ra_session, check_cancel, NULL,
+                                     pool));
 
   replay_baton = apr_pcalloc(pool, sizeof(*replay_baton));
   replay_baton->editor = dump_editor;
@@ -531,7 +533,14 @@ dump_cmd(apr_getopt_t *os,
          apr_pool_t *pool)
 {
   opt_baton_t *opt_baton = baton;
-  return replay_revisions(opt_baton->session, opt_baton->url,
+  svn_ra_session_t *extra_ra_session;
+
+  SVN_ERR(svn_client_open_ra_session(&extra_ra_session,
+                                     opt_baton->url,
+                                     opt_baton->ctx, pool));
+
+  return replay_revisions(opt_baton->session, extra_ra_session,
+                          opt_baton->url,
                           opt_baton->start_revision.value.number,
                           opt_baton->end_revision.value.number,
                           opt_baton->quiet, opt_baton->incremental, pool);

Modified: subversion/branches/ev2-export/subversion/svnrdump/svnrdump.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/svnrdump/svnrdump.h?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/svnrdump/svnrdump.h (original)
+++ subversion/branches/ev2-export/subversion/svnrdump/svnrdump.h Tue Jan 31 12:07:06 2012
@@ -47,6 +47,7 @@ svn_error_t *
 svn_rdump__get_dump_editor(const svn_delta_editor_t **editor,
                            void **edit_baton,
                            svn_stream_t *stream,
+                           svn_ra_session_t *ra_session,
                            svn_cancel_func_t cancel_func,
                            void *cancel_baton,
                            apr_pool_t *pool);

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/externals_tests.py?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/externals_tests.py Tue Jan 31 12:07:06 2012
@@ -2704,6 +2704,77 @@ def remap_file_external_with_prop_del(sb
   # http://subversion.tigris.org/issues/show_bug.cgi?id=4093#desc1
   svntest.actions.run_and_verify_svn(None, None, [], 'up', wc_dir)
 
+
+# Test for issue #4053 'svn:externals with explicit rev checks out HEAD'
+@Issue(4053)
+def dir_external_with_dash_r_only(sbox):
+  "whether '-r1 ^/A B' updates properly"
+  # svntest.factory.make(sbox,"""
+  #   echo 'newer alpha' > A/B/E/alpha
+  #   svn ci
+  #   svn ps svn:externals ' -r1 ^/A/B/E E_ext' .
+  #   svn up
+  #   # ^ move the 'status.tweak(wc_rev=2)' above the 'add()' call
+  #   svn info E_ext
+  #   # ^ change the 'svn info' call to
+  #   #  expected_info = { 'Revision': '1' }
+  #   #  actions.run_and_verify_info([expected_info], E_ext)
+  #   """)
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  url = sbox.repo_url
+
+  A_B_E_alpha = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha')
+  E_ext = os.path.join(wc_dir, 'E_ext')
+
+  # echo 'newer alpha' > A/B/E/alpha
+  main.file_write(A_B_E_alpha, 'newer alpha\n')
+
+  # svn ci
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E/alpha'       : Item(verb='Sending'),
+  })
+
+  expected_status = actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('A/B/E/alpha', wc_rev='2')
+
+  actions.run_and_verify_commit(wc_dir, expected_output, expected_status,
+    None, wc_dir)
+
+  # svn ps svn:externals ' -r1 ^/A/B/E E_ext' .
+  expected_stdout = ["property 'svn:externals' set on '" + wc_dir + "'\n"]
+
+  actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'ps',
+    'svn:externals', ' -r1 ^/A/B/E E_ext', wc_dir)
+
+  # svn up
+  expected_output = svntest.wc.State(wc_dir, {
+    'E_ext/beta'        : Item(status='A '),
+    'E_ext/alpha'       : Item(status='A '),
+  })
+
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.add({
+    'E_ext'             : Item(),
+    'E_ext/alpha'       : Item(contents="This is the file 'alpha'.\n"),
+    'E_ext/beta'        : Item(contents="This is the file 'beta'.\n"),
+  })
+  expected_disk.tweak('A/B/E/alpha', contents='newer alpha\n')
+
+  expected_status.tweak(wc_rev='2')
+  expected_status.tweak('', status=' M')
+  expected_status.add({
+    'E_ext'             : Item(status='X '),
+  })
+
+  actions.run_and_verify_update(wc_dir, expected_output, expected_disk,
+    expected_status, None, None, None, None, None, False, wc_dir)
+
+  # svn info E_ext/alpha
+  expected_info = { 'Revision': '1' }
+  actions.run_and_verify_info([expected_info], E_ext)
+
 ########################################################################
 # Run the tests
 
@@ -2749,6 +2820,7 @@ test_list = [ None,
               include_immediate_dir_externals,
               shadowing,
               remap_file_external_with_prop_del,
+              dir_external_with_dash_r_only,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/log_tests.py Tue Jan 31 12:07:06 2012
@@ -218,7 +218,7 @@ def guarantee_repos_and_wc(sbox):
 
 def merge_history_repos(sbox):
   """Make a repos with varied and interesting merge history, similar
-  to the repos found at: log_tests_data/merge_history_dump.png"""
+  to the repos found at: log_tests_data/merge_history_repo.png"""
 
   upsilon_path = os.path.join('A', 'upsilon')
   omicron_path = os.path.join('blocked', 'omicron')
@@ -281,7 +281,6 @@ def merge_history_repos(sbox):
   # From branch_a to trunk: add 'upsilon' and modify 'iota' and 'mu'.
   #
   # Mergeinfo changes on /trunk:
-  #    Merged /trunk:r2
   #    Merged /branches/a:r3-5
   os.chdir('trunk')
   svntest.main.run_svn(None, 'merge', os.path.join('..', branch_a) + '@HEAD')
@@ -363,8 +362,6 @@ def merge_history_repos(sbox):
   # More merging - r14
   #
   # Mergeinfo changes on /trunk:
-  #    Reverse-merged /trunk:r2
-  #    Merged /trunk:r3-9
   #    Merged /branches/a:r6,8-11
   #    Merged /branches/b:r10-13
   os.chdir('trunk')
@@ -397,8 +394,7 @@ def merge_history_repos(sbox):
   # Merge branches/c to trunk, which produces a conflict - r17
   #
   # Mergeinfo changes on /trunk:
-  #    Merged /trunk:r2
-  #    Merged /branches/c:r3-16
+  #    Merged /branches/c:r5-16
   os.chdir('trunk')
   svntest.main.run_svn(None, 'merge', '--allow-mixed-revisions',
                        os.path.join('..', branch_c) + '@HEAD')

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/log_tests_data/merge_history_repo.png
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/log_tests_data/merge_history_repo.png?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
Binary files - no diff available.

Modified: subversion/branches/ev2-export/subversion/tests/cmdline/merge_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/tests/cmdline/merge_tests.py?rev=1238422&r1=1238421&r2=1238422&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/tests/cmdline/merge_tests.py (original)
+++ subversion/branches/ev2-export/subversion/tests/cmdline/merge_tests.py Tue Jan 31 12:07:06 2012
@@ -13449,6 +13449,12 @@ def natural_history_filtering(sbox):
   #
   # To set up a situation where this can occur we'll do the following:
   #
+  #     trunk   -1-----3-4-5-6-------8----------- A
+  #                \           \       \
+  #     branch1     2-----------\-------9-------- A_COPY
+  #                              \        \
+  #     branch2                   7--------10---- A_COPY_2
+  #
   #   1) Create a 'trunk'.
   #
   #   2) Copy 'trunk' to 'branch1'.



Mime
View raw message