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

svn commit: r1157811 [1/3] - in /subversion/branches/fs-py: ./ subversion/bindings/ctypes-python/csvn/ subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bi...

Author: hwright
Date: Mon Aug 15 12:32:42 2011
New Revision: 1157811

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

Added:
    subversion/branches/fs-py/subversion/bindings/javahl/src/org/apache/subversion/javahl/JNIError.java
      - copied unchanged from r1157792, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/JNIError.java
Removed:
    subversion/branches/fs-py/subversion/bindings/javahl/src/org/tigris/subversion/javahl/JNIError.java
Modified:
    subversion/branches/fs-py/   (props changed)
    subversion/branches/fs-py/configure.ac
    subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/repos.py
    subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/wc.py
    subversion/branches/fs-py/subversion/bindings/ctypes-python/test/localrepos.py
    subversion/branches/fs-py/subversion/bindings/ctypes-python/test/remoterepos.py
    subversion/branches/fs-py/subversion/bindings/ctypes-python/test/svntypes.py
    subversion/branches/fs-py/subversion/bindings/ctypes-python/test/wc.py
    subversion/branches/fs-py/subversion/bindings/javahl/native/ClientContext.cpp
    subversion/branches/fs-py/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
    subversion/branches/fs-py/subversion/bindings/swig/ruby/test/util.rb
    subversion/branches/fs-py/subversion/include/private/svn_client_private.h
    subversion/branches/fs-py/subversion/include/private/svn_wc_private.h
    subversion/branches/fs-py/subversion/include/svn_client.h
    subversion/branches/fs-py/subversion/include/svn_wc.h
    subversion/branches/fs-py/subversion/libsvn_client/blame.c
    subversion/branches/fs-py/subversion/libsvn_client/commit.c
    subversion/branches/fs-py/subversion/libsvn_client/diff.c
    subversion/branches/fs-py/subversion/libsvn_client/merge.c
    subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.c
    subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.h
    subversion/branches/fs-py/subversion/libsvn_client/patch.c
    subversion/branches/fs-py/subversion/libsvn_client/status.c
    subversion/branches/fs-py/subversion/libsvn_fs_fs/tree.c
    subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c
    subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c
    subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c
    subversion/branches/fs-py/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/fs-py/subversion/libsvn_ra_serf/serf.c
    subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c
    subversion/branches/fs-py/subversion/libsvn_ra_serf/util.c
    subversion/branches/fs-py/subversion/libsvn_wc/info.c
    subversion/branches/fs-py/subversion/libsvn_wc/merge.c
    subversion/branches/fs-py/subversion/libsvn_wc/node.c
    subversion/branches/fs-py/subversion/libsvn_wc/status.c
    subversion/branches/fs-py/subversion/libsvn_wc/update_editor.c
    subversion/branches/fs-py/subversion/libsvn_wc/upgrade.c
    subversion/branches/fs-py/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/fs-py/subversion/libsvn_wc/wc_db.c
    subversion/branches/fs-py/subversion/libsvn_wc/wc_db.h
    subversion/branches/fs-py/subversion/svn/info-cmd.c
    subversion/branches/fs-py/subversion/svn/schema/info.rnc
    subversion/branches/fs-py/subversion/svn/status.c
    subversion/branches/fs-py/subversion/tests/cmdline/changelist_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/copy_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/import_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/lock_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/merge_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/fs-py/subversion/tests/cmdline/patch_tests.py
    subversion/branches/fs-py/tools/dev/benchmarks/suite1/benchmark.py
    subversion/branches/fs-py/tools/dev/benchmarks/suite1/run
    subversion/branches/fs-py/tools/dev/unix-build/Makefile.svn
    subversion/branches/fs-py/tools/dist/release.py
    subversion/branches/fs-py/tools/dist/templates/rc-news.ezt

Propchange: subversion/branches/fs-py/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug 15 12:32:42 2011
@@ -54,3 +54,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
+/subversion/trunk:1154223-1157792

Modified: subversion/branches/fs-py/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/configure.ac?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/configure.ac (original)
+++ subversion/branches/fs-py/configure.ac Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/ctypes-python/csvn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/repos.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/repos.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/repos.py Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/ctypes-python/csvn/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/wc.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/wc.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/csvn/wc.py Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/ctypes-python/test/localrepos.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/test/localrepos.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/test/localrepos.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/test/localrepos.py Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/ctypes-python/test/remoterepos.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/test/remoterepos.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/test/remoterepos.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/test/remoterepos.py Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/ctypes-python/test/svntypes.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/test/svntypes.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/test/svntypes.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/test/svntypes.py Mon Aug 15 12:32:42 2011
@@ -21,8 +21,24 @@ import setup_path
 import unittest
 from csvn.core import *
 import csvn.types as _types
+from csvn.types import SvnDate, Hash, Array, APRFile, Stream, SvnStringPtr
 
-class TypesTestCase(unittest.TestCase):
+class SvnDateTestCase(unittest.TestCase):
+
+    def test_as_apr_time_t(self):
+        d1 = SvnDate('1999-12-31T23:59:59.000000Z')
+        d2 = SvnDate('2000-01-01T00:00:00.000000Z')
+        t1 = d1.as_apr_time_t().value
+        t2 = d2.as_apr_time_t().value
+        self.assertEqual(t1 + 1000000, t2)
+
+    def test_as_human_string(self):
+        d1 = SvnDate('1999-12-31T23:59:59.000000Z')
+        s1 = d1.as_human_string()
+        self.assertEqual(s1[:27], '1999-12-31 23:59:59 +0000 (')
+
+
+class HashTestCase(unittest.TestCase):
 
     def test_hash(self):
         self.pydict = {"bruce":"batman", "clark":"superman",
@@ -35,6 +51,34 @@ class TypesTestCase(unittest.TestCase):
         self.assertNotEqual(self.svnhash["clark"].value,
             self.pydict["bruce"])
 
+    def test_insert_delete(self):
+        h = Hash(c_char_p)
+        h['foo'] = 'f'
+        h['bar'] = 'b'
+        self.assertEqual(len(h), 2)
+        self.assertEqual(h['foo'].value, 'f')
+        self.assertEqual(h['bar'].value, 'b')
+        h['bar'] = 'b'
+        self.assertEqual(len(h), 2)
+        del h['foo']
+        self.assertEqual(len(h), 1)
+        self.assertEqual(h['bar'].value, 'b')
+
+    def test_iter(self):
+        h = Hash(c_char_p, { 'foo': 'f', 'bar': 'b' })
+        keys = sorted(h.keys())
+        self.assertEqual(keys, ['bar', 'foo'])
+        vals = []
+        for k in h:
+            vals += [ h[k].value ]
+        self.assertEqual(sorted(vals), ['b', 'f'])
+        vals = []
+        for k,v in h.items():
+            vals += [ v.value ]
+        self.assertEqual(sorted(vals), ['b', 'f'])
+
+class ArrayTestCase(unittest.TestCase):
+
     def test_array(self):
         self.pyarray = ["vini", "vidi", "vici"]
         self.svnarray = _types.Array(c_char_p, self.pyarray)
@@ -43,7 +87,11 @@ class TypesTestCase(unittest.TestCase):
         self.assertEqual(self.svnarray[1], "vidi")
 
 def suite():
-    return unittest.makeSuite(TypesTestCase, 'test')
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(SvnDateTestCase, 'test'))
+    suite.addTest(unittest.makeSuite(HashTestCase, 'test'))
+    suite.addTest(unittest.makeSuite(ArrayTestCase, 'test'))
+    return suite
 
 if __name__ == '__main__':
     runner = unittest.TextTestRunner()

Modified: subversion/branches/fs-py/subversion/bindings/ctypes-python/test/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/ctypes-python/test/wc.py?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/ctypes-python/test/wc.py (original)
+++ subversion/branches/fs-py/subversion/bindings/ctypes-python/test/wc.py Mon Aug 15 12:32:42 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/fs-py/subversion/bindings/javahl/native/ClientContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/native/ClientContext.cpp?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/javahl/native/ClientContext.cpp (original)
+++ subversion/branches/fs-py/subversion/bindings/javahl/native/ClientContext.cpp Mon Aug 15 12:32:42 2011
@@ -158,7 +158,7 @@ ClientContext::getContext(CommitMessage 
     if (!ctx->config)
       {
         const char *configDir = m_configDir.c_str();
-        if (m_configDir.length() == 0)
+        if (m_configDir.empty())
             configDir = NULL;
         SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir,
                                           m_pool->getPool()),
@@ -254,10 +254,17 @@ ClientContext::getContext(CommitMessage 
      * auth_baton's run-time parameter hash.  ### Same with --no-auth-cache? */
     if (!m_userName.empty())
         svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME,
-                               m_userName.c_str());
+                               apr_pstrdup(in_pool.getPool(),
+                                           m_userName.c_str()));
     if (!m_passWord.empty())
         svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD,
-                               m_passWord.c_str());
+                               apr_pstrdup(in_pool.getPool(),
+                                           m_passWord.c_str()));
+    /* Store where to retrieve authentication data? */
+    if (!m_configDir.empty())
+        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR,
+                               apr_pstrdup(in_pool.getPool(),
+                                           m_configDir.c_str()));
 
     ctx->auth_baton = ab;
     ctx->log_msg_baton3 = message;

Modified: subversion/branches/fs-py/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/fs-py/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Mon Aug 15 12:32:42 2011
@@ -130,6 +130,35 @@ public class BasicTests extends SVNTests
     }
 
     /**
+     * Test the JNIError class functionality
+     * @throws Throwable
+     */
+    public void testJNIError() throws Throwable
+    {
+        // build the test setup.
+        OneTest thisTest = new OneTest();
+
+        // Create a client, dispose it, then try to use it later
+        ISVNClient tempclient = new SVNClient();
+        tempclient.dispose();
+
+        // create Y and Y/Z directories in the repository
+        addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y", NodeKind.none,
+                              CommitItemStateFlags.Add);
+        Set<String> urls = new HashSet<String>(1);
+        urls.add(thisTest.getUrl() + "/Y");
+        try 
+        {
+            tempclient.mkdir(urls, false, null, new ConstMsg("log_msg"), null);
+        } 
+        catch(JNIError e)
+        {
+	        return; // Test passes!
+        }
+        fail("A JNIError should have been thrown here.");
+    }
+
+    /**
      * Tests Mergeinfo and RevisionRange classes.
      * @since 1.5
      */

Modified: subversion/branches/fs-py/subversion/bindings/swig/ruby/test/util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/bindings/swig/ruby/test/util.rb?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/bindings/swig/ruby/test/util.rb (original)
+++ subversion/branches/fs-py/subversion/bindings/swig/ruby/test/util.rb Mon Aug 15 12:32:42 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/fs-py/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/private/svn_client_private.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/fs-py/subversion/include/private/svn_client_private.h Mon Aug 15 12:32:42 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/fs-py/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/private/svn_wc_private.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/fs-py/subversion/include/private/svn_wc_private.h Mon Aug 15 12:32:42 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/fs-py/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/svn_client.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/svn_client.h (original)
+++ subversion/branches/fs-py/subversion/include/svn_client.h Mon Aug 15 12:32:42 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/fs-py/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/include/svn_wc.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/include/svn_wc.h (original)
+++ subversion/branches/fs-py/subversion/include/svn_wc.h Mon Aug 15 12:32:42 2011
@@ -1755,7 +1755,7 @@ typedef struct svn_wc_conflict_descripti
   /** Info on the "merge-right source" or "their" version of incoming change. */
   const svn_wc_conflict_version_t *src_right_version;
 
-  /* Remember to adjust svn_wc__conflict_description_dup()
+  /* Remember to adjust svn_wc__conflict_description2_dup()
    * if you add new fields to this struct. */
 } svn_wc_conflict_description2_t;
 
@@ -1849,8 +1849,6 @@ typedef struct svn_wc_conflict_descripti
    * @since New in 1.6. */
   svn_wc_conflict_version_t *src_right_version;
 
-  /* Remember to adjust svn_wc__conflict_description_dup()
-   * if you add new fields to this struct. */
 } svn_wc_conflict_description_t;
 
 /**
@@ -3068,6 +3066,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 +3617,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/fs-py/subversion/libsvn_client/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/blame.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/blame.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/blame.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/commit.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/commit.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/diff.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/diff.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/diff.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/merge.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/merge.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/mergeinfo.h Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/patch.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/patch.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_client/status.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_client/status.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_client/status.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_fs/tree.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_fs/tree.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_ra_neon/fetch.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_neon/fetch.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/locks.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/merge.c Mon Aug 15 12:32:42 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/fs-py/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/ra_serf.h?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/ra_serf.h Mon Aug 15 12:32:42 2011
@@ -179,6 +179,9 @@ struct svn_ra_serf__session_t {
   /* Connection timeout value */
   long timeout;
 
+  /* HTTPv1 flags */
+  svn_tristate_t supports_deadprop_count;
+
   /*** HTTP v2 protocol stuff. ***
    *
    * We assume that if mod_dav_svn sends one of the special v2 OPTIONs
@@ -626,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/fs-py/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/serf.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/serf.c Mon Aug 15 12:32:42 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"
@@ -386,6 +387,8 @@ svn_ra_serf__open(svn_ra_session_t *sess
   serf_sess->session_url_str = apr_pstrdup(serf_sess->pool, repos_URL);
   serf_sess->using_ssl = (svn_cstring_casecmp(url.scheme, "https") == 0);
 
+  serf_sess->supports_deadprop_count = svn_tristate_unknown;
+
   serf_sess->capabilities = apr_hash_make(serf_sess->pool);
 
   SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
@@ -660,6 +663,8 @@ struct dirent_walker_baton_t {
   /* Update the fields in this entry.  */
   svn_dirent_t *entry;
 
+  svn_tristate_t *supports_deadprop_count;
+
   /* If allocations are necessary, then use this pool.  */
   apr_pool_t *result_pool;
 };
@@ -685,9 +690,16 @@ dirent_walker(void *baton,
     {
       if(strcmp(name, "deadprop-count") == 0)
         {
-          apr_int64_t deadprop_count;
-          SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
-          dwb->entry->has_props = deadprop_count > 0;
+          if (*val->data)
+            {
+              apr_int64_t deadprop_count;
+              SVN_ERR(svn_cstring_atoi64(&deadprop_count, val->data));
+              dwb->entry->has_props = deadprop_count > 0;
+              if (dwb->supports_deadprop_count)
+                *dwb->supports_deadprop_count = svn_tristate_true;
+            }
+          else if (dwb->supports_deadprop_count)
+            *dwb->supports_deadprop_count = svn_tristate_false;
         }
     }
   else if (strcmp(ns, "DAV:") == 0)
@@ -734,6 +746,8 @@ struct path_dirent_visitor_t {
   apr_hash_t *full_paths;
   apr_hash_t *base_paths;
   const char *orig_path;
+  svn_tristate_t supports_deadprop_count;
+  apr_pool_t *result_pool;
 };
 
 static svn_error_t *
@@ -771,57 +785,74 @@ path_dirent_walker(void *baton,
     }
 
   dwb.entry = entry;
-  dwb.result_pool = pool;  /* ### fix this!  */
+  dwb.supports_deadprop_count = &dirents->supports_deadprop_count;
+  dwb.result_pool = dirents->result_pool;
   return svn_error_trace(dirent_walker(&dwb, ns, name, val, pool));
 }
 
 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);
@@ -845,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)
@@ -862,11 +895,33 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
     }
 
   dwb.entry = apr_pcalloc(pool, sizeof(*dwb.entry));
-  dwb.result_pool = pool;  /* ### fix this  */
+  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;
@@ -943,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. */
@@ -956,11 +1011,38 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       dirent_walk.full_paths = apr_hash_make(pool);
       dirent_walk.base_paths = apr_hash_make(pool);
       dirent_walk.orig_path = svn_urlpath__canonicalize(path, pool);
+      dirent_walk.supports_deadprop_count = svn_tristate_unknown;
+      dirent_walk.result_pool = pool;
 
       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;
     }
 
   /* If we're asked for the directory properties, fetch them too. */
@@ -1028,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/fs-py/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c?rev=1157811&r1=1157810&r2=1157811&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_ra_serf/update.c Mon Aug 15 12:32:42 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;