Rev 263: Merge upstream fixes. in http://people.samba.org/bzr/jelmer/bzr-svn/bzr.dev

Jelmer Vernooij jelmer at samba.org
Fri Dec 29 16:41:36 GMT 2006


------------------------------------------------------------
revno: 263
revision-id: jelmer at samba.org-20061229164052-l6hr3ie3je9ae1zc
parent: jelmer at samba.org-20061228022606-pl02194x4z5n0zx3
parent: jelmer at samba.org-20061229051751-j93sydbdguw15i25
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: norootid
timestamp: Fri 2006-12-29 17:40:52 +0100
message:
  Merge upstream fixes.
modified:
  TODO                           todo-20060729211917-2kpobww0zyvvo0j2-1
  fetch.py                       fetch.py-20060625004942-x2lfaib8ra707a8p-1
  fileids.py                     fileids.py-20060714013623-u5iiyqqnko11grcf-1
  logwalker.py                   logwalker.py-20060621215743-c13fhfnyzh1xzwh2-1
  repository.py                  repository.py-20060306123302-1f8c5069b3fe0265
  tests/test_fileids.py          test_fileids.py-20060622131341-19gyrlgqy8yl2od5-1
  tests/test_logwalker.py        test_logwalker.py-20060622141944-pkocc3rj8g62ukbi-1
  tests/test_repos.py            test_repos.py-20060508151940-ddc49a59257ca712
  tests/test_scheme.py           test_scheme.py-20060621221855-va2xabhlxpmc9llx-1
    ------------------------------------------------------------
    revno: 236.1.11.1.78
    merged: jelmer at samba.org-20061229051751-j93sydbdguw15i25
    parent: jelmer at samba.org-20061229025004-qped8lkugogltskd
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Fri 2006-12-29 06:17:51 +0100
    message:
      Simplify return values of _apply_changes() functions. They now no longer 
      return a revision id, as that is always the same.
    ------------------------------------------------------------
    revno: 236.1.11.1.77
    merged: jelmer at samba.org-20061229025004-qped8lkugogltskd
    parent: jelmer at samba.org-20061229020414-tqbmu19p0fup7sdg
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Fri 2006-12-29 03:50:04 +0100
    message:
      Remove unused code.
    ------------------------------------------------------------
    revno: 236.1.11.1.76
    merged: jelmer at samba.org-20061229020414-tqbmu19p0fup7sdg
    parent: jelmer at samba.org-20061229005920-5fqkse7ru9l5we5l
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Fri 2006-12-29 03:04:14 +0100
    message:
      Only determine file ids of changed files.
    ------------------------------------------------------------
    revno: 236.1.11.1.75
    merged: jelmer at samba.org-20061229005920-5fqkse7ru9l5we5l
    parent: jelmer at samba.org-20061228183753-j6sxwwoaf81p6a50
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Fri 2006-12-29 01:59:20 +0100
    message:
      Simplify path_to_file_id function a bit.
    ------------------------------------------------------------
    revno: 236.1.11.1.74
    merged: jelmer at samba.org-20061228183753-j6sxwwoaf81p6a50
    parent: jelmer at samba.org-20061228044650-1hvjud25we4tb4tr
    parent: jelmer at samba.org-20061228170228-qdhgqj1akrc7b45s
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Thu 2006-12-28 19:37:53 +0100
    message:
      Merge commits done on train.
        ------------------------------------------------------------
        revno: 236.1.11.1.73.1.3
        merged: jelmer at samba.org-20061228170228-qdhgqj1akrc7b45s
        parent: jelmer at samba.org-20061228170154-n70amzdyj9ejqx16
        committer: Jelmer Vernooij <jelmer at samba.org>
        branch nick: main
        timestamp: Thu 2006-12-28 18:02:28 +0100
        message:
          Remove unused local map obtain code.
        ------------------------------------------------------------
        revno: 236.1.11.1.73.1.2
        merged: jelmer at samba.org-20061228170154-n70amzdyj9ejqx16
        parent: jelmer at samba.org-20061228165251-rr0jtciqj4f1xwya
        committer: Jelmer Vernooij <jelmer at samba.org>
        branch nick: main
        timestamp: Thu 2006-12-28 18:01:54 +0100
        message:
          Split out tests a bit more.
        ------------------------------------------------------------
        revno: 236.1.11.1.73.1.1
        merged: jelmer at samba.org-20061228165251-rr0jtciqj4f1xwya
        parent: jelmer at samba.org-20061228044650-1hvjud25we4tb4tr
        committer: Jelmer Vernooij <jelmer at samba.org>
        branch nick: main
        timestamp: Thu 2006-12-28 17:52:51 +0100
        message:
          Use old inventory to obtain old file ids, saving a rather expensive 
          path_to_file_id() call.
    ------------------------------------------------------------
    revno: 236.1.11.1.73
    merged: jelmer at samba.org-20061228044650-1hvjud25we4tb4tr
    parent: jelmer at samba.org-20061228034106-zflnscoxd7l2x6wt
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Thu 2006-12-28 05:46:50 +0100
    message:
      Remove if statement again. This fixes importing several repositories. 
    ------------------------------------------------------------
    revno: 236.1.11.1.72
    merged: jelmer at samba.org-20061228034106-zflnscoxd7l2x6wt
    parent: jelmer at samba.org-20061227180657-d11m7tlyad4d4bpa
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: main
    timestamp: Thu 2006-12-28 04:41:06 +0100
    message:
      Add tests.
=== modified file 'TODO'
--- a/TODO	2006-12-23 20:08:29 +0000
+++ b/TODO	2006-12-29 16:40:52 +0000
@@ -1,1 +1,2 @@
 - get rid of use of `svn ls' in logwalker
+- more efficient implementation for applying txdeltas to weaves. perhaps convert svn deltas to bzr deltas?

=== modified file 'fetch.py'
--- a/fetch.py	2006-12-28 02:26:06 +0000
+++ b/fetch.py	2006-12-29 16:40:52 +0000
@@ -45,14 +45,14 @@
     def __init__(self, source, target, branch_path, revnum, prev_inventory, 
                  revid, svn_revprops, id_map, parent_branch, parent_id_map):
         self.branch_path = branch_path
-        self.inventory = prev_inventory
+        self.old_inventory = prev_inventory
+        self.inventory = copy(prev_inventory)
         assert self.inventory.root is None or revnum > 0
         self.revid = revid
         self.revnum = revnum
         mutter('idmap for %r %r' % (revid, id_map))
         self.id_map = id_map
         self.parent_branch = parent_branch
-        self.parent_id_map = parent_id_map
         self.source = source
         self.target = target
         self.transact = target.get_transaction()
@@ -107,28 +107,29 @@
         del self.inventory[self.inventory.path2id(path)]
 
     def close_directory(self, id):
-        revid = self.revid
-
-        if id != self.id_map[""][0]:
-            self.inventory[id].revision = revid
-
-            file_weave = self.weave_store.get_weave_or_empty(id, self.transact)
-            if not file_weave.has_version(revid):
-                file_weave.add_lines(revid, self.dir_baserev[id], [])
+        self.inventory[id].revision = self.revid
+
+        file_weave = self.weave_store.get_weave_or_empty(id, self.transact)
+        if not file_weave.has_version(self.revid):
+            file_weave.add_lines(self.revid, self.dir_baserev[id], [])
 
     def add_directory(self, path, parent_baton, copyfrom_path, copyfrom_revnum, pool):
-        file_id, revision_id = self.id_map[path]
+        file_id = self.id_map[path]
 
         self.dir_baserev[file_id] = []
         ie = self.inventory.add_path(path, 'directory', file_id)
-        ie.revision = revision_id
+        ie.revision = self.revid
 
         return file_id
 
     def open_directory(self, path, parent_baton, base_revnum, pool):
-        file_id, revision_id = self.id_map[path]
         assert base_revnum >= 0
-        base_file_id, base_revid = self.source.path_to_file_id(base_revnum, os.path.join(self.parent_branch, path))
+        base_file_id = self.old_inventory.path2id(path)
+        base_revid = self.old_inventory[base_file_id].revision
+        if self.id_map.has_key(path):
+            file_id = self.id_map[path]
+        else:
+            file_id = base_file_id
         if file_id == base_file_id:
             self.dir_baserev[file_id] = [base_revid]
             ie = self.inventory[file_id]
@@ -143,7 +144,7 @@
             self.inventory._byid[file_id] = ie
             ie.file_id = file_id
             self.dir_baserev[file_id] = []
-        ie.revision = revision_id
+        ie.revision = self.revid
         return file_id
 
     def change_dir_prop(self, id, name, value, pool):
@@ -200,8 +201,12 @@
         return path
 
     def open_file(self, path, parent_id, base_revnum, pool):
-        base_file_id, base_revid = self.source.path_to_file_id(base_revnum, os.path.join(self.parent_branch, path))
-        file_id, revid = self.id_map[path]
+        base_file_id = self.old_inventory.path2id(path)
+        base_revid = self.old_inventory[base_file_id].revision
+        if self.id_map.has_key(path):
+            file_id = self.id_map[path]
+        else:
+            file_id = base_file_id
         self.is_executable = None
         self.is_symlink = (self.inventory[base_file_id].kind == 'symlink')
         file_weave = self.weave_store.get_weave_or_empty(base_file_id, self.transact)
@@ -226,10 +231,13 @@
         actual_checksum = md5_strings(lines)
         assert checksum is None or checksum == actual_checksum
 
-        file_id, revision_id = self.id_map[path]
+        if self.id_map.has_key(path):
+            file_id = self.id_map[path]
+        else:
+            file_id = self.old_inventory.path2id(path)
         file_weave = self.weave_store.get_weave_or_empty(file_id, self.transact)
-        if not file_weave.has_version(revision_id):
-            file_weave.add_lines(revision_id, self.file_parents, lines)
+        if not file_weave.has_version(self.revid):
+            file_weave.add_lines(self.revid, self.file_parents, lines)
 
         if file_id in self.inventory:
             ie = self.inventory[file_id]
@@ -237,7 +245,7 @@
             ie = self.inventory.add_path(path, 'symlink', file_id)
         else:
             ie = self.inventory.add_path(path, 'file', file_id)
-        ie.revision = revision_id
+        ie.revision = self.revid
 
         if self.is_symlink:
             ie.symlink_target = lines[0][len("link "):]
@@ -333,28 +341,19 @@
                 parent_branch = None
 
             if parent_revid is None:
-                # if there is no parent id, that means this is the 
-                # first revision on this branch
-                id_map = self.source.get_fileid_map(revnum, branch)
-                parent_id_map = None
                 parent_inv = Inventory(root_id=None)
             elif prev_revid != parent_revid:
-                parent_id_map = self.source.get_fileid_map(parent_revnum, parent_branch)
-                id_map = self.source.get_fileid_map(revnum, branch)
                 parent_inv = self.target.get_inventory(parent_revid)
             else:
-                parent_id_map = copy(id_map)
-                self.source.transform_fileid_map(self.source.uuid, 
-                                        revnum, branch, 
-                                        changes, id_map, 
-                                        # FIXME: use information received in editor
-                                        self.source.revision_fileid_renames(revid))
                 parent_inv = prev_inv
 
+            id_map = self.source.transform_fileid_map(self.source.uuid, 
+                                        revnum, branch, changes)
+
             editor = RevisionBuildEditor(self.source, self.target, branch, 
                                          revnum, parent_inv, revid, 
                                      self.source._log.get_revision_info(revnum),
-                                     id_map, parent_branch, parent_id_map)
+                                     id_map, parent_branch)
 
             pool = Pool()
             edit, edit_baton = svn.delta.make_editor(editor, pool)

=== modified file 'fileids.py'
--- a/fileids.py	2006-12-28 02:26:06 +0000
+++ b/fileids.py	2006-12-29 16:40:52 +0000
@@ -109,8 +109,7 @@
 
         return map
 
-    def apply_changes(self, uuid, revnum, branch, global_changes, map, 
-            renames):
+    def apply_changes(self, uuid, revnum, branch, global_changes, renames):
         """Change file id map to incorporate specified changes.
 
         :param uuid: UUID of repository changes happen in
@@ -128,7 +127,7 @@
 
         revid = generate_svn_revision_id(uuid, revnum, branch)
 
-        return self._apply_changes(map, revid, changes, find_children, renames)
+        return self._apply_changes(revid, changes, find_children, renames)
 
     def get_map(self, uuid, revnum, branch, pb=None, renames_cb=None):
         """Make sure the map is up to date until revnum."""
@@ -148,20 +147,18 @@
                 # found the nearest cached map
                 next_parent_revs = [revid]
                 break
-            else:
-                todo.append((revid, paths))
-                continue
+            todo.append((revid, paths))
+   
+        # target revision was present
+        if len(todo) == 0:
+            return map
 
         if len(next_parent_revs) == 0:
             if self._log.scheme.is_branch(""):
                 map = {"": (generate_svn_file_id(uuid, 0, "", ""), NULL_REVISION)}
             else:
                 map = {}
-    
-        # target revision was present
-        if len(todo) == 0:
-            return map
-    
+
         todo.reverse()
 
         i = 0
@@ -178,7 +175,23 @@
                     yield self.repos.scheme.unprefix(p)[1]
 
             parent_revs = next_parent_revs
-            map = self._apply_changes(map, revid, changes, find_children, renames_cb(revid))
+            
+            revmap = self._apply_changes(revid, changes, find_children, renames)
+            for p in changes:
+                if changes[p][0] == 'M':
+                    revmap[p] = map[p][0]
+
+            map.update(dict([(x, (revmap[x], revid)) for x in revmap]))
+            # Mark all parent paths as changed
+            for p in revmap:
+                parts = p.split("/")
+                for j in range(1, len(parts)):
+                    parent = "/".join(parts[0:len(parts)-j])
+                    assert map.has_key(parent), "Parent item %s of %s doesn't exist in map" % (parent, p)
+                    if map[parent][1] == revid:
+                        break
+                    map[parent] = map[parent][0], revid
+                    
             next_parent_revs = [revid]
             i = i + 1
 
@@ -191,45 +204,26 @@
 
 class SimpleFileIdMap(FileIdMap):
     @staticmethod
-    def _apply_changes(map, revid, changes, find_children, renames):
+    def _apply_changes(revid, changes, find_children, renames):
         def new_file_id(path):
             if renames.has_key(path):
                 return renames[path]
             return generate_file_id(revid, path)
+        map = {}
         sorted_paths = changes.keys()
         sorted_paths.sort()
         for p in sorted_paths:
             data = changes[p]
 
-            if data[0] in ('D', 'R'):
-                assert map.has_key(p), "No map entry %s to delete/replace" % p
-                del map[p]
-                # Delete all children of p as well
-                for c in map.keys():
-                    if c.startswith(p+"/"):
-                        del map[c]
-
             if data[0] in ('A', 'R'):
-                map[p] = new_file_id(p), revid
+                map[p] = new_file_id(p)
 
                 if data[1] is not None:
                     mutter('%r:%s copied from %r:%s' % (p, revid, data[1], data[2]))
                     assert find_children is not None, 'incomplete data for %r' % p
                     for c in find_children(data[1], data[2]):
                         path = c.replace(data[1], p+"/", 1).replace("//", "/")
-                        map[path] = new_file_id(c), revid
+                        map[path] = new_file_id(c)
                         mutter('added mapping %r -> %r' % (path, map[path]))
 
-            elif data[0] == 'M':
-                assert map.has_key(p), "Map has no item %s to modify" % p
-                map[p] = map[p][0], revid
-            
-            # Mark all parent paths as changed
-            parts = p.split("/")
-            for i in range(1, len(parts)):
-                parent = "/".join(parts[0:len(parts)-i])
-                assert map.has_key(parent), "Parent item %s of %s doesn't exist in map" % (parent, p)
-                if map[parent][1] == revid:
-                    break
-                map[parent] = map[parent][0], revid
         return map

=== modified file 'logwalker.py'
--- a/logwalker.py	2006-12-28 02:26:06 +0000
+++ b/logwalker.py	2006-12-29 16:40:52 +0000
@@ -264,11 +264,10 @@
             yield os.path.join(path, p)
             # This needs to be != svn.core.svn_node_file because 
             # some ra backends seem to return negative values for .kind.
-            # This if statement is just an optimization to make use of this 
-            # property when possible.
-            if dirents[p].kind != svn.core.svn_node_file:
-                for c in self.find_children(os.path.join(path, p), revnum):
-                    yield c
+            # however, dirents[p].node seems to contain semi-random 
+            # values.
+            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.

=== modified file 'repository.py'
--- a/repository.py	2006-12-28 02:26:06 +0000
+++ b/repository.py	2006-12-29 16:40:52 +0000
@@ -258,25 +258,17 @@
                 self.revision_fileid_renames)
 
     def transform_fileid_map(self, uuid, revnum, branch, changes, map, renames):
-        return self.fileid_map.apply_changes(uuid, revnum, branch, changes, map, renames)
+        return self.fileid_map.apply_changes(uuid, revnum, branch, changes, renames)
 
     def path_to_file_id(self, revnum, path):
         """Generate a bzr file id from a Subversion file name. 
         
-        This implementation DOES NOT track renames.
-
-        Use get_fileid_map() directly instead of calling this function 
-        multiple times if possible.
-
         :param revnum: Revision number.
         :param path: Absolute path.
         :return: Tuple with file id and revision id.
         """
-        assert isinstance(revnum, int)
+        assert isinstance(revnum, int) and revnum >= 0
         assert isinstance(path, basestring)
-        assert revnum >= 0
-
-        path = path.strip("/")
 
         if revnum == 0:
             from fileids import generate_svn_file_id
@@ -284,12 +276,8 @@
 
         (bp, rp) = self.scheme.unprefix(path)
 
-        revid = self.generate_revision_id(revnum, bp)
-
-        map = self.get_fileid_map(revnum, bp)
-
         try:
-            return map[rp]
+            return self.get_fileid_map(revnum, bp)[rp]
         except KeyError:
             raise NoSuchFile(path=rp)
 

=== modified file 'tests/test_fileids.py'
--- a/tests/test_fileids.py	2006-12-23 16:58:12 +0000
+++ b/tests/test_fileids.py	2006-12-29 16:40:52 +0000
@@ -155,13 +155,19 @@
         for r in revids:
             if not renames.has_key(r):
                 renames[r] = {}
-            map = SimpleFileIdMap._apply_changes(map, r, mappings[r], 
-                                                 find_children, renames=renames[r])
+            revmap = SimpleFileIdMap._apply_changes(r, mappings[r], find_children, renames=renames[r])
+            map.update(dict([(x,(revmap[x],r)) for x in revmap]))
         return map
 
     def test_simple(self):
         map = self.apply_mappings({"svn-v%d:1 at uuid-" % MAPPING_VERSION: {"foo": ('A', None, None)}})
-        self.assertEqual({'': ('ROOT', "first-revision"),
+        self.assertEqual({ 'foo': ("svn-v%d:1 at uuid--foo" % MAPPING_VERSION, 
+                                       "svn-v%d:1 at uuid-" % MAPPING_VERSION)
+                         }, map)
+
+    def test_simple_add(self):
+        map = self.apply_mappings({"svn-v%d:1 at uuid-" % MAPPING_VERSION: {"": ('A', None, None), "foo": ('A', None, None)}})
+        self.assertEqual({'': ('TREE_ROOT', "svn-v%d:1 at uuid-" % MAPPING_VERSION), 
                                'foo': ("svn-v%d:1 at uuid--foo" % MAPPING_VERSION, 
                                        "svn-v%d:1 at uuid-" % MAPPING_VERSION)
                          }, map)
@@ -214,3 +220,4 @@
                  }, 
                 renames={("svn-v%d:2 at uuid-" % MAPPING_VERSION): {"foo": "myid"}})
         self.assertEqual("svn-v%d:1 at uuid--foo" % MAPPING_VERSION, map["foo"][0])
+        self.assertEqual("svn-v%d:1 at uuid-" % MAPPING_VERSION, map["foo"][1])

=== modified file 'tests/test_logwalker.py'
--- a/tests/test_logwalker.py	2006-12-28 02:26:06 +0000
+++ b/tests/test_logwalker.py	2006-12-29 16:40:52 +0000
@@ -383,8 +383,9 @@
 
         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
 
-        self.assertEqual(['trunk/data', 'trunk/data/bla', 'trunk/file'], 
-                list(walker.find_children("trunk", 1)))
+        self.assertEqual(
+                set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
+                set(walker.find_children("trunk", 1)))
 
     def test_find_children_later(self):
         repos_url = self.make_client("a", "dc")
@@ -397,7 +398,44 @@
 
         walker = logwalker.LogWalker(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)))
+        self.assertEqual(set(['trunk/data', 'trunk/data/bla']), 
+                set(walker.find_children("trunk", 1)))
+        self.assertEqual(set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
+                set(walker.find_children("trunk", 2)))
+
+    def test_find_children_copy(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk/data/bla': 'foo',
+                         'dc/trunk/db/f1': 'bloe',
+                         'dc/trunk/db/f2': 'bla'})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+        self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
+
+        self.assertEqual(set(['trunk/data', 'trunk/data/bla', 
+                          'trunk/data/fg', 'trunk/data/fg/f1', 
+                          'trunk/data/fg/f2', 'trunk/db',
+                          'trunk/db/f1', 'trunk/db/f2']), 
+                set(walker.find_children("trunk", 2)))
+
+    def test_find_children_copy_del(self):
+        repos_url = self.make_client("a", "dc")
+        self.build_tree({'dc/trunk/data/bla': 'foo',
+                         'dc/trunk/db/f1': 'bloe',
+                         'dc/trunk/db/f2': 'bla'})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+        self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
+        self.client_commit("dc", "My Message")
+        self.client_delete("dc/trunk/data/fg/f2")
+        self.client_commit("dc", "My Message")
+
+        walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
+
+        self.assertEqual(set(['trunk/data', 'trunk/data/bla', 
+                          'trunk/data/fg', 'trunk/data/fg/f1', 'trunk/db',
+                          'trunk/db/f1', 'trunk/db/f2']), 
+                set(walker.find_children("trunk", 3)))

=== modified file 'tests/test_repos.py'
--- a/tests/test_repos.py	2006-12-28 02:26:06 +0000
+++ b/tests/test_repos.py	2006-12-29 16:40:52 +0000
@@ -476,6 +476,21 @@
         renames = repos.revision_fileid_renames("svn-v%d:1@%s-" % (MAPPING_VERSION, repos.uuid))
         self.assertEqual({"test": "bla"}, renames)
 
+    def test_fetch_delete(self):
+        repos_url = self.make_client('d', 'dc')
+        self.build_tree({'dc/foo/bla': "data"})
+        self.client_add("dc/foo")
+        self.client_commit("dc", "My Message")
+        oldrepos = Repository.open("dc")
+        dir = BzrDir.create("f")
+        newrepos = dir.create_repository()
+        oldrepos.copy_content_into(newrepos)
+        self.client_delete("dc/foo/bla")
+        self.client_commit("dc", "Second Message")
+        newrepos = Repository.open("f")
+        oldrepos.copy_content_into(newrepos)
+        self.assertTrue(oldrepos.has_revision("svn-v%d:2@%s-" % (MAPPING_VERSION, oldrepos.uuid)))
+
     def test_fetch_local(self):
         repos_url = self.make_client('d', 'dc')
         self.build_tree({'dc/foo/bla': "data"})
@@ -570,6 +585,22 @@
                 "svn-v%d:2@%s-" % (MAPPING_VERSION, oldrepos.uuid))
         self.assertNotEqual(inv1.path2id("bla"), inv2.path2id("bla"))
 
+    def test_fetch_copy_subdir(self):
+        repos_url = self.make_client('d', 'dc')
+        self.build_tree({'dc/trunk/mydir/a': "data"})
+        self.client_add("dc/trunk")
+        self.client_commit("dc", "My Message")
+        self.build_tree({'dc/branches/tmp': None})
+        self.client_add("dc/branches")
+        self.client_commit("dc", "Second Message")
+        self.client_copy("dc/trunk/mydir", "dc/branches/tmp/abranch")
+        self.client_commit("dc", "Third Message")
+        oldrepos = Repository.open("svn+"+repos_url)
+        oldrepos.set_branching_scheme(TrunkBranchingScheme())
+        dir = BzrDir.create("f")
+        newrepos = dir.create_repository()
+        oldrepos.copy_content_into(newrepos)
+
     def test_fetch_replace_with_subreplace(self):
         filename = os.path.join(self.test_dir, "dumpfile")
         open(filename, 'w').write("""SVN-fs-dump-format-version: 2

=== modified file 'tests/test_scheme.py'
--- a/tests/test_scheme.py	2006-12-28 02:26:06 +0000
+++ b/tests/test_scheme.py	2006-12-29 16:40:52 +0000
@@ -96,12 +96,26 @@
 
     def test_is_branch_slash(self):
         self.assertFalse(self.scheme.is_branch("/"))
+
+    def test_is_branch_slashsub(self):
         self.assertTrue(self.scheme.is_branch("/foo"))
+
+    def test_is_branch_sub(self):
         self.assertTrue(self.scheme.is_branch("foo"))
+
+    def test_is_branch_sub_sub_slash(self):
         self.assertFalse(self.scheme.is_branch("/foo/foo"))
+
+    def test_is_branch_sub_sub(self):
         self.assertFalse(self.scheme.is_branch("foo/bar"))
+
+    def test_is_branch_unknown(self):
         self.assertFalse(self.scheme.is_branch("foobla"))
+
+    def test_is_branch_doubleslash(self):
         self.assertTrue(self.scheme.is_branch("//foo/"))
+
+    def test_is_branch_nested(self):
         self.assertTrue(self.scheme.is_branch("bar/bloe"))
 
     def test_unprefix_notbranch_empty(self):
@@ -191,40 +205,72 @@
         self.assertFalse(scheme.is_branch("/branches/trunk"))
         self.assertTrue(scheme.is_branch("/bar/branches/trunk"))
 
-    def test_unprefix(self):
-        scheme = TrunkBranchingScheme()
-        self.assertRaises(NotBranchError, scheme.unprefix, "")
-        self.assertRaises(NotBranchError, scheme.unprefix, "branches")
-        self.assertRaises(NotBranchError, scheme.unprefix, "/")
-        self.assertRaises(NotBranchError, scheme.unprefix, "blie/bloe/bla")
-        self.assertRaises(NotBranchError, scheme.unprefix, "aa")
-        self.assertEqual(scheme.unprefix("/trunk"), ("trunk", ""))
-        self.assertEqual(scheme.unprefix("branches/ver1/foo"), ("branches/ver1", "foo"))
-        self.assertEqual(scheme.unprefix("tags/ver1"), ("tags/ver1", ""))
-        self.assertEqual(scheme.unprefix("//trunk/foo"), ("trunk", "foo"))
-        self.assertEqual(scheme.unprefix("/tags/ver2/foo/bar"), ("tags/ver2", "foo/bar"))
+    def test_unprefix_empty(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme().unprefix, "")
+
+    def test_unprefix_topdir(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme().unprefix, "branches")
+
+    def test_unprefix_slash(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme().unprefix, "/")
+
+    def test_unprefix_unknown_sub(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme().unprefix, "blie/bloe/bla")
+
+    def test_unprefix_unknown(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme().unprefix, "aa")
+
+    def test_unprefix_slash_branch(self):
+        self.assertEqual(TrunkBranchingScheme().unprefix("/trunk"), ("trunk", ""))
+
+    def test_unprefix_nested_branch_sub(self):
+        self.assertEqual(TrunkBranchingScheme().unprefix("branches/ver1/foo"), ("branches/ver1", "foo"))
+
+    def test_unprefix_nested_tag_sub(self):
+        self.assertEqual(TrunkBranchingScheme().unprefix("tags/ver1"), ("tags/ver1", ""))
+
+    def test_unprefix_doubleslash_branch(self):
+        self.assertEqual(TrunkBranchingScheme().unprefix("//trunk/foo"), ("trunk", "foo"))
+
+    def test_unprefix_slash_tag(self):
+        self.assertEqual(TrunkBranchingScheme().unprefix("/tags/ver2/foo/bar"), ("tags/ver2", "foo/bar"))
 
     def test_unprefix_level(self):
-        scheme = TrunkBranchingScheme(1)
-        self.assertRaises(NotBranchError, scheme.unprefix, "trunk")
-        self.assertRaises(NotBranchError, scheme.unprefix, "/branches/foo")
-        self.assertRaises(NotBranchError, scheme.unprefix, "branches/ver1/foo")
-        self.assertEqual(scheme.unprefix("/foo/trunk"), ("foo/trunk", ""))
-        self.assertEqual(scheme.unprefix("data/tags/ver1"), ("data/tags/ver1", ""))
-
-    def test_guess(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme(1).unprefix, "trunk")
+
+    def test_unprefix_level_wrong_level(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme(1).unprefix, "/branches/foo")
+
+    def test_unprefix_level_wrong_level_nested(self):
+        self.assertRaises(NotBranchError, TrunkBranchingScheme(1).unprefix, "branches/ver1/foo")
+
+    def test_unprefix_level_correct_branch(self):
+        self.assertEqual(TrunkBranchingScheme(1).unprefix("/foo/trunk"), ("foo/trunk", ""))
+
+    def test_unprefix_level_correct_nested(self):
+        self.assertEqual(TrunkBranchingScheme(1).unprefix("data/tags/ver1"), ("data/tags/ver1", ""))
+
+    def test_guess_trunk_zero(self):
         scheme = BranchingScheme.guess_scheme("trunk") 
         self.assertIsInstance(scheme, TrunkBranchingScheme)
         self.assertEqual(0, scheme.level)
+
+    def test_guess_trunk_branch_sub(self):
         scheme = BranchingScheme.guess_scheme("branches/foo/bar")
         self.assertIsInstance(scheme, TrunkBranchingScheme)
         self.assertEqual(0, scheme.level)
+
+    def test_guess_trunk_level(self):
         scheme = BranchingScheme.guess_scheme("test/branches/foo/bar")
         self.assertIsInstance(scheme, TrunkBranchingScheme)
         self.assertEqual(1, scheme.level)
+
+    def test_guess_trunk_level_sub(self):
         scheme = BranchingScheme.guess_scheme("test/bar/branches/foo/bar")
         self.assertIsInstance(scheme, TrunkBranchingScheme)
         self.assertEqual(2, scheme.level)
+
+    def test_guess_level_detection(self):
         scheme = BranchingScheme.guess_scheme("branches/trunk")
         self.assertIsInstance(scheme, TrunkBranchingScheme)
         self.assertEqual(0, scheme.level)




More information about the bazaar-commits mailing list