Fix get_revision() and fetching of signatures. Now fails on fetching
authorJelmer Vernooij <jelmer@samba.org>
Sat, 15 Apr 2006 01:34:13 +0000 (03:34 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 15 Apr 2006 01:34:13 +0000 (03:34 +0200)
the inventory weave

README
branch.py
repository.py

diff --git a/README b/README
index cab85acfb407e9b8524420ad932a4f5c83c6eea9..7b0428e4b67e172d59020fdb1b5c8880ec061993 100644 (file)
--- a/README
+++ b/README
@@ -1,10 +1,13 @@
 This directory contains a simple plugin that adds 
-Subversion branch support to Bazaar (http://www.bazaar-vcs.org/)
+Subversion (http://subversion.tigris.org/) branch support to 
+Bazaar (http://www.bazaar-vcs.org/)
 
-You will need a modified version of bzr that has support for 
-foreign branches (branch at http://samba.org/~jelmer/bzr/foreignbranch).
+You will need a recent version of Bazaar-NG, at least 0.8 (or 
+one of the 0.8 pre releases).
 
 You also need the Subversion bindings for python.
 
 Simply place this directory in ~/.bazaar/plugins and you should be able 
 to check out branches from Subversion using bzr.
+
+Jelmer Vernooij <jelmer@samba.org>, April 2006.
index 8a6d7236a5fca48f17f1921390b02a4079544a52..4e4c8a8102aa986b8ea6e92f4d0653c76b6420b1 100644 (file)
--- a/branch.py
+++ b/branch.py
@@ -61,7 +61,7 @@ class SvnRevisionTree(Tree):
         self.branch = branch
         self.revision_id = revision_id
         self.revnum = self.branch.get_revnum(revision_id)
-        self._inventory = branch.get_inventory(revision_id)
+        self._inventory = branch.repository.get_inventory(revision_id)
 
     def get_file_sha1(self,file_id):
         return bzrlib.osutils.sha_string(self.get_file(file_id))
@@ -129,7 +129,7 @@ class SvnBranch(Branch):
         raise NotImplementedError('set_root_id not supported on Subversion Branches')
             
     def get_root_id(self):
-        inv = self.get_inventory(self.last_revision())
+        inv = self.repository.get_inventory(self.last_revision())
         return inv.root.file_id
 
     def abspath(self, name):
@@ -194,46 +194,6 @@ class SvnBranch(Branch):
         # from
         return self.revision_history()[0:i+1]
 
-    def get_inventory(self, revision_id):
-        revnum = self.get_revnum(revision_id)
-        mutter('getting inventory %r for branch %r' % (revnum.value.number, self.base))
-
-        mutter("svn ls -r %d '%r'" % (revnum.value.number, self.base))
-        remote_ls = svn.client.ls(self.base.encode('utf8'),
-                                         revnum,
-                                         True, # recurse
-                                         self.repository.client, 
-                                         self.repository.pool)
-        mutter('done')
-
-        # Make sure a directory is always added before its contents
-        names = remote_ls.keys()
-        names.sort(lambda a,b: len(a) - len(b))
-
-        inv = Inventory()
-        for entry in names:
-            ri = entry.rfind('/')
-            if ri == -1:
-                top = entry
-                parent = ''
-            else:
-                top = entry[ri+1:]
-                parent = entry[0:ri]
-
-            parent_id = inv.path2id(parent)
-            assert not parent_id is None
-            
-            id = self.filename_to_file_id(revision_id, entry)
-
-            if remote_ls[entry].kind == svn.core.svn_node_dir:
-                inv.add(InventoryDirectory(id,top,parent_id=parent_id))
-            elif remote_ls[entry].kind == svn.core.svn_node_file:
-                inv.add(InventoryFile(id,top,parent_id=parent_id))
-            else:
-                raise BzrError("Unknown entry kind for '%s': %d" % (entry, remote_ls[entry].kind))
-
-        return inv
-
     def pull(self, source, overwrite=False):
         print "Pull from %s to %s" % (source,self)
         raise NotImplementedError('pull is abstract') #FIXME
@@ -271,23 +231,3 @@ class SvnBranch(Branch):
 
     def append_revision(self, *revision_ids):
         raise NotImplementedError('append_revision is abstract') #FIXME
-
-    def working_tree(self):
-        if self.path is None:
-            raise NoWorkingTree(self.base)
-        else:
-            return SvnWorkingTree(self.path,branch=self)
-
-    # FIXME: perhaps move these four to a 'ForeignBranch' class in 
-    # bzr core?
-    def get_revision_xml(self, revision_id):
-        return bzrlib.xml5.serializer_v5.write_revision_to_string(self.get_revision(revision_id))
-
-    def get_inventory_xml(self, revision_id):
-        return bzrlib.xml5.serializer_v5.write_inventory_to_string(self.get_inventory(revision_id))
-
-    def get_revision_sha1(self, revision_id):
-        return bzrlib.osutils.sha_string(self.get_revision_xml(revision_id))
-
-    def get_inventory_sha1(self, revision_id):
-        return bzrlib.osutils.sha_string(self.get_inventory_xml(revision_id))
index 26b8117005ac199020fec78476278a12b91010a9..eb43ff9dffea1f3a0acb4528b8f00928e2fb8601 100644 (file)
@@ -7,9 +7,14 @@ from bzrlib.repository import Repository
 from bzrlib.lockable_files import LockableFiles, TransportLock
 from bzrlib.trace import mutter
 from bzrlib.revision import Revision
+from bzrlib.errors import NoSuchRevision
+from bzrlib.versionedfile import VersionedFile
+from libsvn._core import SubversionException
 import svn.core
 import bzrlib
 from branch import auth_baton
+from bzrlib.weave import Weave
+from cStringIO import StringIO
 
 """
 Provides a simplified interface to a Subversion repository 
@@ -40,15 +45,51 @@ class SvnRepository(Repository):
     def __del__(self):
         svn.core.svn_pool_destroy(self.pool)
 
-    def get_inventory(self):
-        raise NotImplementedError()
+    def get_inventory(self, revision_id):
+        revnum = self.get_revnum(revision_id)
+        mutter('getting inventory %r for branch %r' % (revnum.value.number, self.base))
+
+        mutter("svn ls -r %d '%r'" % (revnum.value.number, self.base))
+        remote_ls = svn.client.ls(self.base.encode('utf8'),
+                                         revnum,
+                                         True, # recurse
+                                         self.repository.client, 
+                                         self.repository.pool)
+        mutter('done')
+
+        # Make sure a directory is always added before its contents
+        names = remote_ls.keys()
+        names.sort(lambda a,b: len(a) - len(b))
+
+        inv = Inventory()
+        for entry in names:
+            ri = entry.rfind('/')
+            if ri == -1:
+                top = entry
+                parent = ''
+            else:
+                top = entry[ri+1:]
+                parent = entry[0:ri]
+
+            parent_id = inv.path2id(parent)
+            assert not parent_id is None
+            
+            id = self.filename_to_file_id(revision_id, entry)
+
+            if remote_ls[entry].kind == svn.core.svn_node_dir:
+                inv.add(InventoryDirectory(id,top,parent_id=parent_id))
+            elif remote_ls[entry].kind == svn.core.svn_node_file:
+                inv.add(InventoryFile(id,top,parent_id=parent_id))
+            else:
+                raise BzrError("Unknown entry kind for '%s': %d" % (entry, remote_ls[entry].kind))
+
+        return inv
 
     def all_revision_ids(self):
         raise NotImplementedError()
 
     def get_inventory_weave(self):
-        # FIXME
-        raise NotImplementedError()
+        raise NotImplementedError
 
     def get_ancestry(self, revision_id):
         (path,revnum) = self.parse_revision_id(revision_id)
@@ -102,6 +143,7 @@ class SvnRepository(Repository):
         return self._found
 
     def get_revision(self,revision_id):
+        mutter("retrieving %s" % revision_id)
         (path,revnum) = self.parse_revision_id(revision_id)
         
         url = self.url + "/" + path
@@ -113,6 +155,10 @@ class SvnRepository(Repository):
         (svn_props, actual_rev) = svn.client.revprop_list(url.encode('utf8'), rev, self.client, self.pool)
         assert actual_rev == revnum
 
+        revt_peg = svn.core.svn_opt_revision_t()
+        revt_peg.kind = svn.core.svn_opt_revision_number
+        revt_peg.value.number = revnum
+
         revt_begin = svn.core.svn_opt_revision_t()
         revt_begin.kind = svn.core.svn_opt_revision_number
         revt_begin.value.number = revnum - 1
@@ -127,11 +173,16 @@ class SvnRepository(Repository):
             revid = "%d@%s-%s" % (rev,self.uuid,path)
             parent_ids.append(revid)
 
-        mutter("log3 %s" % url)
-        svn.client.log3([url.encode('utf8')], revt_begin, revt_begin, \
+        mutter("log3 -r%d:0 %s" % (revnum-1,url))
+        try:
+            svn.client.log3([url.encode('utf8')], revt_peg, revt_begin, \
                 revt_end, 1, False, False, rcvr, 
                 self.client, self.pool)
 
+        except SubversionException, (_,num):
+            if num != 195012:
+                raise
+
         # Commit SVN revision properties to a Revision object
         bzr_props = {}
         rev = Revision(revision_id=revision_id,
@@ -147,6 +198,8 @@ class SvnRepository(Repository):
         rev.message = bzr_props[svn.core.SVN_PROP_REVISION_LOG]
 
         rev.properties = bzr_props
+
+        rev.inventory_sha1 = "EMPTY"  #FIXME
         
         return rev
 
@@ -159,9 +212,6 @@ class SvnRepository(Repository):
     def fileid_involved(self, last_revid=None):
         raise NotImplementedError()
 
-    def get_inventory_xml(self, revision_id):
-        raise NotImplementedError()
-
     def fileid_involved_by_set(self, changes):
         ids = []
 
@@ -171,6 +221,7 @@ class SvnRepository(Repository):
         return ids
 
     def parse_revision_id(self,revid):
+        assert isinstance(revid,basestring)
         at = revid.index("@")
         fash = revid.rindex("-")
         uuid = revid[at+1:fash]
@@ -180,8 +231,32 @@ class SvnRepository(Repository):
 
         return (revid[fash+1:],int(revid[0:at]))
 
+    def get_inventory_xml(self, revision_id):
+        return bzrlib.xml5.serializer_v5.write_inventory_to_string(self.get_inventory(revision_id))
+
+    def get_inventory_sha1(self, revision_id):
+        return bzrlib.osutils.sha_string(self.get_inventory_xml(revision_id))
+
+    def get_revision_xml(self, revision_id):
+        return bzrlib.xml5.serializer_v5.write_revision_to_string(self.get_revision(revision_id))
+
+    def get_revision_sha1(self, revision_id):
+        return bzrlib.osutils.sha_string(self.get_revision_xml(revision_id))
+
     def get_revision_graph_with_ghosts(self, revision_id):
-        raise NotImplementedError()
+        result = Graph()
+
+        #FIXME
+        raise NotImplementedError
+
+        return result
+
+    def has_signature_for_revision_id(self, revision_id):
+        return False # SVN doesn't store GPG signatures. Perhaps 
+                     # store in SVN revision property?
+
+    def get_signature_text(self, revision_id):
+        raise NoSuchRevision(self, revision_id) # SVN doesn't store GPG signatures
 
     def get_revision_graph(self, revision_id):
         if revision_id is None: