You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2011/08/16 17:12:15 UTC

svn commit: r1158318 [1/2] - in /subversion/branches/issue-3975: ./ subversion/bindings/ctypes-python/csvn/ subversion/bindings/ctypes-python/test/ subversion/bindings/swig/ruby/test/ subversion/include/ subversion/include/private/ subversion/libsvn_cl...

Author: pburba
Date: Tue Aug 16 15:12:14 2011
New Revision: 1158318

URL: http://svn.apache.org/viewvc?rev=1158318&view=rev
Log:
On the issue-3975 branch: Sync with ^/subversion/trunk through r1157415.


Modified:
    subversion/branches/issue-3975/   (props changed)
    subversion/branches/issue-3975/configure.ac
    subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/repos.py
    subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/wc.py
    subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/localrepos.py
    subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/remoterepos.py
    subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/wc.py
    subversion/branches/issue-3975/subversion/bindings/swig/ruby/test/util.rb
    subversion/branches/issue-3975/subversion/include/private/svn_client_private.h
    subversion/branches/issue-3975/subversion/include/private/svn_wc_private.h
    subversion/branches/issue-3975/subversion/include/svn_client.h
    subversion/branches/issue-3975/subversion/include/svn_wc.h
    subversion/branches/issue-3975/subversion/libsvn_client/blame.c
    subversion/branches/issue-3975/subversion/libsvn_client/commit.c
    subversion/branches/issue-3975/subversion/libsvn_client/diff.c
    subversion/branches/issue-3975/subversion/libsvn_client/merge.c
    subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.c
    subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.h
    subversion/branches/issue-3975/subversion/libsvn_client/patch.c
    subversion/branches/issue-3975/subversion/libsvn_client/status.c
    subversion/branches/issue-3975/subversion/libsvn_fs_fs/tree.c
    subversion/branches/issue-3975/subversion/libsvn_ra_neon/fetch.c
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/merge.c
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/update.c
    subversion/branches/issue-3975/subversion/libsvn_ra_serf/util.c
    subversion/branches/issue-3975/subversion/libsvn_wc/info.c
    subversion/branches/issue-3975/subversion/libsvn_wc/merge.c
    subversion/branches/issue-3975/subversion/libsvn_wc/node.c
    subversion/branches/issue-3975/subversion/libsvn_wc/status.c
    subversion/branches/issue-3975/subversion/libsvn_wc/update_editor.c
    subversion/branches/issue-3975/subversion/libsvn_wc/upgrade.c
    subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c
    subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h
    subversion/branches/issue-3975/subversion/svn/info-cmd.c
    subversion/branches/issue-3975/subversion/svn/schema/info.rnc
    subversion/branches/issue-3975/subversion/svn/status.c
    subversion/branches/issue-3975/subversion/tests/cmdline/changelist_tests.py
    subversion/branches/issue-3975/subversion/tests/cmdline/copy_tests.py
    subversion/branches/issue-3975/subversion/tests/cmdline/import_tests.py
    subversion/branches/issue-3975/subversion/tests/cmdline/lock_tests.py
    subversion/branches/issue-3975/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/issue-3975/subversion/tests/cmdline/patch_tests.py
    subversion/branches/issue-3975/tools/dev/benchmarks/suite1/benchmark.py
    subversion/branches/issue-3975/tools/dev/benchmarks/suite1/run
    subversion/branches/issue-3975/tools/dev/unix-build/Makefile.svn
    subversion/branches/issue-3975/tools/dist/release.py
    subversion/branches/issue-3975/tools/dist/templates/rc-news.ezt

Propchange: subversion/branches/issue-3975/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Aug 16 15:12:14 2011
@@ -54,4 +54,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1152931-1154347
+/subversion/trunk:1152931-1157415

Modified: subversion/branches/issue-3975/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/configure.ac?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/configure.ac (original)
+++ subversion/branches/issue-3975/configure.ac Tue Aug 16 15:12:14 2011
@@ -737,7 +737,7 @@ AC_ARG_WITH(libmagic,AS_HELP_STRING([--w
       AC_CHECK_LIB(magic, magic_open, [libmagic_found="builtin"])
     ])
     libmagic_prefix="the default locations"
-  else
+  elif test "$withval" != "no"; then
     libmagic_prefix=$withval
     save_cppflags="$CPPFLAGS"
     CPPFLAGS="$CPPFLAGS -I$libmagic_prefix/include"

Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/repos.py?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/repos.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/repos.py Tue Aug 16 15:12:14 2011
@@ -67,6 +67,10 @@ class RepositoryURI(object):
         return self._as_parameter_
 
 class RemoteRepository(object):
+    """This class represents a connection from the client to a remote
+       Subversion repository."""
+    # The interface corresponds roughly to the svn_ra API, and an object of
+    # this type basically represents the C type 'svn_ra_session_t'.
 
     def __init__(self, url, user=None):
         """Open a new session to URL with the specified USER.
@@ -95,6 +99,10 @@ class RemoteRepository(object):
         self.client[0].log_msg_baton2 = c_void_p()
         self._log_func = None
 
+    def close(self):
+        """Close this RemoteRepository object, releasing any resources."""
+        self.pool.clear()
+
     def txn(self):
         """Create a transaction"""
         return Txn(self)
@@ -146,7 +154,12 @@ class RemoteRepository(object):
         svn_ra_get_dir2(self, dirents.byref(), NULL, NULL, path,
                         rev, fields, dirents.pool)
         self.iterpool.clear()
-        return dirents
+        # Create a Python dict of svn_dirent_t objects from this Hash of
+        # pointers to svn_dirent_t.
+        result = {}
+        for path, dirent_p in dirents.items():
+            result[path] = dirent_p[0]
+        return result
 
     def cat(self, buffer, path, rev = SVN_INVALID_REVNUM):
         """Get PATH@REV and save it to BUFFER. BUFFER must be a Python file
@@ -170,7 +183,7 @@ class RemoteRepository(object):
             rev = self.latest_revnum()
         svn_ra_stat(self, path, rev, byref(dirent), dirent.pool)
         self.iterpool.clear()
-        return dirent
+        return dirent[0]
 
     def proplist(self, path, rev = SVN_INVALID_REVNUM):
         """Return a dictionary containing the properties on PATH@REV
@@ -396,6 +409,14 @@ class LocalRepository(object):
             svn_repos_open(byref(self._as_parameter_), path, self.pool)
         self.fs = _fs(self)
 
+    def __del__(self):
+        self.close()
+
+    def close(self):
+        """Close this LocalRepository object, releasing any resources. In
+           particular, this closes the rep-cache DB."""
+        self.pool.clear()
+
     def latest_revnum(self):
         """Get the latest revision in the repository"""
         return self.fs.latest_revnum()
@@ -532,7 +553,6 @@ class _fs(object):
        This class represents an svn_fs_t object"""
 
     def __init__(self, repos):
-        self.repos = repos
         self.iterpool = Pool()
         self._as_parameter_ = svn_repos_fs(repos)
 
@@ -563,13 +583,6 @@ class _fs(object):
            temporary allocations."""
         return _fs_root(self, rev, txn, pool, iterpool)
 
-    def txn(self, message, base_rev=None):
-        """Open a new transaction for commit to the specified
-           repository, assuming that our data is up to date as
-           of base_rev. Setup the author and commit message
-           revprops."""
-        return _fs_txn(self.repos, message, base_rev)
-
 class _fs_root(object):
     """NOTE: This is a private class. Don't use it outside of
        this module. Use the Repos.txn() method instead.

Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/wc.py?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/wc.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/csvn/wc.py Tue Aug 16 15:12:14 2011
@@ -79,6 +79,10 @@ class WC(object):
         self.client[0].log_msg_baton2 = c_void_p()
         self._log_func = None
 
+    def close(self):
+        """Close this WC object, releasing any resources."""
+        self.pool.clear()
+
     def copy(self, src, dest, rev = ""):
         """Copy src to dest.
 

Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/localrepos.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/localrepos.py?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/localrepos.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/localrepos.py Tue Aug 16 15:12:14 2011
@@ -33,15 +33,21 @@ class LocalRepositoryTestCase(unittest.T
         dumpfile = open(os.path.join(os.path.split(__file__)[0],
                         'test.dumpfile'))
 
-        # Just in case a preivous test instance was not properly cleaned up
-        self.tearDown()
+        # Just in case a previous test instance was not properly cleaned up
+        self.remove_from_disk()
+
         self.repos = LocalRepository(repos_location, create=True)
         self.repos.load(dumpfile)
 
     def tearDown(self):
+        self.repos.close()
+        self.remove_from_disk()
+        self.repos = None
+
+    def remove_from_disk(self):
+        """Remove anything left on disk"""
         if os.path.exists(repos_location):
             svn_repos_delete(repos_location, Pool())
-        self.repos = None
 
     def test_local_latest_revnum(self):
         self.assertEqual(9, self.repos.latest_revnum())

Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/remoterepos.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/remoterepos.py?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/remoterepos.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/remoterepos.py Tue Aug 16 15:12:14 2011
@@ -27,6 +27,13 @@ from csvn.core import *
 from urllib import pathname2url
 from csvn.repos import LocalRepository, RemoteRepository
 from stat import *
+from sys import version_info # For Python version check
+if version_info[0] >= 3:
+  # Python >=3.0
+  from io import StringIO
+else:
+  # Python <3.0
+  from StringIO import StringIO
 
 repos_location = os.path.join(tempfile.gettempdir(), "svn_test_repos")
 repos_url = pathname2url(repos_location)
@@ -46,17 +53,32 @@ class RemoteRepositoryTestCase(unittest.
         dumpfile = open(os.path.join(os.path.split(__file__)[0],
                         'test.dumpfile'))
 
-        # Just in case a preivous test instance was not properly cleaned up
-        self.tearDown()
+        # Just in case a previous test instance was not properly cleaned up
+        self.remove_from_disk()
+
         self.repos = LocalRepository(repos_location, create=True)
         self.repos.load(dumpfile)
 
         self.repos = RemoteRepository(repos_url)
 
     def tearDown(self):
+        self.repos.close()
+        self.remove_from_disk()
+        self.repos = None
+
+    def remove_from_disk(self):
+        """Remove anything left on disk"""
         if os.path.exists(repos_location):
             svn_repos_delete(repos_location, Pool())
-        self.repos = None
+
+    def svn_dirent_t_assert_equal(self, a, b):
+        """Assert that two svn_dirent_t's are equal, ignoring their 'time'
+           fields."""
+        self.assertEqual(a.kind, b.kind)
+        self.assertEqual(a.size, b.size)
+        self.assertEqual(a.has_props, b.has_props)
+        self.assertEqual(a.created_rev, b.created_rev)
+        self.assertEqual(a.last_author, b.last_author)
 
     def test_remote_latest_revnum(self):
         self.assertEqual(9, self.repos.latest_revnum())
@@ -71,6 +93,50 @@ class RemoteRepositoryTestCase(unittest.
         self.assertEqual(svn_node_none,
             self.repos.check_path("does_not_compute"))
 
+    def test_list(self):
+        expected = {
+            'README.txt':
+                svn_dirent_t(kind=svn_node_file, size=159, has_props=True,
+                             created_rev=9, last_author=String('bruce')),
+            'ANOTHERREADME.txt':
+                svn_dirent_t(kind=svn_node_file, size=66, has_props=False,
+                             created_rev=4, last_author=String('clark')) }
+        found = self.repos.list("trunk")
+        self.assertEqual(sorted(found.keys()), sorted(expected.keys()))
+        for path in found:
+            self.svn_dirent_t_assert_equal(found[path], expected[path])
+
+    def test_info(self):
+        e = svn_dirent_t(kind=svn_node_file, size=159, has_props=True,
+                         created_rev=9, last_author=String('bruce'))
+        f = self.repos.info("trunk/README.txt")
+        self.svn_dirent_t_assert_equal(f, e)
+
+    def test_proplist(self):
+        expected = { 'Awesome': 'Yes',
+            'svn:entry:last-author': 'bruce',
+            'svn:entry:committed-rev': '9' }
+        found = self.repos.proplist("trunk/README.txt")
+        # Check results, ignoring some entry-props
+        del found['svn:entry:committed-date']
+        del found['svn:entry:uuid']
+        self.assertEqual(sorted(found.keys()), sorted(expected.keys()))
+        for pname in found:
+            self.assertEqual(found[pname], expected[pname])
+
+    def test_propget(self):
+        found = self.repos.propget("Awesome", "trunk/README.txt")
+        self.assertEqual(found, "Yes")
+
+    def test_log(self):
+        expected = [ (8, 'clark'),
+                     (9, 'bruce') ]
+        for found in self.repos.log(7, 9, ["trunk/README.txt"]):
+            (e_rev, e_author) = expected[0]
+            self.assertEqual(found.revision, e_rev)
+            self.assertEqual(found.author, e_author)
+            expected = expected[1:]
+
     def test_revprop_list(self):
         # Test argument-free case
         props = self.repos.revprop_list()

Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/wc.py?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/wc.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/wc.py Tue Aug 16 15:12:14 2011
@@ -59,8 +59,9 @@ class WCTestCase(unittest.TestCase):
         dumpfile = open(os.path.join(os.path.split(__file__)[0],
                         'test.dumpfile'))
 
-        # Just in case a preivous test instance was not properly cleaned up
-        self.tearDown()
+        # Just in case a previous test instance was not properly cleaned up
+        self.remove_from_disk()
+
         self.repos = LocalRepository(repos_location, create=True)
         self.repos.load(dumpfile)
 
@@ -68,12 +69,18 @@ class WCTestCase(unittest.TestCase):
         self.wc.checkout(repo_url)
 
     def tearDown(self):
+        self.repos.close()
+        self.wc.close()
+        self.remove_from_disk()
+        self.wc = None
+
+    def remove_from_disk(self):
+        """Remove anything left on disk"""
         pool = Pool()
         if os.path.exists(wc_location):
             svn_io_remove_dir(wc_location, pool)
         if os.path.exists(repos_location):
             svn_repos_delete(repos_location, pool)
-        self.wc = None
 
     def _info_receiver(self, path, info):
         self.last_info = info
@@ -247,5 +254,5 @@ def suite():
     return unittest.makeSuite(WCTestCase, 'test')
 
 if __name__ == '__main__':
-    runner = unittest.TextTestRunner(verbosity=2)
+    runner = unittest.TextTestRunner()
     runner.run(suite())

Modified: subversion/branches/issue-3975/subversion/bindings/swig/ruby/test/util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/swig/ruby/test/util.rb?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/swig/ruby/test/util.rb (original)
+++ subversion/branches/issue-3975/subversion/bindings/swig/ruby/test/util.rb Tue Aug 16 15:12:14 2011
@@ -262,7 +262,7 @@ realm = #{@realm}
             "svn://#{@svnserve_host}:#{@svnserve_port}#{@full_repos_path}"
           # Avoid a race by waiting a short time for svnserve to start up.
           # Without this, tests can fail with "Connection refused" errors.
-          sleep 0.1
+          sleep 1
           break
         end
       end

Modified: subversion/branches/issue-3975/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/private/svn_client_private.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/issue-3975/subversion/include/private/svn_client_private.h Tue Aug 16 15:12:14 2011
@@ -48,7 +48,7 @@ svn_client__assert_homogeneous_target_ty
 
 /* Create a svn_client_status_t structure *CST for LOCAL_ABSPATH, shallow
  * copying data from *STATUS wherever possible and retrieving the other values
- * where needed. Peform temporary allocations in SCRATCH_POOL and allocate the
+ * where needed. Perform temporary allocations in SCRATCH_POOL and allocate the
  * result in RESULT_POOL
  */
 svn_error_t *

Modified: subversion/branches/issue-3975/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/private/svn_wc_private.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/issue-3975/subversion/include/private/svn_wc_private.h Tue Aug 16 15:12:14 2011
@@ -1010,9 +1010,6 @@ svn_wc__get_not_present_descendants(cons
  * If DELETED is not NULL, set *DELETED to TRUE if the node is marked as
  * deleted in the working copy.
  *
- * If CONFLICTED is not NULL, set *CONFLICTED to TRUE if the node is somehow
- * conflicted.
- *
  * All output arguments except OBSTRUCTION_STATE can be NULL to ommit the
  * result.
  *
@@ -1023,7 +1020,6 @@ svn_wc__check_for_obstructions(svn_wc_no
                                svn_node_kind_t *kind,
                                svn_boolean_t *added,
                                svn_boolean_t *deleted,
-                               svn_boolean_t *conflicted,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,

Modified: subversion/branches/issue-3975/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/svn_client.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/svn_client.h (original)
+++ subversion/branches/issue-3975/subversion/include/svn_client.h Tue Aug 16 15:12:14 2011
@@ -2105,11 +2105,11 @@ typedef struct svn_client_status_t
    * svn_wc_status_modified and svn_wc_status_conflicted. */
   enum svn_wc_status_kind prop_status;
 
-  /** a node can be 'locked' if a working copy update is in progress or
+  /** A node can be 'locked' if a working copy update is in progress or
    * was interrupted. */
   svn_boolean_t wc_is_locked;
 
-  /** a file or directory can be 'copied' if it's scheduled for
+  /** A file or directory can be 'copied' if it's scheduled for
    * addition-with-history (or part of a subtree that is scheduled as such.).
    */
   svn_boolean_t copied;
@@ -2135,7 +2135,7 @@ typedef struct svn_client_status_t
   /** Last commit author of this item */
   const char *changed_author;
 
-    /** a file or directory can be 'switched' if the switch command has been
+  /** A file or directory can be 'switched' if the switch command has been
    * used.  If this is TRUE, then file_external will be FALSE.
    */
   svn_boolean_t switched;
@@ -2201,11 +2201,24 @@ typedef struct svn_client_status_t
 
   /** @} */
 
-  /** Reserved for libsvn_client's internal use; this value is only to be used for
-   * libsvn_client backwards compatibility wrappers. This value may be NULL or
-   * to other data in future versions. */
+  /** Reserved for libsvn_client's internal use; this value is only to be used
+   * for libsvn_client backwards compatibility wrappers. This value may be NULL
+   * or to other data in future versions. */
   const void *backwards_compatibility_baton;
 
+  /** Set to the local absolute path that this node was moved from, if this
+   * file or directory has been moved here locally. */
+  const char *moved_from_abspath;
+
+  /** Set to the local absolute path that this node was moved to, if this file
+   * or directory has been moved away locally. */
+  const char *moved_to_abspath;
+
+  /* If this file or directory has been moved away locally, set this to the
+   * local absolute path that was the root of the move-away, i.e. to the
+   * op-root of the delete-half of the move operation. */
+  const char *moved_to_op_root_abspath;
+
   /* NOTE! Please update svn_client_status_dup() when adding new fields here. */
 } svn_client_status_t;
 

Modified: subversion/branches/issue-3975/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/svn_wc.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/svn_wc.h (original)
+++ subversion/branches/issue-3975/subversion/include/svn_wc.h Tue Aug 16 15:12:14 2011
@@ -3068,6 +3068,13 @@ typedef struct svn_wc_info_t
   /** The local absolute path of the working copy root.  */
   const char *wcroot_abspath;
 
+  /** The path the node was moved from, if it was moved here. Else NULL.
+   * @since New in 1.8. */
+  const char *moved_from_abspath;
+
+  /** The path the node was moved to, if it was moved away. Else NULL.
+   * @since New in 1.8. */
+  const char *moved_to_abspath;
 } svn_wc_info_t;
 
 /**
@@ -3612,6 +3619,19 @@ typedef struct svn_wc_status3_t
 
   /** @} */
 
+  /** Set to the local absolute path that this node was moved from, if this
+   * file or directory has been moved here locally. */
+  const char *moved_from_abspath;
+
+  /** Set to the local absolute path that this node was moved to, if this file
+   * or directory has been moved away locally. */
+  const char *moved_to_abspath;
+
+  /* If this file or directory has been moved away locally, set this to the
+   * local absolute path that was the root of the move-away, i.e. to the
+   * op-root of the delete-half of the move operation. */
+  const char *moved_to_op_root_abspath;
+
   /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
 } svn_wc_status3_t;
 

Modified: subversion/branches/issue-3975/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/blame.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/blame.c Tue Aug 16 15:12:14 2011
@@ -85,7 +85,7 @@ struct file_rev_baton {
   struct rev *rev;     /* the rev for which blame is being assigned
                           during a diff */
   struct blame_chain *chain;      /* the original blame chain. */
-  const char *tmp_path; /* temp file name to feed svn_io_open_unique_file */
+  const char *repos_root_url;    /* To construct a url */
   apr_pool_t *mainpool;  /* lives during the whole sequence of calls */
   apr_pool_t *lastpool;  /* pool used during previous call */
   apr_pool_t *currpool;  /* pool used during this call */
@@ -424,7 +424,11 @@ file_rev_handler(void *baton, const char
   if (frb->ctx->notify_func2)
     {
       svn_wc_notify_t *notify
-        = svn_wc_create_notify(path, svn_wc_notify_blame_revision, pool);
+            = svn_wc_create_notify_url(
+                            svn_path_url_add_component2(frb->repos_root_url,
+                                                        path+1, pool),
+                            svn_wc_notify_blame_revision, pool);
+      notify->path = path;
       notify->kind = svn_node_none;
       notify->content_state = notify->prop_state
         = svn_wc_notify_state_inapplicable;
@@ -642,8 +646,7 @@ svn_client_blame5(const char *target,
       frb.merged_chain->pool = pool;
     }
 
-  SVN_ERR(svn_io_temp_dir(&frb.tmp_path, pool));
-  frb.tmp_path = svn_dirent_join(frb.tmp_path, "tmp", pool),
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &frb.repos_root_url, pool));
 
   frb.mainpool = pool;
   /* The callback will flip the following two pools, because it needs

Modified: subversion/branches/issue-3975/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/commit.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/commit.c Tue Aug 16 15:12:14 2011
@@ -696,7 +696,6 @@ svn_client_import4(const char *path,
   apr_hash_t *excludes = apr_hash_make(pool);
   svn_node_kind_t kind;
   const char *local_abspath;
-  const char *base_dir_abspath;
   apr_array_header_t *new_entries = apr_array_make(pool, 4,
                                                    sizeof(const char *));
   const char *temp;
@@ -708,7 +707,6 @@ svn_client_import4(const char *path,
                              _("'%s' is not a local path"), path);
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-  base_dir_abspath = local_abspath;
 
   /* Create a new commit item and add it to the array. */
   if (SVN_CLIENT__HAS_LOG_MSG_FUNC(ctx))
@@ -739,8 +737,6 @@ svn_client_import4(const char *path,
     }
 
   SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
-  if (kind == svn_node_file)
-    base_dir_abspath = svn_dirent_dirname(local_abspath, pool);
 
   /* Figure out all the path components we need to create just to have
      a place to stick our imported tree. */
@@ -770,7 +766,7 @@ svn_client_import4(const char *path,
         }
     }
   while ((err = get_ra_editor(&ra_session,
-                              &editor, &edit_baton, ctx, url, base_dir_abspath,
+                              &editor, &edit_baton, ctx, url, NULL,
                               log_msg, NULL, revprop_table, FALSE, NULL, TRUE,
                               commit_callback, commit_baton, subpool)));
 

Modified: subversion/branches/issue-3975/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/diff.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/diff.c Tue Aug 16 15:12:14 2011
@@ -400,15 +400,22 @@ print_git_diff_header_deleted(svn_stream
  * OS using HEADER_ENCODING. All allocations are done in RESULT_POOL. */
 static svn_error_t *
 print_git_diff_header_copied(svn_stream_t *os, const char *header_encoding,
-                             const char *copyfrom_path, const char *path,
+                             const char *copyfrom_path,
+                             svn_revnum_t copyfrom_rev,
+                             const char *path,
                              apr_pool_t *result_pool)
 {
   SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
                                       "diff --git a/%s b/%s%s",
                                       copyfrom_path, path, APR_EOL_STR));
-  SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
-                                      "copy from %s%s", copyfrom_path,
-                                      APR_EOL_STR));
+  if (copyfrom_rev != SVN_INVALID_REVNUM)
+    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
+                                        "copy from %s@%ld%s", copyfrom_path,
+                                        copyfrom_rev, APR_EOL_STR));
+  else
+    SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
+                                        "copy from %s%s", copyfrom_path,
+                                        APR_EOL_STR));
   SVN_ERR(svn_stream_printf_from_utf8(os, header_encoding, result_pool,
                                       "copy to %s%s", path, APR_EOL_STR));
   return SVN_NO_ERROR;
@@ -450,9 +457,10 @@ print_git_diff_header_modified(svn_strea
  * HEADER_ENCODING. Return suitable diff labels for the git diff in *LABEL1
  * and *LABEL2. REPOS_RELPATH1 and REPOS_RELPATH2 are relative to reposroot.
  * are the paths passed to the original diff command. REV1 and REV2 are
- * revisions being diffed. COPYFROM_PATH indicates where the diffed item
- * was copied from. RA_SESSION and WC_CTX are used to adjust paths in the
- * headers to be relative to the repository root.
+ * revisions being diffed. COPYFROM_PATH and COPYFROM_REV indicate where the
+ * diffed item was copied from.
+ * RA_SESSION and WC_CTX are used to adjust paths in the headers to be
+ * relative to the repository root.
  * WC_ROOT_ABSPATH is the absolute path to the root directory of a working
  * copy involved in a repos-wc diff, and may be NULL.
  * Use SCRATCH_POOL for temporary allocations. */
@@ -465,6 +473,7 @@ print_git_diff_header(svn_stream_t *os,
                       svn_revnum_t rev1,
                       svn_revnum_t rev2,
                       const char *copyfrom_path,
+                      svn_revnum_t copyfrom_rev,
                       const char *header_encoding,
                       svn_ra_session_t *ra_session,
                       svn_wc_context_t *wc_ctx,
@@ -484,7 +493,8 @@ print_git_diff_header(svn_stream_t *os,
   else if (operation == svn_diff_op_copied)
     {
       SVN_ERR(print_git_diff_header_copied(os, header_encoding,
-                                           copyfrom_path, repos_relpath2,
+                                           copyfrom_path, copyfrom_rev,
+                                           repos_relpath2,
                                            scratch_pool));
       *label1 = diff_label(apr_psprintf(scratch_pool, "a/%s", copyfrom_path),
                            rev1, scratch_pool);
@@ -605,6 +615,7 @@ display_prop_diffs(const apr_array_heade
           SVN_ERR(print_git_diff_header(os, &label1, &label2,
                                         svn_diff_op_modified,
                                         path1, path2, rev1, rev2, NULL,
+                                        SVN_INVALID_REVNUM,
                                         encoding, ra_session, wc_ctx,
                                         wc_root_abspath, pool));
           SVN_ERR(svn_stream_close(os));
@@ -899,6 +910,7 @@ diff_content_changed(const char *path,
                      const char *mimetype2,
                      svn_diff_operation_kind_t operation,
                      const char *copyfrom_path,
+                     svn_revnum_t copyfrom_rev,
                      void *diff_baton)
 {
   struct diff_cmd_baton *diff_cmd_baton = diff_baton;
@@ -1028,6 +1040,7 @@ diff_content_changed(const char *path,
               SVN_ERR(print_git_diff_header(os, &label1, &label2, operation,
                                             tmp_path1, tmp_path2, rev1, rev2,
                                             copyfrom_path,
+                                            copyfrom_rev,
                                             diff_cmd_baton->header_encoding,
                                             diff_cmd_baton->ra_session,
                                             diff_cmd_baton->wc_ctx,
@@ -1098,7 +1111,8 @@ diff_file_changed(svn_wc_notify_state_t 
     SVN_ERR(diff_content_changed(path,
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
-                                 svn_diff_op_modified, NULL, diff_baton));
+                                 svn_diff_op_modified, NULL,
+                                 SVN_INVALID_REVNUM, diff_baton));
   if (prop_changes->nelts > 0)
     SVN_ERR(diff_props_changed(prop_state, tree_conflicted,
                                path, FALSE, prop_changes,
@@ -1152,12 +1166,13 @@ diff_file_added(svn_wc_notify_state_t *c
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
                                  svn_diff_op_copied, copyfrom_path,
-                                 diff_baton));
+                                 copyfrom_revision, diff_baton));
   else if (tmpfile1)
     SVN_ERR(diff_content_changed(path,
                                  tmpfile1, tmpfile2, rev1, rev2,
                                  mimetype1, mimetype2,
-                                 svn_diff_op_added, NULL, diff_baton));
+                                 svn_diff_op_added, NULL, SVN_INVALID_REVNUM,
+                                 diff_baton));
   if (prop_changes->nelts > 0)
     SVN_ERR(diff_props_changed(prop_state, tree_conflicted,
                                path, FALSE, prop_changes,
@@ -1208,7 +1223,8 @@ diff_file_deleted(svn_wc_notify_state_t 
                                      diff_cmd_baton->revnum1,
                                      diff_cmd_baton->revnum2,
                                      mimetype1, mimetype2,
-                                     svn_diff_op_deleted, NULL, diff_baton));
+                                     svn_diff_op_deleted, NULL,
+                                     SVN_INVALID_REVNUM, diff_baton));
     }
 
   /* We don't list all the deleted properties. */

Modified: subversion/branches/issue-3975/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/merge.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/merge.c Tue Aug 16 15:12:14 2011
@@ -427,7 +427,6 @@ perform_obstruction_check(svn_wc_notify_
                                          kind,
                                          added,
                                          deleted,
-                                         NULL,
                                          wc_ctx, local_abspath,
                                          check_root,
                                          scratch_pool));

Modified: subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.c Tue Aug 16 15:12:14 2011
@@ -476,28 +476,66 @@ svn_client__get_repos_mergeinfo_catalog(
   apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
-  svn_mergeinfo_t repos_mergeinfo;
+  svn_mergeinfo_t repos_mergeinfo_cat;
   apr_array_header_t *rel_paths = apr_array_make(scratch_pool, 1,
                                                  sizeof(rel_path));
 
   APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
 
   /* Fetch the mergeinfo. */
-  err = svn_ra_get_mergeinfo2(ra_session, &repos_mergeinfo, rel_paths, rev,
-                              inherit, validate_inherited_mergeinfo,
+  err = svn_ra_get_mergeinfo2(ra_session, &repos_mergeinfo_cat, rel_paths,
+                              rev, inherit, validate_inherited_mergeinfo,
                               include_descendants, result_pool);
   if (err)
     {
       if (squelch_incapable && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
         {
           svn_error_clear(err);
-          repos_mergeinfo = NULL;
+          *mergeinfo_cat = NULL;
         }
       else
         return svn_error_trace(err);
     }
 
-  *mergeinfo_cat = repos_mergeinfo;
+  if (repos_mergeinfo_cat == NULL)
+    {
+      *mergeinfo_cat = NULL;
+    }
+  else
+    {
+      const char *repos_root;
+      const char *session_url;
+
+      SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root, scratch_pool));
+      SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, scratch_pool));
+
+      if (strcmp(repos_root, session_url) == 0)
+        {
+          *mergeinfo_cat = repos_mergeinfo_cat;
+        }
+      else
+        {
+          apr_hash_index_t *hi;
+          svn_mergeinfo_catalog_t rekeyed_mergeinfo_cat =
+            apr_hash_make(result_pool);
+
+          for (hi = apr_hash_first(scratch_pool, repos_mergeinfo_cat);
+               hi;
+               hi = apr_hash_next(hi))
+            {
+              const char *path =
+                svn_path_url_add_component2(session_url,
+                                            svn__apr_hash_index_key(hi),
+                                            scratch_pool);
+              SVN_ERR(svn_ra_get_path_relative_to_root(ra_session, &path,
+                                                       path,
+                                                       result_pool));
+              apr_hash_set(rekeyed_mergeinfo_cat, path, APR_HASH_KEY_STRING,
+                           svn__apr_hash_index_val(hi));
+            }
+          *mergeinfo_cat = rekeyed_mergeinfo_cat;
+        }
+    }
   return SVN_NO_ERROR;
 }
 
@@ -560,6 +598,8 @@ svn_client__get_wc_or_repos_mergeinfo_ca
   const char *local_abspath;
   const char *repos_root;
   const char *repos_relpath;
+  svn_mergeinfo_catalog_t target_mergeinfo_cat_wc = NULL;
+  svn_mergeinfo_catalog_t target_mergeinfo_cat_repos = NULL;
 
   SVN_ERR(svn_dirent_get_absolute(&local_abspath, target_wcpath,
                                   scratch_pool));
@@ -581,23 +621,37 @@ svn_client__get_wc_or_repos_mergeinfo_ca
   else
     url = NULL;
 
+  if (!repos_only)
+    {
+      SVN_ERR(svn_client__get_wc_mergeinfo_catalog(&target_mergeinfo_cat_wc,
+                                                   inherited,
+                                                   include_descendants,
+                                                   inherit,
+                                                   local_abspath,
+                                                   NULL, NULL,
+                                                   ignore_invalid_mergeinfo,
+                                                   ctx,
+                                                   result_pool,
+                                                   scratch_pool));
+
+      /* If we want LOCAL_ABSPATH's inherited mergeinfo, were we able to
+         get it from the working copy?  If not, then we must ask the
+         repository. */
+      if (! ((*inherited)
+             || (inherit == svn_mergeinfo_explicit)
+             || (repos_relpath
+                 && target_mergeinfo_cat_wc
+                 && apr_hash_get(target_mergeinfo_cat_wc, repos_relpath,
+                                 APR_HASH_KEY_STRING))))
+        {
+          repos_only = TRUE;
+          /* We already have any subtree mergeinfo from the working copy, no
+             need to ask the server for it again. */
+          include_descendants = FALSE;
+        }
+    }
+
   if (repos_only)
-    *target_mergeinfo_catalog = NULL;
-  else
-    SVN_ERR(svn_client__get_wc_mergeinfo_catalog(target_mergeinfo_catalog,
-                                                 inherited,
-                                                 include_descendants,
-                                                 inherit,
-                                                 local_abspath,
-                                                 NULL, NULL,
-                                                 ignore_invalid_mergeinfo,
-                                                 ctx,
-                                                 result_pool, scratch_pool));
-
-  /* If there is no WC mergeinfo check the repository for inherited
-     mergeinfo, unless TARGET_WCPATH is a local addition or has a
-     local modification which has removed all of its pristine mergeinfo. */
-  if (*target_mergeinfo_catalog == NULL)
     {
       /* No need to check the repos if this is a local addition. */
       if (url != NULL)
@@ -631,13 +685,14 @@ svn_client__get_wc_or_repos_mergeinfo_ca
                 }
 
               SVN_ERR(svn_client__get_repos_mergeinfo_catalog(
-                        target_mergeinfo_catalog, ra_session,
+                        &target_mergeinfo_cat_repos, ra_session,
                         "", target_rev, inherit,
-                        TRUE, FALSE, TRUE,
+                        TRUE, include_descendants, TRUE,
                         result_pool, scratch_pool));
 
-              if (*target_mergeinfo_catalog
-                  && apr_hash_get(*target_mergeinfo_catalog, "",
+              if (target_mergeinfo_cat_repos
+                  && apr_hash_get(target_mergeinfo_cat_repos,
+                                  repos_relpath,
                                   APR_HASH_KEY_STRING))
                 {
                   *inherited = TRUE;
@@ -660,6 +715,25 @@ svn_client__get_wc_or_repos_mergeinfo_ca
             }
         }
     }
+
+  /* Combine the mergeinfo from the working copy and repository as needed. */
+  if (target_mergeinfo_cat_wc)
+    {
+      *target_mergeinfo_catalog = target_mergeinfo_cat_wc;
+      if (target_mergeinfo_cat_repos)
+        SVN_ERR(svn_mergeinfo_catalog_merge(*target_mergeinfo_catalog,
+                                            target_mergeinfo_cat_repos,
+                                            result_pool, scratch_pool));
+    }
+  else if (target_mergeinfo_cat_repos)
+    {
+      *target_mergeinfo_catalog = target_mergeinfo_cat_repos;
+    }
+  else
+    {
+      *target_mergeinfo_catalog = NULL;
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1074,41 +1148,11 @@ get_mergeinfo(svn_mergeinfo_catalog_t *m
 
   if (use_url)
     {
-      svn_mergeinfo_catalog_t tmp_catalog;
-
       rev = peg_rev;
       SVN_ERR(svn_client__get_repos_mergeinfo_catalog(
-        &tmp_catalog, ra_session, "", rev, svn_mergeinfo_inherited,
+        mergeinfo_catalog, ra_session, "", rev, svn_mergeinfo_inherited,
         FALSE, include_descendants, TRUE,
         result_pool, scratch_pool));
-
-      /* If we're not querying the root of the repository, the catalog
-         we fetched will be keyed on paths relative to the session
-         URL.  But our caller is expecting repository relpaths.  So we
-         do a little dance...  */
-      if (tmp_catalog && (strcmp(url, *repos_root) != 0))
-        {
-          apr_hash_index_t *hi;
-
-          *mergeinfo_catalog = apr_hash_make(result_pool);
-
-          for (hi = apr_hash_first(scratch_pool, tmp_catalog);
-               hi; hi = apr_hash_next(hi))
-            {
-              /* session-relpath -> repos-url -> repos-relpath */
-              const char *path =
-                svn_path_url_add_component2(url, svn__apr_hash_index_key(hi),
-                                            scratch_pool);
-              SVN_ERR(svn_ra_get_path_relative_to_root(ra_session, &path, path,
-                                                       result_pool));
-              apr_hash_set(*mergeinfo_catalog, path, APR_HASH_KEY_STRING,
-                           svn__apr_hash_index_val(hi));
-            }
-        }
-      else
-        {
-          *mergeinfo_catalog = tmp_catalog;
-        }
     }
   else /* ! svn_path_is_url() */
     {
@@ -1312,6 +1356,8 @@ find_nearest_ancestor(const apr_array_he
    svn_log_entry_receiver_t callback. */
 struct filter_log_entry_baton_t
 {
+  /* Is TRUE if RANGELIST describes potentially merged revisions, is FALSE
+     if RANGELIST describes potentially eligible revisions. */
   svn_boolean_t filtering_merged;
 
   /* Unsorted array of repository relative paths representing the merge
@@ -1329,8 +1375,9 @@ struct filter_log_entry_baton_t
      TARGET_MERGEINFO_CATALOG. */
   apr_array_header_t *depth_first_catalog_index;
 
-  /* A rangelist describing all the ranges merged to ABS_REPOS_TARGET_PATH
-     from the */
+  /* 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;
 
   /* The wrapped svn_log_entry_receiver_t callback and baton which
@@ -1345,9 +1392,18 @@ struct filter_log_entry_baton_t
    `struct filter_log_entry_baton_t *'.
 
    Call the wrapped log receiver BATON->log_receiver (with
-   BATON->log_receiver_baton), only if the log entry falls within the
-   ranges in BATON->rangelist.
- */
+   BATON->log_receiver_baton) if:
+   
+   BATON->FILTERING_MERGED is FALSE and the changes represented by LOG_ENTRY
+   have been fully merged from BATON->MERGE_SOURCE_PATHS to the WC target
+   based on the mergeinfo for the WC contained in BATON->TARGET_MERGEINFO_CATALOG.
+
+   Or
+
+   BATON->FILTERING_MERGED is TRUE and the changes represented by LOG_ENTRY
+   have not been merged, or only partially merged, from
+   BATON->MERGE_SOURCE_PATHS to the WC target based on the mergeinfo for the
+   WC contained in BATON->TARGET_MERGEINFO_CATALOG. */
 static svn_error_t *
 filter_log_entry_with_rangelist(void *baton,
                                 svn_log_entry_t *log_entry,
@@ -1410,6 +1466,7 @@ filter_log_entry_with_rangelist(void *ba
           apr_hash_index_t *hi2;
           svn_boolean_t found_this_revision = FALSE;
           const char *merge_source_rel_target;
+          const char *merge_source_path;
 
           svn_pool_clear(iterpool);
 
@@ -1417,8 +1474,8 @@ filter_log_entry_with_rangelist(void *ba
              merge sources.  If not then ignore this path.  */
           for (i = 0; i < fleb->merge_source_paths->nelts; i++)
             {
-              const char *merge_source_path
-                = APR_ARRAY_IDX(fleb->merge_source_paths, i, const char *);
+              merge_source_path = APR_ARRAY_IDX(fleb->merge_source_paths,
+                                                i, const char *);
 
               merge_source_rel_target
                 = svn_fspath__skip_ancestor(merge_source_path, path);
@@ -1452,20 +1509,33 @@ filter_log_entry_with_rangelist(void *ba
                    hi2;
                    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_ERR(svn_rangelist_intersect(&intersection, rangelist,
-                                                  this_rev_rangelist, FALSE,
-                                                  iterpool));
-                  if (intersection->nelts)
+
+                  /* Does the mergeinfo for PATH reflect if
+                     LOG_ENTRY->REVISION was previously merged
+                     from MERGE_SOURCE_PATH? */
+                  if (svn_fspath__is_ancestor(merge_source_path,
+                                              mergeinfo_path))
                     {
+                      /* Something was merged from MERGE_SOURCE_PATH, does
+                         it include LOG_ENTRY->REVISION? */
                       SVN_ERR(svn_rangelist_intersect(&intersection,
                                                       rangelist,
                                                       this_rev_rangelist,
-                                                      TRUE, iterpool));
+                                                      FALSE,
+                                                      iterpool));
                       if (intersection->nelts)
                         {
-                          found_this_revision = TRUE;
-                          break;
+                          SVN_ERR(svn_rangelist_intersect(&intersection,
+                                                          rangelist,
+                                                          this_rev_rangelist,
+                                                          TRUE, iterpool));
+                          if (intersection->nelts)
+                            {
+                              found_this_revision = TRUE;
+                              break;
+                            }
                         }
                     }
                 }

Modified: subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/mergeinfo.h Tue Aug 16 15:12:14 2011
@@ -186,7 +186,7 @@ svn_client__get_repos_mergeinfo(svn_ra_s
 /* If INCLUDE_DESCENDANTS is FALSE, behave exactly like
    svn_client__get_repos_mergeinfo() except the mergeinfo for REL_PATH
    is put in the mergeinfo catalog MERGEINFO_CAT, with the key being
-   REL_PATH itself.
+   the repository root-relative path of REL_PATH.
 
    If INCLUDE_DESCENDANTS is true, then any subtrees under REL_PATH
    with explicit mergeinfo are also included in MERGEINFO_CAT.  The

Modified: subversion/branches/issue-3975/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/patch.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/patch.c Tue Aug 16 15:12:14 2011
@@ -365,7 +365,7 @@ obtain_eol_and_keywords_for_file(apr_has
 static svn_error_t *
 resolve_target_path(patch_target_t *target,
                     const char *path_from_patchfile,
-                    const char *local_abspath,
+                    const char *wcroot_abspath,
                     int strip_count,
                     svn_boolean_t prop_changes_only,
                     svn_wc_context_t *wc_ctx,
@@ -398,7 +398,8 @@ resolve_target_path(patch_target_t *targ
 
   if (svn_dirent_is_absolute(stripped_path))
     {
-      target->local_relpath = svn_dirent_is_child(local_abspath, stripped_path,
+      target->local_relpath = svn_dirent_is_child(wcroot_abspath,
+                                                  stripped_path,
                                                   result_pool);
 
       if (! target->local_relpath)
@@ -419,7 +420,7 @@ resolve_target_path(patch_target_t *targ
   /* Make sure the path is secure to use. We want the target to be inside
    * of the working copy and not be fooled by symlinks it might contain. */
   SVN_ERR(svn_dirent_is_under_root(&under_root,
-                                   &target->local_abspath, local_abspath,
+                                   &target->local_abspath, wcroot_abspath,
                                    target->local_relpath, result_pool));
 
   if (! under_root)
@@ -478,11 +479,32 @@ resolve_target_path(patch_target_t *targ
       return SVN_NO_ERROR;
     }
 
-  /* ### Shouldn't libsvn_wc flag an obstruction in this case? */
-  if (target->locally_deleted && target->kind_on_disk != svn_node_none)
+  if (target->locally_deleted)
     {
-      target->skipped = TRUE;
-      return SVN_NO_ERROR;
+      const char *moved_to_abspath;
+
+      SVN_ERR(svn_wc__node_was_moved_away(&moved_to_abspath, NULL,
+                                          wc_ctx, target->local_abspath,
+                                          result_pool, scratch_pool));
+      if (moved_to_abspath)
+        {
+          target->local_abspath = moved_to_abspath;
+          target->local_relpath = svn_dirent_skip_ancestor(wcroot_abspath,
+                                                          moved_to_abspath);
+          SVN_ERR_ASSERT(target->local_relpath &&
+                         target->local_relpath[0] != '\0');
+
+          /* As far as we are concerned this target is not locally deleted. */
+          target->locally_deleted = FALSE;
+
+          SVN_ERR(svn_io_check_path(target->local_abspath,
+                                    &target->kind_on_disk, scratch_pool));
+        }
+      else if (target->kind_on_disk != svn_node_none)
+        {
+          target->skipped = TRUE;
+          return SVN_NO_ERROR;
+        }
     }
 
   return SVN_NO_ERROR;
@@ -828,7 +850,7 @@ choose_target_filename(const svn_patch_t
 static svn_error_t *
 init_patch_target(patch_target_t **patch_target,
                   const svn_patch_t *patch,
-                  const char *base_dir,
+                  const char *wcroot_abspath,
                   svn_wc_context_t *wc_ctx, int strip_count,
                   svn_boolean_t remove_tempfiles,
                   apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -873,7 +895,7 @@ init_patch_target(patch_target_t **patch
   target->prop_targets = apr_hash_make(result_pool);
 
   SVN_ERR(resolve_target_path(target, choose_target_filename(patch),
-                              base_dir, strip_count, prop_changes_only,
+                              wcroot_abspath, strip_count, prop_changes_only,
                               wc_ctx, result_pool, scratch_pool));
   if (! target->skipped)
     {

Modified: subversion/branches/issue-3975/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/status.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/status.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/status.c Tue Aug 16 15:12:14 2011
@@ -385,7 +385,7 @@ svn_client_status5(svn_revnum_t *result_
           svn_boolean_t added;
 
           /* Our status target does not exist in HEAD.  If we've got
-             it localled added, that's okay.  But if it was previously
+             it locally added, that's okay.  But if it was previously
              versioned, then it must have since been deleted from the
              repository.  (Note that "locally replaced" doesn't count
              as "added" in this case.)  */
@@ -563,6 +563,17 @@ svn_client_status_dup(const svn_client_s
                                                              result_pool);
     }
 
+  if (status->moved_from_abspath)
+    st->moved_from_abspath =
+      apr_pstrdup(result_pool, status->moved_from_abspath);
+
+  if (status->moved_to_abspath)
+    st->moved_to_abspath = apr_pstrdup(result_pool, status->moved_to_abspath);
+
+  if (status->moved_to_op_root_abspath)
+    st->moved_to_op_root_abspath =
+      apr_pstrdup(result_pool, status->moved_to_op_root_abspath);
+
   return st;
 }
 
@@ -667,6 +678,10 @@ svn_client__create_status(svn_client_sta
         (*cst)->node_status = svn_wc_status_conflicted;
     }
 
+  (*cst)->moved_from_abspath = status->moved_from_abspath;
+  (*cst)->moved_to_abspath = status->moved_to_abspath;
+  (*cst)->moved_to_op_root_abspath = status->moved_to_op_root_abspath;
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/issue-3975/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_fs_fs/tree.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_fs_fs/tree.c Tue Aug 16 15:12:14 2011
@@ -2925,7 +2925,7 @@ prev_location(const char **prev_path,
               const char *path,
               apr_pool_t *pool)
 {
-  const char *copy_path, *copy_src_path, *remainder = "";
+  const char *copy_path, *copy_src_path, *remainder_path = "";
   svn_fs_root_t *copy_root;
   svn_revnum_t copy_src_rev;
 
@@ -2955,8 +2955,8 @@ prev_location(const char **prev_path,
   SVN_ERR(fs_copied_from(&copy_src_rev, &copy_src_path,
                          copy_root, copy_path, pool));
   if (strcmp(copy_path, path) != 0)
-    remainder = svn_relpath__is_child(copy_path, path, pool);
-  *prev_path = svn_fspath__join(copy_src_path, remainder, pool);
+    remainder_path = svn_relpath__is_child(copy_path, path, pool);
+  *prev_path = svn_fspath__join(copy_src_path, remainder_path, pool);
   *prev_rev = copy_src_rev;
   return SVN_NO_ERROR;
 }
@@ -3184,7 +3184,7 @@ history_prev(void *baton, apr_pool_t *po
 
   if (copyroot_rev > commit_rev)
     {
-      const char *remainder;
+      const char *remainder_path;
       const char *copy_dst, *copy_src;
       svn_fs_root_t *copyroot_root;
 
@@ -3202,11 +3202,11 @@ history_prev(void *baton, apr_pool_t *po
          one of these other criteria ... ### for now just fallback to
          the old copy hunt algorithm. */
       if (strcmp(path, copy_dst) == 0)
-        remainder = "";
+        remainder_path = "";
       else
-        remainder = svn_relpath__is_child(copy_dst, path, pool);
+        remainder_path = svn_relpath__is_child(copy_dst, path, pool);
 
-      if (remainder)
+      if (remainder_path)
         {
           /* If we get here, then our current path is the destination
              of, or the child of the destination of, a copy.  Fill
@@ -3215,7 +3215,7 @@ history_prev(void *baton, apr_pool_t *po
           SVN_ERR(svn_fs_fs__dag_get_copyfrom_path(&copy_src, node, pool));
 
           dst_rev = copyroot_rev;
-          src_path = svn_fspath__join(copy_src, remainder, pool);
+          src_path = svn_fspath__join(copy_src, remainder_path, pool);
         }
     }
 

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_neon/fetch.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_neon/fetch.c Tue Aug 16 15:12:14 2011
@@ -528,7 +528,10 @@ static svn_error_t *simple_fetch_file(sv
                              TRUE, pool));
 
   /* close the handler, since the file reading completed successfully. */
-  return (*frc.handler)(NULL, frc.handler_baton);
+  if (frc.stream)
+    return svn_stream_close(frc.stream);
+  else
+    return (*frc.handler)(NULL, frc.handler_baton);
 }
 
 /* Helper for svn_ra_neon__get_file.  This implements

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c Tue Aug 16 15:12:14 2011
@@ -385,14 +385,6 @@ handle_lock(serf_request_t *request,
           return err;
         }
 
-      /* 405 == Method Not Allowed (Occurs when trying to lock a working
-         copy path which no longer exists at HEAD in the repository. */
-      if (sl.code == 405)
-        return svn_error_createf(SVN_ERR_FS_OUT_OF_DATE,
-                                 NULL,
-                                 _("Lock request failed: %d %s"),
-                                   ctx->status_code, ctx->reason);
-
       headers = serf_bucket_response_get_headers(response);
 
       val = serf_bucket_headers_get(headers, SVN_DAV_LOCK_OWNER_HEADER);

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/merge.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/merge.c Tue Aug 16 15:12:14 2011
@@ -294,8 +294,7 @@ end_merge(svn_ra_serf__xml_parser_t *par
           href = apr_hash_get(info->props, "href", APR_HASH_KEY_STRING);
           if (! svn_urlpath__is_ancestor(ctx->merge_url, href))
             {
-              /* ### need something better than APR_EGENERAL */
-              return svn_error_createf(APR_EGENERAL, NULL,
+              return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
                                        _("A MERGE response for '%s' is not "
                                          "a child of the destination ('%s')"),
                                        href, ctx->merge_url);

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/ra_serf.h Tue Aug 16 15:12:14 2011
@@ -629,6 +629,11 @@ struct svn_ra_serf__xml_parser_t {
 
      See libsvn_ra_serf/util.c  */
   struct svn_ra_serf__pending_t *pending;
+
+  /* Response restart support */
+  const void *headers_baton; /* Last pointer to headers */
+  apr_off_t skip_size; /* Number of bytes to skip */
+  apr_off_t read_size; /* Number of bytes read from response */
 };
 
 /*

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/serf.c Tue Aug 16 15:12:14 2011
@@ -39,10 +39,11 @@
 #include "../libsvn_ra/ra_loader.h"
 #include "svn_config.h"
 #include "svn_delta.h"
-#include "svn_version.h"
 #include "svn_dirent_uri.h"
+#include "svn_hash.h"
 #include "svn_path.h"
 #include "svn_time.h"
+#include "svn_version.h"
 
 #include "private/svn_dav_protocol.h"
 #include "private/svn_dep_compat.h"
@@ -790,52 +791,68 @@ path_dirent_walker(void *baton,
 }
 
 static const svn_ra_serf__dav_props_t *
-get_dirent_props(apr_uint32_t dirent_fields, apr_pool_t *pool)
+get_dirent_props(apr_uint32_t dirent_fields,
+                 svn_ra_serf__session_t *session,
+                 apr_pool_t *pool)
 {
   svn_ra_serf__dav_props_t *prop;
   apr_array_header_t *props = apr_array_make
     (pool, 7, sizeof(svn_ra_serf__dav_props_t));
 
-  if (dirent_fields & SVN_DIRENT_KIND)
+  if (session->supports_deadprop_count != svn_tristate_false
+      || ! (dirent_fields & SVN_DIRENT_HAS_PROPS))
     {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = "resourcetype";
-    }
+      if (dirent_fields & SVN_DIRENT_KIND)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "resourcetype";
+        }
 
-  if (dirent_fields & SVN_DIRENT_SIZE)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = "getcontentlength";
-    }
+      if (dirent_fields & SVN_DIRENT_SIZE)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "getcontentlength";
+        }
 
-  if (dirent_fields & SVN_DIRENT_HAS_PROPS)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = SVN_DAV_PROP_NS_DAV;
-      prop->name = "deadprop-count";
-    }
+      if (dirent_fields & SVN_DIRENT_HAS_PROPS)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = SVN_DAV_PROP_NS_DAV;
+          prop->name = "deadprop-count";
+        }
 
-  if (dirent_fields & SVN_DIRENT_CREATED_REV)
-    {
-      svn_ra_serf__dav_props_t *p = apr_array_push(props);
-      p->namespace = "DAV:";
-      p->name = SVN_DAV__VERSION_NAME;
-    }
+      if (dirent_fields & SVN_DIRENT_CREATED_REV)
+        {
+          svn_ra_serf__dav_props_t *p = apr_array_push(props);
+          p->namespace = "DAV:";
+          p->name = SVN_DAV__VERSION_NAME;
+        }
 
-  if (dirent_fields & SVN_DIRENT_TIME)
-    {
-      prop = apr_array_push(props);
-      prop->namespace = "DAV:";
-      prop->name = SVN_DAV__CREATIONDATE;
-    }
+      if (dirent_fields & SVN_DIRENT_TIME)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = SVN_DAV__CREATIONDATE;
+        }
 
-  if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+      if (dirent_fields & SVN_DIRENT_LAST_AUTHOR)
+        {
+          prop = apr_array_push(props);
+          prop->namespace = "DAV:";
+          prop->name = "creator-displayname";
+        }
+    }
+  else
     {
+      /* We found an old subversion server that can't handle
+         the deadprop-count property in the way we expect.
+
+         The neon behavior is to retrieve all properties in this case */
       prop = apr_array_push(props);
       prop->namespace = "DAV:";
-      prop->name = "creator-displayname";
+      prop->name = "allprop";
     }
 
   prop = apr_array_push(props);
@@ -859,10 +876,12 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
   svn_revnum_t fetched_rev;
   svn_error_t *err;
   struct dirent_walker_baton_t dwb;
+  svn_tristate_t deadprop_count = svn_tristate_unknown;
 
   err = fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
                          session, rel_path, revision,
-                         get_dirent_props(SVN_DIRENT_ALL, pool), pool);
+                         get_dirent_props(SVN_DIRENT_ALL, session, pool),
+                         pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -876,12 +895,33 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
     }
 
   dwb.entry = apr_pcalloc(pool, sizeof(*dwb.entry));
-  dwb.supports_deadprop_count = NULL;
+  dwb.supports_deadprop_count = &deadprop_count;
   dwb.result_pool = pool;
   SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
                                       dirent_walker, &dwb,
                                       pool));
 
+  if (deadprop_count == svn_tristate_false
+      && session->supports_deadprop_count == svn_tristate_unknown
+      && !dwb.entry->has_props)
+    {
+      /* We have to requery as the server didn't give us the right
+         information */
+      session->supports_deadprop_count = svn_tristate_false;
+
+      SVN_ERR(fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
+                               session, rel_path, fetched_rev,
+                               get_dirent_props(SVN_DIRENT_ALL, session, pool),
+                               pool));
+
+      SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
+                                      dirent_walker, &dwb,
+                                      pool));
+    }
+
+  if (deadprop_count != svn_tristate_unknown)
+    session->supports_deadprop_count = deadprop_count;
+
   *dirent = dwb.entry;
 
   return SVN_NO_ERROR;
@@ -958,7 +998,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
                                           path, revision, "1",
                                           get_dirent_props(dirent_fields,
-                                                           pool),
+                                                           session, pool),
                                           pool, pool));
 
       /* Check if the path is really a directory. */
@@ -977,7 +1017,30 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
                                           &dirent_walk, pool));
 
+      if (dirent_walk.supports_deadprop_count == svn_tristate_false
+          && session->supports_deadprop_count == svn_tristate_unknown
+          && dirent_fields & SVN_DIRENT_HAS_PROPS)
+        {
+          /* We have to requery as the server didn't give us the right
+             information */
+          session->supports_deadprop_count = svn_tristate_false;
+          SVN_ERR(svn_ra_serf__retrieve_props(&props, session,
+                                              session->conns[0],
+                                              path, revision, "1",
+                                              get_dirent_props(dirent_fields,
+                                                               session, pool),
+                                              pool, pool));
+
+          SVN_ERR(svn_hash__clear(dirent_walk.full_paths, pool));
+          SVN_ERR(svn_hash__clear(dirent_walk.base_paths, pool));
+
+          SVN_ERR(svn_ra_serf__walk_all_paths(props, revision,
+                                              path_dirent_walker,
+                                              &dirent_walk, pool));
+        }
+
       *dirents = dirent_walk.base_paths;
+
       if (dirent_walk.supports_deadprop_count != svn_tristate_unknown)
         session->supports_deadprop_count = dirent_walk.supports_deadprop_count;
     }
@@ -1047,7 +1110,7 @@ svn_ra_serf__get_uuid(svn_ra_session_t *
       SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, NULL, pool));
       if (!session->uuid)
         {
-          return svn_error_create(APR_EGENERAL, NULL,
+          return svn_error_create(SVN_ERR_RA_DAV_RESPONSE_HEADER_BADNESS, NULL,
                                   _("The UUID property was not found on the "
                                     "resource or any of its parents"));
         }

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/update.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/update.c Tue Aug 16 15:12:14 2011
@@ -918,6 +918,7 @@ handle_fetch(serf_request_t *request,
 
       if (fetch_ctx->aborted_read)
         {
+          apr_off_t skip;
           /* We haven't caught up to where we were before. */
           if (fetch_ctx->read_size < fetch_ctx->aborted_read_size)
             {
@@ -938,9 +939,10 @@ handle_fetch(serf_request_t *request,
           /* Woo-hoo.  We're back. */
           fetch_ctx->aborted_read = FALSE;
 
-          /* Increment data and len by the difference. */
-          data += fetch_ctx->read_size - fetch_ctx->aborted_read_size;
-          len = fetch_ctx->read_size - fetch_ctx->aborted_read_size;
+          /* Update data and len to just provide the new data. */
+          skip = len - (fetch_ctx->read_size - fetch_ctx->aborted_read_size);
+          data += skip;
+          len -= skip;
         }
 
       if (fetch_ctx->delta_stream)
@@ -983,7 +985,12 @@ handle_fetch(serf_request_t *request,
              ### end of this block, so it will work for now.  */
           apr_pool_t *scratch_pool = info->editor_pool;
 
-          err = info->textdelta(NULL, info->textdelta_baton);
+          if (fetch_ctx->delta_stream)
+            err = svn_error_trace(svn_stream_close(fetch_ctx->delta_stream));
+          else
+            err = svn_error_trace(info->textdelta(NULL,
+                                                  info->textdelta_baton));
+
           if (err)
             {
               return error_fetch(request, fetch_ctx, err);
@@ -1021,7 +1028,7 @@ handle_fetch(serf_request_t *request,
 
           if (err)
             {
-              return error_fetch(request, fetch_ctx, err);
+              return svn_error_trace(error_fetch(request, fetch_ctx, err));
             }
 
           fetch_ctx->done = TRUE;

Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/util.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/util.c Tue Aug 16 15:12:14 2011
@@ -821,7 +821,7 @@ start_error(svn_ra_serf__xml_parser_t *p
         }
       else
         {
-          ctx->error->apr_err = APR_EGENERAL;
+          ctx->error->apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
         }
 
       /* Start collecting cdata. */
@@ -1497,6 +1497,21 @@ inject_to_parser(svn_ra_serf__xml_parser
   return SVN_NO_ERROR;
 }
 
+/* Apr pool cleanup handler to release an XML_Parser in success and error
+   conditions */
+static apr_status_t
+xml_parser_cleanup(void *baton)
+{
+  XML_Parser *xmlp = baton;
+
+  if (*xmlp)
+    {
+      XML_ParserFree(*xmlp);
+      *xmlp = NULL;
+    }
+
+  return APR_SUCCESS;
+}
 
 svn_error_t *
 svn_ra_serf__process_pending(svn_ra_serf__xml_parser_t *parser,
@@ -1633,7 +1648,7 @@ svn_ra_serf__process_pending(svn_ra_serf
          return status. We just don't care.  */
       (void) XML_Parse(parser->xmlp, NULL, 0, 1);
 
-      XML_ParserFree(parser->xmlp);
+      apr_pool_cleanup_run(parser->pool, &parser->xmlp, xml_parser_cleanup);
       parser->xmlp = NULL;
       add_done_item(parser);
     }
@@ -1690,9 +1705,27 @@ svn_ra_serf__handle_xml_parser(serf_requ
       return SVN_NO_ERROR;
     }
 
+  if (ctx->headers_baton == NULL)
+    ctx->headers_baton = serf_bucket_response_get_headers(response);
+  else if (ctx->headers_baton != serf_bucket_response_get_headers(response))
+    {
+      /* We got a new response to an existing parser...
+         This tells us the connection has restarted and we should continue
+         where we stopped last time.
+       */
+
+      /* Is this a second attempt?? */
+      if (!ctx->skip_size)
+        ctx->skip_size = ctx->read_size;
+
+      ctx->read_size = 0; /* New request, nothing read */
+    }
+
   if (!ctx->xmlp)
     {
       ctx->xmlp = XML_ParserCreate(NULL);
+      apr_pool_cleanup_register(ctx->pool, &ctx->xmlp, xml_parser_cleanup,
+                                apr_pool_cleanup_null);
       XML_SetUserData(ctx->xmlp, ctx);
       XML_SetElementHandler(ctx->xmlp, start_xml, end_xml);
       if (ctx->cdata)
@@ -1732,6 +1765,35 @@ svn_ra_serf__handle_xml_parser(serf_requ
           return svn_error_wrap_apr(status, NULL);
         }
 
+      ctx->read_size += len;
+
+      if (ctx->skip_size)
+        {
+          /* Handle restarted requests correctly: Skip what we already read */
+          apr_size_t skip;
+
+          if (ctx->skip_size >= ctx->read_size)
+            {
+            /* Eek.  What did the file shrink or something? */
+              if (APR_STATUS_IS_EOF(status))
+                {
+                  SVN_ERR_MALFUNCTION();
+                }
+
+              /* Skip on to the next iteration of this loop. */
+              if (APR_STATUS_IS_EAGAIN(status))
+                {
+                  return svn_error_wrap_apr(status, NULL);
+                }
+              continue;
+            }
+
+          skip = (apr_size_t)(len - (ctx->read_size - ctx->skip_size));
+          data += skip;
+          len -= skip;
+          ctx->skip_size = 0;
+        }
+
       /* Ensure that the parser's PAUSED state is correct before we test
          the flag.  */
       PBTEST_SET_PAUSED(ctx);
@@ -1783,8 +1845,7 @@ svn_ra_serf__handle_xml_parser(serf_requ
         {
           SVN_ERR_ASSERT(ctx->xmlp != NULL);
 
-          XML_ParserFree(ctx->xmlp);
-          ctx->xmlp = NULL;
+          apr_pool_cleanup_run(ctx->pool, &ctx->xmlp, xml_parser_cleanup);
           add_done_item(ctx);
           return svn_error_trace(err);
         }
@@ -1818,8 +1879,7 @@ svn_ra_serf__handle_xml_parser(serf_requ
               /* Ignore the return status. We just don't care.  */
               (void) XML_Parse(ctx->xmlp, NULL, 0, 1);
 
-              XML_ParserFree(ctx->xmlp);
-              ctx->xmlp = NULL;
+              apr_pool_cleanup_run(ctx->pool, &ctx->xmlp, xml_parser_cleanup);
               add_done_item(ctx);
             }
 
@@ -2013,17 +2073,27 @@ handle_response(serf_request_t *request,
 
   ctx->conn->last_status_code = sl.code;
 
-  if (sl.code == 409 || sl.code >= 500)
+  if (sl.code == 405 || sl.code == 409 || sl.code >= 500)
     {
-      /* 409 Conflict: can indicate a hook error.
+      /* 405 Method Not allowed.
+         409 Conflict: can indicate a hook error.
          5xx (Internal) Server error. */
       SVN_ERR(svn_ra_serf__handle_server_error(request, response, pool));
 
       if (!ctx->session->pending_error)
         {
+          apr_status_t apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
+
+          /* 405 == Method Not Allowed (Occurs when trying to lock a working
+             copy path which no longer exists at HEAD in the repository. */
+
+          if (sl.code == 405 && !strcmp(ctx->method, "LOCK"))
+            apr_err = SVN_ERR_FS_OUT_OF_DATE;
+
           return
-              svn_error_createf(APR_EGENERAL, NULL,
-              _("Unspecified error message: %d %s"), sl.code, sl.reason);
+              svn_error_createf(apr_err, NULL,
+                                _("%s request on '%s' failed: %d %s"),
+                                ctx->method, ctx->path, sl.code, sl.reason);
         }
 
       return SVN_NO_ERROR; /* Error is set in caller */
@@ -2249,7 +2319,7 @@ svn_ra_serf__discover_vcc(const char **v
           if ((err->apr_err != SVN_ERR_FS_NOT_FOUND) &&
               (err->apr_err != SVN_ERR_RA_DAV_FORBIDDEN))
             {
-              return err;  /* found a _real_ error */
+              return svn_error_trace(err);  /* found a _real_ error */
             }
           else
             {

Modified: subversion/branches/issue-3975/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/info.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/info.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/info.c Tue Aug 16 15:12:14 2011
@@ -63,6 +63,11 @@ svn_wc_info_dup(const svn_wc_info_t *inf
     new_info->copyfrom_url = apr_pstrdup(pool, info->copyfrom_url);
   if (info->wcroot_abspath)
     new_info->wcroot_abspath = apr_pstrdup(pool, info->wcroot_abspath);
+  if (info->moved_from_abspath)
+    new_info->moved_from_abspath = apr_pstrdup(pool, info->moved_from_abspath);
+  if (info->moved_to_abspath)
+    new_info->moved_to_abspath = apr_pstrdup(pool, info->moved_to_abspath);
+
   return new_info;
 }
 
@@ -146,6 +151,12 @@ build_info_for_node(svn_wc__info2_t **in
 
               wc_info->copyfrom_rev = original_revision;
             }
+
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL,
+                                           &wc_info->moved_from_abspath, NULL,
+                                           db, local_abspath,
+                                           result_pool, scratch_pool));
         }
       else if (op_root)
         {
@@ -199,7 +210,7 @@ build_info_for_node(svn_wc__info2_t **in
                                             result_pool, scratch_pool));
 
       /* And now fetch the url and revision of what will be deleted */
-      SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL,
+      SVN_ERR(svn_wc__db_scan_deletion(NULL, &wc_info->moved_to_abspath,
                                        &work_del_abspath, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));

Modified: subversion/branches/issue-3975/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/merge.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/merge.c Tue Aug 16 15:12:14 2011
@@ -814,7 +814,7 @@ setup_text_conflict_desc(const char *lef
   svn_wc_conflict_description2_t *cdesc;
 
   cdesc = svn_wc_conflict_description_create_text2(target_abspath, pool);
-  cdesc->is_binary = FALSE;
+  cdesc->is_binary = is_binary;
   cdesc->mime_type = (mimeprop && mimeprop->value)
                      ? mimeprop->value->data : NULL,
   cdesc->base_abspath = left_abspath;

Modified: subversion/branches/issue-3975/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/node.c?rev=1158318&r1=1158317&r2=1158318&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/node.c Tue Aug 16 15:12:14 2011
@@ -1647,7 +1647,6 @@ svn_wc__check_for_obstructions(svn_wc_no
                                svn_node_kind_t *kind,
                                svn_boolean_t *added,
                                svn_boolean_t *deleted,
-                               svn_boolean_t *conflicted,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,
@@ -1656,7 +1655,6 @@ svn_wc__check_for_obstructions(svn_wc_no
   svn_wc__db_status_t status;
   svn_wc__db_kind_t db_kind;
   svn_node_kind_t disk_kind;
-  svn_boolean_t conflicted_p;
   svn_error_t *err;
 
   *obstruction_state = svn_wc_notify_state_inapplicable;
@@ -1666,14 +1664,12 @@ svn_wc__check_for_obstructions(svn_wc_no
     *added = FALSE;
   if (deleted)
     *deleted = FALSE;
-  if (conflicted)
-    *conflicted = FALSE;
 
   SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
   err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, &conflicted_p, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                              NULL, NULL, NULL, NULL, NULL,
                              wc_ctx->db, local_abspath,
                              scratch_pool, scratch_pool);
@@ -1779,17 +1775,6 @@ svn_wc__check_for_obstructions(svn_wc_no
         SVN_ERR_MALFUNCTION();
     }
 
-  if (conflicted_p && (conflicted != NULL))
-    {
-      svn_boolean_t text_c, prop_c, tree_c;
-
-      SVN_ERR(svn_wc__internal_conflicted_p(&text_c, &prop_c, &tree_c,
-                                            wc_ctx->db, local_abspath,
-                                            scratch_pool));
-
-      *conflicted = (text_c || prop_c || tree_c);
-    }
-
   return SVN_NO_ERROR;
 }