More efficient implementation of find_children().
authorJelmer Vernooij <jelmer@samba.org>
Mon, 25 Dec 2006 00:21:58 +0000 (01:21 +0100)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 25 Dec 2006 00:21:58 +0000 (01:21 +0100)
Make sure calls to get_dir2() never start with a slash, as that
causes strange errors over ra_dav.

fileids.py
logwalker.py
tests/test_logwalker.py
transport.py

index abc99242c558b4aa67823127201c03be0511fbb9..d79e9626d1ce96bd9f8e09355c8c0c47b95c6682 100644 (file)
@@ -193,7 +193,9 @@ class SimpleFileIdMap(FileIdMap):
                         warn('incomplete data for %r' % p)
                     else:
                         for c in find_children(data[1], data[2]):
-                            map[c.replace(data[1], p, 1)] = generate_file_id(revid, c), revid
+                            path = c.replace(data[1], p, 1)
+                            map[path] = generate_file_id(revid, c), revid
+                            mutter('added mapping %r -> %r' % (path, map[path]))
 
             elif data[0] == 'M':
                 if p == "":
index a7abe14bbb6e67394852f8f44bda327112ced3c8..530b03d39a0cdc37a8c79619ac1b0a84c8f3daef 100644 (file)
@@ -302,7 +302,8 @@ class LogWalker(object):
 
         try:
             (dirents, _, _) = self.transport.get_dir2(
-                "/" + path.encode('utf8'), revnum, 0)
+                path.lstrip("/").encode('utf8'), revnum, 
+                svn.core.SVN_DIRENT_KIND)
         except SubversionException, (_, num):
             if num == svn.core.SVN_ERR_FS_NOT_DIRECTORY:
                 return
@@ -310,8 +311,9 @@ class LogWalker(object):
 
         for p in dirents:
             yield os.path.join(path, p)
-            for c in self.find_children(os.path.join(path, p), revnum):
-                yield c
+            if dirents[p].kind == svn.core.svn_node_dir:
+                for c in self.find_children(os.path.join(path, p), revnum):
+                    yield c
 
     def get_previous(self, path, revnum):
         """Return path,revnum pair specified pair was derived from.
index a8252d439d6a494a02f29b3072e21d36b1f57f35..07ed09dfc0795c445ebc055272948b0ac42da001 100644 (file)
@@ -381,3 +381,53 @@ class TestLogWalker(TestCaseWithSubversionRepository):
         self.assertEqual("", info[0])
         self.assertEqual("My Message", info[1])
 
+    def test_find_children_empty(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk': None})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(TrunkBranchingScheme(), 
+                                     transport=SvnRaTransport(repos_url))
+
+        self.assertEqual([], list(walker.find_children("trunk", 1)))
+
+    def test_find_children_one(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk/data': 'foo'})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(TrunkBranchingScheme(), 
+                                     transport=SvnRaTransport(repos_url))
+
+        self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
+
+    def test_find_children_nested(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk/data/bla': 'foo', 'dc/trunk/file': 'bla'})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(TrunkBranchingScheme(), 
+                                     transport=SvnRaTransport(repos_url))
+
+        self.assertEqual(['trunk/data', 'trunk/data/bla', 'trunk/file'], 
+                list(walker.find_children("trunk", 1)))
+
+    def test_find_children_later(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk/data/bla': 'foo'})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+        self.build_tree({'dc/trunk/file': 'bla'})
+        self.client_add("dc/trunk/file")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(TrunkBranchingScheme(), 
+                                     transport=SvnRaTransport(repos_url))
+
+        self.assertEqual(['trunk/data', 'trunk/data/bla'], 
+                list(walker.find_children("trunk", 1)))
+        self.assertEqual(['trunk/data', 'trunk/data/bla', 'trunk/file'], 
+                list(walker.find_children("trunk", 2)))
index 72dbd0fe368cbe193069fa9c9e68baa0de76461d..fa1bb6a8bf16f47a7056198edd1883aeaab334a5 100644 (file)
@@ -173,8 +173,11 @@ class SvnRaTransport(Transport):
             self._ra = svn.client.open_ra_session(self.svn_url.encode('utf8'), 
                     self._client, self.pool)
     @need_lock
-    def get_dir2(self, *args, **kwargs):
-        return svn.ra.get_dir2(self._ra, *args, **kwargs)
+    def get_dir2(self, path, *args, **kwargs):
+        # ra_dav backends fail with strange errors if the path starts with a 
+        # slash while other backends don't.
+        assert len(path) == 0 or path[0] != "/"
+        return svn.ra.get_dir2(self._ra, path, *args, **kwargs)
 
     def list_dir(self, relpath):
         if relpath == ".":