[Pkg-bazaar-commits] ./bzr-svn/unstable r350: * New upstream release.

Jelmer Vernooij jelmer at samba.org
Fri Jul 17 11:28:14 UTC 2009


------------------------------------------------------------
revno: 350
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: unstable
timestamp: Fri 2009-07-17 13:26:31 +0200
message:
  * New upstream release.
  * Bump standards version to 3.8.2.
modified:
  NEWS
  __init__.py
  auth.py
  cache/sqlitecache.py
  commit.py
  debian/changelog
  debian/control
  fetch.py
  layout/__init__.py
  layout/standard.py
  mapping.py
  mapping3/__init__.py
  setup.py
  tests/__init__.py
  tests/test_blackbox.py
  tests/test_cache.py
  tests/test_layout.py
  tests/test_repository.py
  transport.py
    ------------------------------------------------------------
    revno: 220.106.278
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Thu 2009-06-18 15:23:43 +0200
    message:
      Start on 0.6.3.
    modified:
      NEWS
      __init__.py
      setup.py
    ------------------------------------------------------------
    revno: 220.106.279
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Thu 2009-06-18 15:29:43 +0200
    message:
      Fix test against bzr.dev.
    modified:
      tests/test_blackbox.py
    ------------------------------------------------------------
    revno: 220.106.280
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Thu 2009-06-18 23:25:43 +0200
    message:
      fix syntax errors.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.281
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Fri 2009-06-19 02:41:52 +0200
    message:
      Fix CustomLayout.get_branches().
    modified:
      NEWS
      layout/standard.py
      tests/test_layout.py
    ------------------------------------------------------------
    revno: 220.106.282
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-06-20 17:07:22 +0200
    message:
      Add helper function for converting from bzr to svn urls.
    modified:
      tests/test_repository.py
      transport.py
    ------------------------------------------------------------
    revno: 220.106.283
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-06-20 17:10:38 +0200
    message:
      Fix file:// URLs on Windows.
    modified:
      tests/__init__.py
      transport.py
    ------------------------------------------------------------
    revno: 220.106.284
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-06-20 17:12:27 +0200
    message:
      Fix import.
    modified:
      tests/__init__.py
    ------------------------------------------------------------
    revno: 220.106.285
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-06-20 17:20:05 +0200
    message:
      Fix bug raising UnavailableFeature.
    modified:
      tests/test_cache.py
    ------------------------------------------------------------
    revno: 220.106.286
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-06-20 18:45:44 +0200
    message:
      Cope with revisions that don't have a revision message set.
    modified:
      NEWS
      fetch.py
      mapping.py
    ------------------------------------------------------------
    revno: 220.106.287
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 05:33:16 +0200
    message:
      Remove content cache.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.288
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 05:44:21 +0200
    message:
      Use insert_record_stream for directories.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.289
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 06:01:16 +0200
    message:
      Use chunks internally during fetch, rather than fulltext.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.290
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 06:01:35 +0200
    message:
      Remove unused StringIO import.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.291
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 06:12:56 +0200
    message:
      Formatting, simplify.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.292
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 06:32:35 +0200
    message:
      Focus more on chunks rather than lines where possible; pass base_ie.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.293
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 06:58:56 +0200
    message:
      Avoid add_lines.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.294
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Tue 2009-06-23 07:26:19 +0200
    message:
      Quicker check for potential links.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.295
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-06-24 16:39:06 +0200
    message:
      Fix formatting in svn-layout text, remove references to schemes to avoid confusion.
    modified:
      layout/__init__.py
    ------------------------------------------------------------
    revno: 220.106.296
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-06-24 17:08:30 +0200
    message:
      Auto-pack after fetch.
    modified:
      NEWS
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.297
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-06-24 17:16:59 +0200
    message:
      Only do optimal packing on bzr >= 1.17.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.298
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-06-24 18:45:53 +0200
    message:
      Fix sqlitecache.
    modified:
      cache/sqlitecache.py
    ------------------------------------------------------------
    revno: 220.106.299
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-07-01 14:16:49 +0200
    message:
      Avoid connecting twice when pushing.
    modified:
      commit.py
    ------------------------------------------------------------
    revno: 220.106.300
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-07-01 14:17:03 +0200
    message:
      Prevent syntax error.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.301
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Wed 2009-07-01 14:26:18 +0200
    message:
      Only pack if it makes the target repo smaller.
    modified:
      fetch.py
    ------------------------------------------------------------
    revno: 220.106.302
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Fri 2009-07-03 00:53:59 +0200
    message:
      Explain repository UUIDs.
    modified:
      NEWS
      layout/__init__.py
    ------------------------------------------------------------
    revno: 220.106.303
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Fri 2009-07-03 01:07:24 +0200
    message:
      Remove svn-branching-schemes help topic.
    modified:
      NEWS
      __init__.py
      mapping3/__init__.py
    ------------------------------------------------------------
    revno: 220.106.304
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Sat 2009-07-04 00:28:25 +0200
    message:
      Fix mutter arguments.
    modified:
      auth.py
    ------------------------------------------------------------
    revno: 220.106.305
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Mon 2009-07-13 19:10:25 +0200
    message:
      Remove incorrect command count.
    modified:
      __init__.py
    ------------------------------------------------------------
    revno: 220.106.306
    committer: Jelmer Vernooij <jelmer at samba.org>
    branch nick: 0.6
    timestamp: Fri 2009-07-17 13:18:30 +0200
    message:
      Release 0.6.3.
    modified:
      NEWS
      __init__.py
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-06-18 13:33:41 +0000
+++ b/NEWS	2009-07-17 11:26:31 +0000
@@ -1,3 +1,25 @@
+bzr-svn 0.6.3                    2009-07-17
+
+ FEATURES
+
+  * Pack relevant parts of the repository after fetch.
+
+ CHANGES
+  
+  * Removed svn-branching-schemes help, because it's not relevant for new 
+    users and might be confusing for users looking at "bzr help topics".
+ 
+ BUG FIXES
+ 
+  * Fix CustomLayout.get_branches. (Closes: #388698)
+
+  * Fix fetching of revisions with no commit message set to the 2a repository 
+    format.
+
+  * Explain repository UUIDs in "bzr help svn-layout". (#391525)
+
+  * Mark as compatible with bzr 1.17.
+
 bzr-svn 0.6.2                    2009-06-18
 
   FEATURES

=== modified file '__init__.py'
--- a/__init__.py	2009-06-18 13:33:41 +0000
+++ b/__init__.py	2009-07-17 11:26:31 +0000
@@ -20,7 +20,7 @@
 
 Most Bazaar commands should work fine with Subversion branches. 
 
-bzr-svn also adds four new commands to Bazaar:
+bzr-svn also adds new commands to Bazaar:
 
  - bzr svn-import
  - bzr svn-layout
@@ -34,7 +34,7 @@
 # versions ending in 'exp' mean experimental mappings
 # versions ending in 'dev' mean development version
 # versions ending in 'final' mean release (well tested, etc)
-version_info = (0, 6, 2, 'final', 0)
+version_info = (0, 6, 3, 'final', 0)
 
 if version_info[3] == 'final':
     version_string = '%d.%d.%d' % version_info[:3]
@@ -153,9 +153,6 @@
                         'SvnRaTransport')
 register_lazy_transport('svn+', 'bzrlib.plugins.svn.transport', 
                         'SvnRaTransport')
-topic_registry.register_lazy('svn-branching-schemes', 
-                             'bzrlib.plugins.svn.mapping3',
-                             'help_schemes', 'Subversion branching schemes')
 topic_registry.register_lazy('svn-layout', 
                              'bzrlib.plugins.svn.layout',
                              'help_layout', 'Subversion repository layouts')

=== modified file 'auth.py'
--- a/auth.py	2009-06-12 02:43:34 +0000
+++ b/auth.py	2009-07-03 22:28:25 +0000
@@ -83,8 +83,8 @@
         :param username: Username, if it is already known, or None.
         :param may_save: Whether or not the username should be saved.
         """
-        mutter("Obtaining username and password for SVN connection %r (username: %r)", 
-               realm, username)
+        mutter("Obtaining username and password for SVN connection %r"
+               "(username: %r)", realm, username)
         username = self.get_user(self.scheme, 
                 host=self.host, path=self.path, realm=realm, ask=True)
         password = self.get_password(self.scheme, host=self.host, 
@@ -224,7 +224,7 @@
             try:
                 credentials['port'] = socket.getservbyname(credentials['scheme'])
             except socket.error:
-                mutter("Unable to look up default port for %(scheme)s", 
+                mutter("Unable to look up default port for %(scheme)s" % 
                        credentials)
                 return None
         return "<%(scheme)s://%(host)s:%(port)s> %(realm)s" % credentials

=== modified file 'cache/sqlitecache.py'
--- a/cache/sqlitecache.py	2009-06-14 23:36:21 +0000
+++ b/cache/sqlitecache.py	2009-06-24 16:45:53 +0000
@@ -351,7 +351,8 @@
         result = self.cachedb.execute("select all_revprops from revinfo where rev = ?", (revnum,)).fetchone()
         if result is None:
             all_revprops = False
-        all_revprops = result[0]
+        else:
+            all_revprops = result[0]
         return (revprops, all_revprops)
 
     def insert_revprops(self, revision, revprops, all_revprops):

=== modified file 'commit.py'
--- a/commit.py	2009-06-18 13:33:41 +0000
+++ b/commit.py	2009-07-17 11:26:31 +0000
@@ -750,33 +750,33 @@
             conn = self.repository.transport.get_connection()
             assert self.supports_custom_revprops or self._svn_revprops.keys() == [properties.PROP_REVISION_LOG], \
                     "revprops: %r" % self._svn_revprops.keys()
+            replace_existing = False
+            # See whether the base of the commit matches the lhs parent
+            # if not, we need to replace the existing directory
+            if len(bp_parts) == len(existing_bp_parts):
+                if self.base_path is None or self.base_path.strip("/") != "/".join(bp_parts).strip("/"):
+                    replace_existing = True
+                    if self._append_revisions_only:
+                        raise AppendRevisionsOnlyViolation(
+                            urlutils.join(self.repository.base, self.branch_path))
+                elif self.base_revnum < self.repository._log.find_latest_change(self.branch_path, repository_latest_revnum):
+                    replace_existing = True
+                    if self._append_revisions_only:
+                        raise AppendRevisionsOnlyViolation(
+                            urlutils.join(self.repository.base, self.branch_path))
+                elif self.old_inv.root.file_id != self.new_root_id:
+                    replace_existing = True
+
+            if self.new_root_id in self.old_inv:
+                root_from = self.old_inv.id2path(self.new_root_id)
+            else:
+                root_from = None
+
             self.editor = convert_svn_error(conn.get_commit_editor)(
                     self._svn_revprops, done, None, False)
             try:
                 root = self.editor.open_root(self.base_revnum)
 
-                replace_existing = False
-                # See whether the base of the commit matches the lhs parent
-                # if not, we need to replace the existing directory
-                if len(bp_parts) == len(existing_bp_parts):
-                    if self.base_path is None or self.base_path.strip("/") != "/".join(bp_parts).strip("/"):
-                        replace_existing = True
-                        if self._append_revisions_only:
-                            raise AppendRevisionsOnlyViolation(
-                                urlutils.join(self.repository.base, self.branch_path))
-                    elif self.base_revnum < self.repository._log.find_latest_change(self.branch_path, repository_latest_revnum):
-                        replace_existing = True
-                        if self._append_revisions_only:
-                            raise AppendRevisionsOnlyViolation(
-                                urlutils.join(self.repository.base, self.branch_path))
-                    elif self.old_inv.root.file_id != self.new_root_id:
-                        replace_existing = True
-
-                if self.new_root_id in self.old_inv:
-                    root_from = self.old_inv.id2path(self.new_root_id)
-                else:
-                    root_from = None
-
                 branch_editors = self.open_branch_editors(root, bp_parts,
                     existing_bp_parts, self.base_url, self.base_revnum, 
                     root_from, replace_existing)

=== modified file 'debian/changelog'
--- a/debian/changelog	2009-06-18 13:37:50 +0000
+++ b/debian/changelog	2009-07-17 11:26:31 +0000
@@ -1,3 +1,10 @@
+bzr-svn (0.6.3-1) unstable; urgency=low
+
+  * New upstream release.
+  * Bump standards version to 3.8.2.
+
+ -- Jelmer Vernooij <jelmer at debian.org>  Fri, 17 Jul 2009 13:26:29 +0200
+
 bzr-svn (0.6.2-1) unstable; urgency=low
 
   * New upstream snapshot.

=== modified file 'debian/control'
--- a/debian/control	2009-06-18 13:33:41 +0000
+++ b/debian/control	2009-07-17 11:26:31 +0000
@@ -5,13 +5,13 @@
 Homepage: http://bazaar-vcs.org/BzrSvn
 Uploaders: Jelmer Vernooij <jelmer at debian.org>, Reinhard Tartler <siretart at tauware.de>, Robert Collins <robertc at robertcollins.net>
 Build-Depends: python-central (>= 0.5), cdbs (>= 0.4.43), python, debhelper (>= 5.0.37.2), bzr (>= 1.16~), python (>= 2.5), python-subvertpy (>> 0.6.1)
-Standards-Version: 3.8.1
+Standards-Version: 3.8.2
 XS-Python-Version: >= 2.5
 Vcs-Bzr: http://bzr.debian.org/pkg-bazaar/bzr-svn/unstable
 
 Package: bzr-svn
 Architecture: all
-Depends: bzr (>= 1.16~), bzr (<< 1.17~), ${python:Depends}, ${misc:Depends}, python (>= 2.5) | python-pysqlite2 | python-tdb (>= 1.1.2~git20081222), python-subvertpy (>> 0.6.1)
+Depends: bzr (>= 1.16~), bzr (<< 1.18~), ${python:Depends}, ${misc:Depends}, python (>= 2.5) | python-pysqlite2 | python-tdb (>= 1.1.2~git20081222), python-subvertpy (>> 0.6.1)
 Enhances: bzr, subversion
 Recommends: python-tdb (>= 1.1.2~git20081222), python-xdg
 Suggests: bzr-rebase (>= 0.5.0)

=== modified file 'fetch.py'
--- a/fetch.py	2009-06-18 13:33:41 +0000
+++ b/fetch.py	2009-07-17 11:26:31 +0000
@@ -24,9 +24,6 @@
 except ImportError:
     from bzrlib.plugins.svn.pycompat import defaultdict
 
-from cStringIO import (
-    StringIO,
-    )
 import subvertpy
 from subvertpy import (
     ERR_FS_NOT_DIRECTORY,
@@ -64,6 +61,7 @@
     InterRepository,
     )
 from bzrlib.versionedfile import (
+    ChunkedContentFactory,
     FulltextContentFactory,
     )
 
@@ -99,8 +97,19 @@
 ERR_FS_PATH_SYNTAX = getattr(subvertpy, "ERR_FS_PATH_SYNTAX", 160005)
 
 
-def apply_txdelta_handler_chunks(chunks, stream):
-    return apply_txdelta_handler(''.join(chunks), stream)
+try:
+    from subvertpy.delta import apply_txdelta_handler_chunks
+except ImportError:
+    def apply_txdelta_handler_chunks(source_chunks, target_chunks):
+        class ChunkWriteStream(object):
+
+            def __init__(self, l):
+                self.l = l
+
+            def write(self, s):
+                self.l.append(s)
+        return apply_txdelta_handler(''.join(source_chunks), 
+                                     ChunkWriteStream(target_chunks))
 
 
 def inventory_ancestors(inv, fileid, exceptions):
@@ -115,10 +124,10 @@
     return ret
 
 
-def md5_strings(lines):
-    """Return the MD5sum of a list of lines."""
+def md5_strings(chunks):
+    """Return the MD5sum of a list of chunks."""
     s = osutils.md5()
-    map(s.update, lines)
+    map(s.update, chunks)
     return s.hexdigest()
 
 
@@ -428,9 +437,11 @@
 
             self.new_ie.revision = self.editor._get_text_revision(self.path) or self.editor.revid
             text_parents = self.editor._get_text_parents(self.path) or self.parent_revids
-            self.editor.texts.add_lines(
+            self.editor.texts.insert_record_stream([
+                ChunkedContentFactory(
                 (self.new_id, self.new_ie.revision),
-                tuple([(self.new_id, revid) for revid in text_parents]), [])
+                tuple([(self.new_id, revid) for revid in text_parents]), None,
+                [])])
             self.editor._inv_delta.append((self.old_path, self.path, self.new_id, self.new_ie))
         if self._renew_fileids:
             # Make sure files get re-added that weren't mentioned explicitly
@@ -480,7 +491,8 @@
             # to make sure all children get readded with a new file id
             renew_fileids = base_file_id
         return DirectoryRevisionBuildEditor(self.editor, old_path, path, 
-            base_file_id, file_id, self.new_id, file_parents, renew_fileids=renew_fileids)
+            base_file_id, file_id, self.new_id, file_parents,
+            renew_fileids=renew_fileids)
 
     def _add_file(self, path, copyfrom_path=None, copyfrom_revnum=-1):
         file_id = self.editor._get_new_id(path)
@@ -497,93 +509,98 @@
             old_path = None
         if copyfrom_path is not None:
             # Delta's will be against this text
-            copyfrom_ie = self.editor.get_old_ie(copyfrom_path, copyfrom_revnum)
-            data = self.editor._get_chunked(ie.file_id, ie.revision)
+            base_ie = self.editor.get_old_ie(copyfrom_path, copyfrom_revnum)
         else:
-            data = []
-        return FileRevisionBuildEditor(self.editor, old_path, path, file_id, self.new_id,
-            data=data)
+            base_ie = None
+        return FileRevisionBuildEditor(self.editor, old_path, path, file_id, 
+                                       self.new_id, base_ie)
 
     def _open_file(self, path, base_revnum):
         base_file_id = self.editor._get_old_id(self.old_id, path)
-        base_revid = self.editor.old_inventory[base_file_id].revision
         file_id = self.editor._get_existing_id(self.old_id, self.new_id, path)
         base_ie = self.editor.old_inventory[base_file_id]
         is_symlink = (base_ie.kind == 'symlink')
-        file_data = self.editor._get_chunked(base_file_id, base_revid)
         if file_id == base_file_id:
-            file_parents = [base_revid]
+            file_parents = [base_ie.revision]
             old_path = path
         else:
             # Replace with historical version
             old_path = None
             file_parents = []
             self._delete_entry(path, base_revnum)
-        return FileRevisionBuildEditor(self.editor, old_path, path, file_id, self.new_id, 
-            file_parents, file_data, is_symlink=is_symlink)
+        return FileRevisionBuildEditor(self.editor, old_path, path, file_id, 
+                                       self.new_id, base_ie, file_parents, 
+                                       is_symlink=is_symlink)
+
+
+def content_starts_with_link(cf):
+    # Shortcut for chunked:
+    if cf.storage_kind == "chunked":
+        chks = cf.get_bytes_as("chunked")
+        if not chks:
+            return False
+        if len(chks[0]) >= 5:
+            return chks[0].startswith("link ")
+    return cf.get_bytes_as('fulltext').startswith('link ')
 
 
 class FileRevisionBuildEditor(FileBuildEditor):
 
-    def __init__(self, editor, old_path, path, file_id, parent_file_id, file_parents=[], 
-        data=[], is_symlink=False):
+    def __init__(self, editor, old_path, path, file_id, parent_file_id,
+                 base_ie, file_parents=[], is_symlink=False):
         super(FileRevisionBuildEditor, self).__init__(editor, path)
         self.old_path = old_path
         self.file_id = file_id
         # This should be the *chunks* of the file
-        self.file_data = data
         self.is_symlink = is_symlink
         self.file_parents = file_parents
-        self.file_stream = None
+        self.base_ie = base_ie
+        if self.base_ie is None:
+            self.base_chunks = []
+        else:
+            self.base_chunks = self.editor._get_chunked(self.base_ie)
+        self.chunks = None
         self.parent_file_id = parent_file_id
 
     def _apply_textdelta(self, base_checksum=None):
-        actual_checksum = md5_strings(self.file_data)
-        if base_checksum is not None and base_checksum != actual_checksum:
-            raise VersionedFileInvalidChecksum("base checksum mismatch: %r != %r in %s (%s:%d)" % (base_checksum, actual_checksum, self.editor.revid, self.editor.branch_path, self.editor.revnum))
-        self.file_stream = StringIO()
-        return apply_txdelta_handler_chunks(self.file_data, self.file_stream)
+        if base_checksum is not None:
+            actual_checksum = md5_strings(self.base_chunks)
+            if base_checksum != actual_checksum:
+                raise VersionedFileInvalidChecksum("base checksum mismatch: %r != %r in %s (%s:%d)" % (base_checksum, actual_checksum, self.editor.revid, self.editor.revmeta.branch_path, self.editor.revmeta.revnum))
+        self.chunks = []
+        return apply_txdelta_handler_chunks(self.base_chunks, self.chunks)
 
     def _close(self, checksum=None):
-        if self.file_stream is not None:
-            self.file_stream.seek(0)
-            lines = self.file_stream.readlines()
+        if self.chunks is not None:
+            chunks = self.chunks
         else:
-            # Data didn't change or file is new
-            lines = osutils.chunks_to_lines(self.file_data)
-        actual_checksum = md5_strings(lines)
-        assert checksum is None or checksum == actual_checksum
+            chunks = self.base_chunks
+        md5sum = osutils.md5()
+        shasum = osutils.sha()
+        text_size = 0
+        for chunk in chunks:
+            md5sum.update(chunk)
+            shasum.update(chunk)
+            text_size += len(chunk)
+        text_sha1 = shasum.hexdigest()
+        if checksum is not None:
+            actual_checksum = md5sum.hexdigest()
+            if checksum != actual_checksum:
+                raise VersionedFileInvalidChecksum("created checksum mismatch: %r != %r in %s (%s:%d)" % (checksum, actual_checksum, self.editor.revid, self.editor.revmeta.branch_path, self.editor.revmeta.revnum))
         text_revision = (self.editor._get_text_revision(self.path) or
                          self.editor.revid)
         text_parents = self.editor._get_text_parents(self.path)
         if text_parents is None:
             text_parents = self.file_parents
         parent_keys = tuple([(self.file_id, revid) for revid in text_parents])
-        parent_texts = {}
-        if parent_keys:
-            parent_text = self.editor._content_cache.get(parent_keys[0], None)
-            if parent_text is not None:
-                parent_texts[parent_keys[0]] = parent_text
         file_key = (self.file_id, text_revision)
-        text_sha1, text_size, parent_content = self.editor.texts.add_lines(
-            file_key, parent_keys, lines,
-            parent_texts=parent_texts,
-            random_id=False, 
-            check_content=False, # Can we assume we are always line-safe?
-            )
-        self.editor._text_cache[file_key] = lines
-        if parent_content is not None:
-            # TODO: parent_content is meant to be an opaque structure. However
-            #       if we know the target is a knit or pack repo, we could
-            #       share the _text_cache, rather than creating a new one here.
-            self.editor._content_cache[file_key] = parent_content
+        cf = ChunkedContentFactory(file_key, parent_keys, text_sha1, chunks)
+        self.editor.texts.insert_record_stream([cf])
+        self.editor._text_cache[file_key] = chunks
 
-        content_starts_with_link = False
-        if lines and lines[0].startswith('link '):
-            content_starts_with_link = True
         if self.is_special is not None:
-            self.is_symlink = (self.is_special and content_starts_with_link)
-        elif content_starts_with_link:
+            self.is_symlink = (self.is_special and content_starts_with_link(cf))
+        elif content_starts_with_link(cf):
             # This file just might be a file that is svn:special but didn't
             # contain a symlink but does now
             if not self.is_symlink:
@@ -593,14 +610,12 @@
 
         assert self.is_symlink in (True, False)
 
-        if self.editor.old_inventory.has_id(self.file_id):
-            if self.is_executable is None:
-                self.is_executable = self.editor.old_inventory[self.file_id].executable
+        if self.base_ie is not None and self.is_executable is None:
+                self.is_executable = self.base_ie.executable
 
         if self.is_symlink:
             ie = InventoryLink(self.file_id, urlutils.basename(self.path), self.parent_file_id)
-            fulltext = ''.join(lines)
-            ie.symlink_target = fulltext[len("link "):]
+            ie.symlink_target = cf.get_bytes_as('fulltext')[len("link "):]
             if "\n" in ie.symlink_target:
                 raise AssertionError("bzr doesn't support newlines in symlink targets yet")
             ie.text_sha1 = None
@@ -616,7 +631,7 @@
         ie.revision = text_revision
         self.editor._inv_delta.append((self.old_path, self.path, self.file_id, ie))
 
-        self.file_stream = None
+        self.chunks = None
 
 
 class RevisionBuildEditor(DeltaBuildEditor):
@@ -624,7 +639,7 @@
     Bazaar revision.
     """
     def __init__(self, source, target, revid, prev_inventory, revmeta, mapping,
-                 text_cache, content_cache):
+                 text_cache):
         self.target = target
         self.source = source
         self.texts = target.texts
@@ -632,7 +647,6 @@
         self._text_revids = None
         self._text_parents = None
         self._text_cache = text_cache
-        self._content_cache = content_cache
         self.old_inventory = prev_inventory
         self._inv_delta = []
         self._deleted = set()
@@ -654,25 +668,22 @@
         file_id = inv.path2id(path)
         return inv[file_id]
 
-    def _get_record(self, file_id, revision_id):
-        return self.texts.get_record_stream([(file_id, revision_id)], 'unordered', True).next()
-
-    def _get_chunked(self, file_id, revision_id):
-        file_data = self._text_cache.get((file_id, revision_id))
+    def _get_chunked(self, ie):
+        key = (ie.file_id, ie.revision)
+        file_data = self._text_cache.get(key)
         if file_data is not None: 
             return file_data
-        record = self._get_record(file_id, revision_id)
+        record = self.texts.get_record_stream([key], 'unordered', True).next()
         if record.storage_kind == 'absent':
-            raise RevisionNotPresent(revision_id, file_id)
+            raise RevisionNotPresent(ie.revision, ie.file_id)
         return record.get_bytes_as('chunked')
 
     def _finish_commit(self):
         rev = self.revmeta.get_revision(self.mapping)
         # Escaping the commit message is really the task of the serialiser
-        if rev.message is not None:
-            if getattr(self.target._serializer, "squashes_xml_invalid_characters", True):
-                from bzrlib.xml_serializer import escape_invalid_chars
-                rev.message, num_replaced = escape_invalid_chars(rev.message)
+        if getattr(self.target._serializer, "squashes_xml_invalid_characters", True):
+            from bzrlib.xml_serializer import escape_invalid_chars
+            rev.message, num_replaced = escape_invalid_chars(rev.message)
         try:
             basis_id = rev.parent_ids[0]
         except IndexError:
@@ -977,12 +988,11 @@
         :return: List with revmeta, mapping tuples to fetch
         """
         from_revnum = self.source.get_latest_revnum()
-        return self.find_iter_revisions(
-            self.source._revmeta_provider.iter_all_revisions(
+        all_revs = self.source._revmeta_provider.iter_all_revisions(
                 self.source.get_layout(), 
                 check_unusual_path=mapping.is_branch_or_tag,
-                from_revnum=from_revnum, pb=pb), mapping,
-            lambda x: False)
+                from_revnum=from_revnum, pb=pb)
+        return self.find_iter_revisions(all_revs, mapping, lambda x: False)
 
     def find_mainline(self, foreign_revid, mapping, find_ghosts=False,
                       pb=None):
@@ -1051,14 +1061,10 @@
 
     def __init__(self, source, target):
         super(InterFromSvnRepository, self).__init__(source, target)
-        def lines_to_size(lines):
-            return sum(map(len, lines))
+        def chunks_to_size(chunks):
+            return sum(map(len, chunks))
         self._text_cache = lru_cache.LRUSizeCache(TEXT_CACHE_SIZE,
-                                                  compute_size=lines_to_size)
-        # TODO: it would be nice to get rid of this extra cache, we don't
-        # (yet) because the cached content objects are supposed to be opaque
-        self._content_cache = lru_cache.LRUCache(TEXT_CACHE_SIZE /
-                                                 (1*1024*1024))
+                                                  compute_size=chunks_to_size)
 
         self._use_replay_range = self.source.transport.has_capability("partial-replay") and False
         self._use_replay = self.source.transport.has_capability("partial-replay") and False
@@ -1095,7 +1101,7 @@
         try:
             return RevisionBuildEditor(self.source, self.target, revid, 
                 self._get_inventory(revmeta.get_lhs_parent_revid(mapping)), 
-                revmeta, mapping, self._text_cache, self._content_cache)
+                revmeta, mapping, self._text_cache)
         except NoSuchRevision:
             lhs_parent_revmeta = revmeta.get_lhs_parent_revmeta(mapping)
             expected_lhs_parent_revid = revmeta.get_implicit_lhs_parent_revid(mapping)
@@ -1199,7 +1205,7 @@
                 self._prev_inv = editor.inventory
                 assert self._prev_inv.revision_id == revid
         finally:
-            self.target.commit_write_group()
+            return self.target.commit_write_group()
 
     def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
               needed=None, mapping=None, project=None, fetch_spec=None):
@@ -1254,10 +1260,12 @@
                 nested_pb = None
             try:
                 if self._use_replay_range:
-                    self._fetch_revision_chunks(needed, pb)
+                    pack_hint = self._fetch_revision_chunks(needed, pb)
                 else:
-                    self._fetch_revisions(needed, pb,
+                    pack_hint = self._fetch_revisions(needed, pb,
                         use_replay=self._use_replay)
+                if pack_hint is not None and self.target._format.pack_compresses:
+                    self.target.pack(hint=pack_hint)
             finally:
                 if nested_pb is not None:
                     nested_pb.finished()
@@ -1321,7 +1329,7 @@
                     if not conn.busy:
                         self.source.transport.add_connection(conn)
         finally:
-            self.target.commit_write_group()
+            return self.target.commit_write_group()
 
     @staticmethod
     def is_compatible(source, target):

=== modified file 'layout/__init__.py'
--- a/layout/__init__.py	2009-06-11 21:15:27 +0000
+++ b/layout/__init__.py	2009-07-02 22:53:59 +0000
@@ -233,39 +233,37 @@
 
 help_layout = """Subversion repository layouts.
 
-Subversion is basically a versioned file system. It does not have 
-any notion of branches and what is a branch in Subversion is therefor
-up to the user. 
-
-In order for Bazaar to access a Subversion repository it has to know 
-what paths to consider branches. What it will and will not consider 
-a branch or tag is defined by the repository layout.
-When you connect to a repository for the first time, Bazaar
-will try to determine the layout to use using some simple 
-heuristics. It is always possible to change the branching scheme it should 
-use later.
-
-There are some conventions in use in Subversion for repository layouts. 
-The most common one is probably the trunk/branches/tags 
-layout, where the repository contains a "trunk" directory with the main 
-development branch, other branches in a "branches" directory and tags as 
-subdirectories of a "tags" directory. This layout is named 
-"trunk" in Bazaar.
-
-Another option is simply having just one branch at the root of the repository. 
-This scheme is called "root" by Bazaar.
-
-The layout bzr-svn should use for a repository can be set in the 
-configuration file ~/.bazaar/subversion.conf. If you have a custom 
-repository, you can set the "branches" and "tags" variables. These variables 
-can contain asterisks. Multiple locations can be separated by a semicolon. 
-For example:
+Subversion is basically a versioned file system. It does not have any notion of
+branches and what is a branch in Subversion is therefor up to the user. 
+
+In order for Bazaar to access a Subversion repository it has to know what paths
+to consider branches. What it will and will not consider a branch or tag is
+defined by the repository layout.  When you connect to a repository for the
+first time, Bazaar will try to determine the layout to use using some simple
+heuristics. It is always possible to change the repository layout it should use
+later.
+
+There are some conventions in use in Subversion for repository layouts.  The
+most common one is probably the trunk/branches/tags layout, where the
+repository contains a "trunk" directory with the main development branch, other
+branches in a "branches" directory and tags as subdirectories of a "tags"
+directory. This layout is named "trunk" in Bazaar.
+
+Another option is simply having just one branch at the root of the repository.
+This layout is called "root" by Bazaar.
+
+The layout bzr-svn should use for a repository can be set in the configuration
+file ~/.bazaar/subversion.conf. If you have a custom repository, you can set
+the "branches" and "tags" variables. These variables can contain asterisks.
+Multiple locations can be separated by a semicolon.  For example:
 
 [203ae883-c723-44c9-aabd-cb56e4f81c9a]
 branches = path/to/*/bla;path/to/trunk
 
 This would consider paths path/to/foo/bla, path/to/blie/bla and path/to/trunk 
-branches, if they existed.
+branches, if they existed. The key used (203a...) is the UUID of the Subversion
+repository. The UUID for a repository can be found by running "svn info <url>" 
+or "bzr info <url>".
 
 """
 

=== modified file 'layout/standard.py'
--- a/layout/standard.py	2009-06-11 21:15:27 +0000
+++ b/layout/standard.py	2009-06-19 00:41:52 +0000
@@ -299,14 +299,14 @@
 
         :result: Iterator over tuples with (project, branch path)
         """
-        return [(project, b, b.split("/")[-1]) for b in self.branches if repository.transport.check_path(b, revnum) == NODE_DIR]
+        return [(project, b, b.split("/")[-1], None) for b in self.branches if repository.transport.check_path(b, revnum) == NODE_DIR]
 
     def get_tags(self, repository, revnum, project=None, pb=None):
         """Retrieve a list of paths that refer to tags in a specific revision.
 
         :result: Iterator over tuples with (project, branch path)
         """
-        return [(project, t, t.split("/")[-1]) for t in self.tags if repository.transport.check_path(t, revnum) == NODE_DIR]
+        return [(project, t, t.split("/")[-1], None) for t in self.tags if repository.transport.check_path(t, revnum) == NODE_DIR]
 
     def __repr__(self):
         return "%s(%r,%r)" % (self.__class__.__name__, self.branches, self.tags)

=== modified file 'mapping.py'
--- a/mapping.py	2009-06-18 13:33:41 +0000
+++ b/mapping.py	2009-07-17 11:26:31 +0000
@@ -197,7 +197,7 @@
 
 def parse_svn_log(log):
     if log is None:
-        return None
+        return ""
     try:
         return log.decode("utf-8")
     except UnicodeDecodeError:

=== modified file 'mapping3/__init__.py'
--- a/mapping3/__init__.py	2009-03-07 01:34:15 +0000
+++ b/mapping3/__init__.py	2009-07-17 11:26:31 +0000
@@ -13,34 +13,4 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-help_schemes = """Subversion Branching Schemes
-
-Subversion is basically a versioned file system. It does not have 
-any notion of branches and what is a branch in Subversion is therefor
-up to the user. 
-
-In order for Bazaar to access a Subversion repository it has to know 
-what paths to consider branches. It does this by using so-called branching 
-schemes. When you connect to a repository for the first time, Bazaar
-will try to determine the branching scheme to use using some simple 
-heuristics. It is always possible to change the branching scheme it should 
-use later.
-
-There are some conventions in use in Subversion for repository layouts. 
-The most common one is probably the trunk/branches/tags 
-layout, where the repository contains a "trunk" directory with the main 
-development branch, other branches in a "branches" directory and tags as 
-subdirectories of a "tags" directory. This branching scheme is named 
-"trunk" in Bazaar.
-
-Another option is simply having just one branch at the root of the repository. 
-This scheme is called "none" by Bazaar.
-
-The branching scheme bzr-svn should use for a repository can be set in the 
-configuration file ~/.bazaar/subversion.conf.
-
-Branching schemes are only used for version 3 of the Bzr<->Svn mappings.
-"""
-
-
 

=== modified file 'setup.py'
--- a/setup.py	2009-05-22 17:10:23 +0000
+++ b/setup.py	2009-06-18 13:23:43 +0000
@@ -5,7 +5,7 @@
 from distutils.core import setup
 import os, sys
 
-version = (0, 6, 2)
+version = (0, 6, 3)
 version_string = ".".join([str(x) for x in version])
 
 setup(name='bzr-svn',

=== modified file 'tests/__init__.py'
--- a/tests/__init__.py	2009-06-01 14:59:02 +0000
+++ b/tests/__init__.py	2009-07-17 11:26:31 +0000
@@ -16,9 +16,7 @@
 
 """Tests for the bzr-svn plugin."""
 
-import os
 import subvertpy.tests
-import sys
 
 
 from bzrlib import (
@@ -32,11 +30,15 @@
     TestCaseInTempDir,
     )
 
+from bzrlib.plugins.svn.transport import (
+    svn_to_bzr_url,
+    )
+
 
 class SubversionTestCase(subvertpy.tests.SubversionTestCase,TestCaseInTempDir):
 
     def make_repository(self, *args, **kwargs):
-        return subvertpy.tests.SubversionTestCase.make_repository(self, *args, **kwargs)
+        return svn_to_bzr_url(subvertpy.tests.SubversionTestCase.make_repository(self, *args, **kwargs))
 
     def setUp(self):
         subvertpy.tests.SubversionTestCase.setUp(self)

=== modified file 'tests/test_blackbox.py'
--- a/tests/test_blackbox.py	2009-06-18 13:33:41 +0000
+++ b/tests/test_blackbox.py	2009-07-17 11:26:31 +0000
@@ -111,11 +111,8 @@
         self.build_tree({"dc/foo": "blaaaa"})
         self.run_bzr("add dc/foo")
         self.run_bzr("commit -m msg dc")
-        self.run_bzr_error([
-            # Ideally this should say:
-            # ['ERROR: Empty branch already exists at /trunk. Specify --overwrite or remove it before pushing.\n'
-             'ERROR: These branches have diverged.  Try using "merge" and then "push".\n'
-            ], ["push", "-d", "dc", "%s/trunk" % repos_url])
+        output, err = self.run_bzr("push -d dc %s/trunk" % repos_url, retcode=3)
+        self.assertTrue(('ERROR: These branches have diverged.  See "bzr help diverged-branches" for more information.\n' in err) or ('ERROR: These branches have diverged.  Try using "merge" and then "push".\n' in err))
 
     def test_dpush_empty_existing(self):
         repos_url = self.make_repository('d')

=== modified file 'tests/test_cache.py'
--- a/tests/test_cache.py	2009-06-01 14:51:51 +0000
+++ b/tests/test_cache.py	2009-06-20 15:20:05 +0000
@@ -79,7 +79,7 @@
         try:
             from bzrlib.plugins.svn.cache.tdbcache import LogCache, tdb_open
         except ImportError:
-            raise UnavailableFeature
+            raise UnavailableFeature("tdb")
         import tdb
         self.cache = LogCache(tdb_open("cache.tdb", 0, tdb.DEFAULT, os.O_RDWR|os.O_CREAT))
 
@@ -134,7 +134,7 @@
         try:
             from bzrlib.plugins.svn.cache.tdbcache import RevisionIdMapCache, tdb_open
         except ImportError:
-            raise UnavailableFeature
+            raise UnavailableFeature("tdb")
         import tdb
         self.cache = RevisionIdMapCache(tdb_open("cache.tdb", 0, tdb.DEFAULT, os.O_RDWR|os.O_CREAT))
 
@@ -191,7 +191,7 @@
         try:
             from bzrlib.plugins.svn.cache.tdbcache import RevisionInfoCache, tdb_open
         except ImportError:
-            raise UnavailableFeature
+            raise UnavailableFeature("tdb")
         import tdb
         self.cache = RevisionInfoCache(tdb_open("cache.tdb", 0, tdb.DEFAULT, os.O_RDWR|os.O_CREAT))
 
@@ -234,6 +234,6 @@
         try:
             from bzrlib.plugins.svn.cache.tdbcache import ParentsCache, tdb_open
         except ImportError:
-            raise UnavailableFeature
+            raise UnavailableFeature("tdb")
         import tdb
         self.cache = ParentsCache(tdb_open("cache.tdb", 0, tdb.DEFAULT, os.O_RDWR|os.O_CREAT))

=== modified file 'tests/test_layout.py'
--- a/tests/test_layout.py	2009-05-22 01:01:26 +0000
+++ b/tests/test_layout.py	2009-06-19 00:41:52 +0000
@@ -13,6 +13,8 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import subvertpy
+
 from bzrlib.tests import (
     TestCase,
     )
@@ -145,3 +147,21 @@
         x = CustomLayout(["foo/bar"])
         self.assertFalse(x.is_branch_parent("foo/bar"))
         self.assertTrue(x.is_branch_parent("foo"))
+
+    def test_get_branches(self):
+        x = CustomLayout(["foo/bar"])
+        class MockTransport(object):
+
+            def __init__(self, available_paths):
+                self._paths = available_paths
+
+            def check_path(self, path, revnum):
+                return self._paths.get(path, subvertpy.NODE_NONE)
+
+        class MockRepository(object):
+
+            def __init__(self, available_paths):
+                self.transport = MockTransport(available_paths)
+
+        self.assertEquals([(None, "foo/bar", "bar", None)],
+            x.get_branches(MockRepository({"foo/bar": subvertpy.NODE_DIR}), 3))

=== modified file 'tests/test_repository.py'
--- a/tests/test_repository.py	2009-05-20 16:19:35 +0000
+++ b/tests/test_repository.py	2009-07-17 11:26:31 +0000
@@ -63,7 +63,7 @@
 
         repos = Repository.open(self.repos_url)
 
-        self.assertEqual("SvnRepository('%s/')" % urlutils.local_path_to_url(urlutils.join(self.test_dir, "a")), repos.__repr__())
+        self.assertEqual("SvnRepository('%s')" % urlutils.local_path_to_url(urlutils.join(self.test_dir, "a")), repos.__repr__())
 
     def test_gather_stats(self):
         repos = Repository.open(self.repos_url)

=== modified file 'transport.py'
--- a/transport.py	2009-06-18 13:33:41 +0000
+++ b/transport.py	2009-07-17 11:26:31 +0000
@@ -21,6 +21,7 @@
 import subvertpy
 from subvertpy import ERR_FS_NOT_DIRECTORY
 from subvertpy.client import get_config
+import sys
 import urlparse
 import urllib
 
@@ -89,9 +90,7 @@
     if ra_transport is not None:
         return ra_transport
 
-    svnbase = bzr_transport.external_url()
-    if svnbase.startswith("readonly+"):
-        svnbase = svnbase[len("readonly+"):]
+    svnbase = bzr_to_svn_url(bzr_transport.external_url())
     # If this is a HTTP transport, use the existing connection to check 
     # that the remote end supports version control.
     from bzrlib.transport.http._urllib import HttpTransport_urllib, Request
@@ -149,6 +148,9 @@
 
     This will possibly remove the svn+ prefix.
     """
+    if url.startswith("readonly+"):
+        url = url[len("readonly+"):]
+
     if (url.startswith("svn+http://") or 
         url.startswith("svn+https://")):
         url = url[len("svn+"):] # Skip svn+
@@ -161,6 +163,18 @@
     return url
 
 
+def svn_to_bzr_url(url):
+    """Convert a Subversion URL to a URL understood by Bazaar.
+
+    This mainly involves fixing file:// URLs on Windows.
+    """
+    if sys.platform == "win32":
+        # Subversion URLs have only two // after file: on Windows
+        if url.startswith("file://"):
+            url = "file:///" + url[len("file://"):]
+    return url
+
+
 class SubversionProgressReporter(object):
 
     def __init__(self, url):



More information about the Pkg-bazaar-commits mailing list