More work on supporting creating branches.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 16 Jul 2007 01:34:19 +0000 (03:34 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 16 Jul 2007 01:34:19 +0000 (03:34 +0200)
commit.py
format.py
tests/__init__.py
tests/test_radir.py

index cb934693cc812c4e328b9fe5f6365acfec97c56f..03961b8147f17c209d096edcd481dc185ae38d73 100644 (file)
--- a/commit.py
+++ b/commit.py
 import svn.delta
 from svn.core import Pool, SubversionException
 
+from bzrlib import osutils, urlutils
 from bzrlib.branch import Branch
 from bzrlib.errors import InvalidRevisionId, DivergedBranches
 from bzrlib.inventory import Inventory
-import bzrlib.osutils as osutils
 from bzrlib.repository import RootCommitBuilder, InterRepository
 from bzrlib.revision import NULL_REVISION
 from bzrlib.trace import mutter
@@ -33,6 +33,7 @@ from repository import (SVN_PROP_BZR_MERGE, SVN_PROP_BZR_FILEIDS,
                         SvnRepository)
 from revids import escape_svn_path
 
+from copy import copy
 import os
 
 class SvnCommitBuilder(RootCommitBuilder):
@@ -198,7 +199,7 @@ class SvnCommitBuilder(RootCommitBuilder):
 
                 child_baton = self.editor.add_file(
                            os.path.join(self.branch.branch_path, self.new_inventory.id2path(child_ie.file_id)), baton, 
-                           "%s/%s" % (self.branch.base, self.old_inv.id2path(child_ie.file_id)),
+                           urlutils.join(self.repository.transport.svn_url, self.branch.branch_path, self.old_inv.id2path(child_ie.file_id)),
                            self.base_revnum, self.pool)
 
             # open if they existed at the same location
@@ -266,7 +267,7 @@ class SvnCommitBuilder(RootCommitBuilder):
                 child_baton = self.editor.add_directory(
                            os.path.join(self.branch.branch_path, self.new_inventory.id2path(child_ie.file_id)),
                            baton, 
-                           "%s/%s" % (self.branch.base, self.old_inv.id2path(child_ie.file_id)),
+                           urlutils.join(self.repository.transport.svn_url, self.branch.branch_path, self.old_inv.id2path(child_ie.file_id)),
                            self.base_revnum, self.pool)
 
             # open if they existed at the same location and 
@@ -473,6 +474,43 @@ def push_as_merged(target, source, revision_id):
             raise DivergedBranches(source, target)
         raise
 
+
+def push_new(target_repository, target_branch_path, source, stop_revision=None):
+    """Push a revision into Subversion, creating a new branch.
+
+    This will do a new commit in the target branch.
+
+    :param target: Branch to push to
+    :param source: Branch to pull the revision from
+    :param revision_id: Revision id of the revision to push
+    """
+    if stop_revision is None:
+        stop_revision = source.last_revision()
+    history = source.revision_history()
+    revhistory = copy(history)
+    revhistory.reverse()
+    start_revid = None
+    for revid in revhistory:
+        if target_repository.has_revision(revid):
+            start_revid = revid
+            break
+
+    if start_revid is not None:
+        (copy_path, copy_revnum, 
+            scheme) = target_repository.lookup_revision_id(start_revid)
+    else:
+        # None of the revisions are already present in the repository
+        copy_path = None
+        copy_revnum = None
+    
+    # TODO: Get commit builder but specify that target_branch_path should
+    # be created and copied from (copy_path, copy_revnum)
+
+    branch = self.open_branch()
+    branch.pull(source)
+    return branch
+
+
 def push(target, source, revision_id):
     """Push a revision into Subversion.
 
index 61a0f5e6dfd9fec9dcd06f6d98c44ea585b1c3d1..d59b1016fcbc5a1d2fbc2d192cdecb9f6d72fbb5 100644 (file)
--- a/format.py
+++ b/format.py
@@ -131,6 +131,16 @@ class SvnRemoteAccess(BzrDir):
             format = BzrDirFormat.get_default_format()
         return not isinstance(self._format, format.__class__)
 
+    def import_branch(self, source):
+        """Create a new branch in this repository, possibly 
+        with the specified history, optionally importing revisions.
+        """
+        from commit import push_new
+        return push_new(self.find_repository(), 
+                        self.branch_path,
+                        source,
+                        source.last_revision())
+
     def create_branch(self):
         """See BzrDir.create_branch()."""
         from branch import SvnBranch
index 72e83b14c2099db968d30b9dc1cb0697e5ec5f40..5c56c2fbfa0b8fc54fa36c8ff64eb83b0dda418b 100644 (file)
@@ -166,6 +166,27 @@ class TestCaseWithSubversionRepository(TestCaseInTempDir):
         """
         svn.client.add3(relpath, recursive, False, False, self.client_ctx)
 
+    def revnum_to_opt_rev(self, revnum):
+        rev = svn.core.svn_opt_revision_t()
+        if revnum is None:
+            rev.kind = svn.core.svn_opt_revision_head
+        else:
+            rev.kind = svn.core.svn_opt_revision_number
+            rev.value.number = revnum
+        return rev
+
+    def client_log(self, path, start_revnum=None, stop_revnum=None):
+        ret = {}
+        def rcvr(orig_paths, rev, author, date, message, pool):
+            ret[rev] = (orig_paths, author, date, message)
+        svn.client.log([path], self.revnum_to_opt_rev(start_revnum),
+                       self.revnum_to_opt_rev(stop_revnum),
+                       True,
+                       True,
+                       rcvr,
+                       self.client_ctx)
+        return ret
+
     def client_delete(self, relpath):
         """Remove specified files from working copy.
 
index ca0495cb5ce93be1eee355f7d3f18721cefd3f14..473cd265a96d89ab452297daf261f7b395fc5931 100644 (file)
@@ -77,6 +77,18 @@ class TestRemoteAccess(TestCaseWithSubversionRepository):
         x = BzrDir.open(repos_url)
         self.assertTrue(hasattr(x, 'svn_root_url'))
 
+    def test_import_branch(self):
+        repos_url = self.make_client("d", "dc")
+        x = BzrDir.open(repos_url+"/trunk")
+        origb = BzrDir.create_standalone_workingtree("origb")
+        self.build_tree({'origb/twin': 'bla', 'origb/peaks': 'bloe'})
+        origb.add(["twin", "peaks"])
+        origb.commit("Message")
+        b = x.import_branch(source=origb.branch)
+        self.assertEquals(origb.revision_history(), b.revision_history())
+        self.assertEquals(origb.revision_history(), 
+                Branch.open(repos_url+"/trunk").revision_history())
+
     def test_open_repos_root(self):
         repos_url = self.make_client("d", "dc")
         x = BzrDir.open(repos_url)