Rev 4415: Merge bzr.dev 4409, resolve NEWS in lp:///~jameinel/bzr/bencode_serializer

John Arbash Meinel john at arbash-meinel.com
Thu Jun 4 22:26:06 BST 2009


At lp:///~jameinel/bzr/bencode_serializer

------------------------------------------------------------
revno: 4415 [merge]
revision-id: john at arbash-meinel.com-20090604212546-dpmrzvg49q40tvnj
parent: john at arbash-meinel.com-20090604212302-7369sr8it1i2kxhs
parent: pqm at pqm.ubuntu.com-20090604210544-x6j63s03knqk7qfg
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bencode_serializer
timestamp: Thu 2009-06-04 16:25:46 -0500
message:
  Merge bzr.dev 4409, resolve NEWS
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
  bzrlib/inventory.py            inventory.py-20050309040759-6648b84ca2005b37
  bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
  bzrlib/reconcile.py            reweave_inventory.py-20051108164726-1e5e0934febac06e
  bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/serializer.py           serializer.py-20090402143702-wmkh9cfjhwpju0qi-1
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
  bzrlib/tests/blackbox/test_export.py test_export.py-20051229024010-e6c26658e460fb1c
  bzrlib/tests/branch_implementations/test_check.py test_check.py-20080429151303-1sbfclxhddpz0tnj-1
  bzrlib/tests/branch_implementations/test_reconcile.py test_reconcile.py-20080429161555-qlmccuyeyt6pvho7-1
  bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
  bzrlib/tests/inventory_implementations/basics.py basics.py-20070903044446-kdjwbiu1p1zi9phs-1
  bzrlib/tests/per_repository/test_iter_reverse_revision_history.py test_iter_reverse_re-20070217015036-spu7j5ggch7pbpyd-1
  bzrlib/tests/per_repository/test_reconcile.py test_reconcile.py-20060223022332-572ef70a3288e369
  bzrlib/tests/per_repository_reference/test_initialize.py test_initialize.py-20090527083941-4rz2urcthjet5e2i-1
  bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/tests/test_serializer.py test_serializer.py-20090403213933-q6x117y8t9fbeyoz-1
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-06-04 21:23:02 +0000
+++ b/NEWS	2009-06-04 21:25:46 +0000
@@ -24,6 +24,9 @@
   but using a Revision serializer using bencode rather than XML.
   (Jelmer Vernooij, John Arbash Meinel)
 
+* mail_client=claws now supports --body (and message body hooks).  Also uses
+  configured from address.  (Barry Warsaw)
+
 
 Improvements
 ************
@@ -66,6 +69,22 @@
   the fetched revisions, not in the stacked-on ancestry.
   (John Arbash Meinel)
 
+* Reconcile can now deal with text revisions that originated in revisions 
+  that are ghosts. (Jelmer Vernooij, #336749)
+
+* Support cloning of branches with ghosts in the left hand side history.
+  (Jelmer Vernooij, #248540)
+
+* The ''bzr diff'' now catches OSError from osutils.rmtree and logs a
+  helpful message to the trace file, unless the temp directory really was
+  removed (which would be very strange).  Since the diff operation has
+  succeeded from the user's perspective, no output is written to stderr 
+  or stdout.  (Maritza Mendez, #363837)
+
+* Translate errors received from a smart server in response to a
+  ``BzrDirFormat.initialize`` or ``BzrDirFormat.initialize_ex`` request.
+  This was causing tracebacks even for mundane errors like
+  ``PermissionDenied``.  (Andrew Bennetts, #381329)
 
 Documentation
 *************
@@ -85,6 +104,8 @@
 Testing
 *******
 
+* The number of cores is now correctly detected on OSX. (John Szakmeister)
+
 
 bzr 1.15
 ########

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2009-05-29 10:25:37 +0000
+++ b/bzrlib/branch.py	2009-06-03 21:31:43 +0000
@@ -1085,18 +1085,14 @@
         source_revno, source_revision_id = self.last_revision_info()
         if revision_id is None:
             revno, revision_id = source_revno, source_revision_id
-        elif source_revision_id == revision_id:
-            # we know the revno without needing to walk all of history
-            revno = source_revno
         else:
-            # To figure out the revno for a random revision, we need to build
-            # the revision history, and count its length.
-            # We don't care about the order, just how long it is.
-            # Alternatively, we could start at the current location, and count
-            # backwards. But there is no guarantee that we will find it since
-            # it may be a merged revision.
-            revno = len(list(self.repository.iter_reverse_revision_history(
-                                                                revision_id)))
+            graph = self.repository.get_graph()
+            try:
+                revno = graph.find_distance_to_null(revision_id, 
+                    [(source_revision_id, source_revno)])
+            except errors.GhostRevisionsHaveNoRevno:
+                # Default to 1, if we can't find anything else
+                revno = 1
         destination.set_last_revision_info(revno, revision_id)
 
     @needs_read_lock
@@ -1147,10 +1143,18 @@
 
         :return: A BranchCheckResult.
         """
+        ret = BranchCheckResult(self)
         mainline_parent_id = None
         last_revno, last_revision_id = self.last_revision_info()
-        real_rev_history = list(self.repository.iter_reverse_revision_history(
-                                last_revision_id))
+        real_rev_history = []
+        try:
+            for revid in self.repository.iter_reverse_revision_history(
+                last_revision_id):
+                real_rev_history.append(revid)
+        except errors.RevisionNotPresent:
+            ret.ghosts_in_mainline = True
+        else:
+            ret.ghosts_in_mainline = False
         real_rev_history.reverse()
         if len(real_rev_history) != last_revno:
             raise errors.BzrCheckError('revno does not match len(mainline)'
@@ -1172,7 +1176,7 @@
                                         "parents of {%s}"
                                         % (mainline_parent_id, revision_id))
             mainline_parent_id = revision_id
-        return BranchCheckResult(self)
+        return ret
 
     def _get_checkout_format(self):
         """Return the most suitable metadir for a checkout of this branch.
@@ -2780,6 +2784,7 @@
 
     def __init__(self, branch):
         self.branch = branch
+        self.ghosts_in_mainline = False
 
     def report_results(self, verbose):
         """Report the check results via trace.note.
@@ -2790,6 +2795,8 @@
         note('checked branch %s format %s',
              self.branch.base,
              self.branch._format)
+        if self.ghosts_in_mainline:
+            note('branch contains ghosts in mainline')
 
 
 class Converter5to6(object):

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2009-06-03 01:43:22 +0000
+++ b/bzrlib/bzrdir.py	2009-06-04 21:25:46 +0000
@@ -2358,26 +2358,95 @@
     def set_branch_format(self, format):
         self._branch_format = format
 
-    def require_stacking(self):
+    def require_stacking(self, stack_on=None, possible_transports=None):
+        """We have a request to stack, try to ensure the formats support it.
+
+        :param stack_on: If supplied, it is the URL to a branch that we want to
+            stack on. Check to see if that format supports stacking before
+            forcing an upgrade.
+        """
+        # Stacking is desired. requested by the target, but does the place it
+        # points at support stacking? If it doesn't then we should
+        # not implicitly upgrade. We check this here.
+        new_repo_format = None
+        new_branch_format = None
+
+        # a bit of state for get_target_branch so that we don't try to open it
+        # 2 times, for both repo *and* branch
+        target = [None, False, None] # target_branch, checked, upgrade anyway
+        def get_target_branch():
+            if target[1]:
+                # We've checked, don't check again
+                return target
+            if stack_on is None:
+                # No target format, that means we want to force upgrading
+                target[:] = [None, True, True]
+                return target
+            try:
+                target_dir = BzrDir.open(stack_on,
+                    possible_transports=possible_transports)
+            except errors.NotBranchError:
+                # Nothing there, don't change formats
+                target[:] = [None, True, False]
+                return target
+            except errors.JailBreak:
+                # JailBreak, JFDI and upgrade anyway
+                target[:] = [None, True, True]
+                return target
+            try:
+                target_branch = target_dir.open_branch()
+            except errors.NotBranchError:
+                # No branch, don't upgrade formats
+                target[:] = [None, True, False]
+                return target
+            target[:] = [target_branch, True, False]
+            return target
+
+        if not (self.repository_format.supports_external_lookups):
+            # We need to upgrade the Repository.
+            target_branch, _, do_upgrade = get_target_branch()
+            if target_branch is None:
+                # We don't have a target branch, should we upgrade anyway?
+                if do_upgrade:
+                    # stack_on is inaccessible, JFDI.
+                    # TODO: bad monkey, hard-coded formats...
+                    if self.repository_format.rich_root_data:
+                        new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
+                    else:
+                        new_repo_format = pack_repo.RepositoryFormatKnitPack5()
+            else:
+                # If the target already supports stacking, then we know the
+                # project is already able to use stacking, so auto-upgrade
+                # for them
+                new_repo_format = target_branch.repository._format
+                if not new_repo_format.supports_external_lookups:
+                    # target doesn't, source doesn't, so don't auto upgrade
+                    # repo
+                    new_repo_format = None
+            if new_repo_format is not None:
+                self.repository_format = new_repo_format
+                note('Source repository format does not support stacking,'
+                     ' using format:\n  %s',
+                     new_repo_format.get_format_description())
+
         if not self.get_branch_format().supports_stacking():
-            # We need to make a stacked branch, but the default format for the
-            # target doesn't support stacking.  So force a branch that *can*
-            # support stacking.
-            from bzrlib.branch import BzrBranchFormat7
-            branch_format = BzrBranchFormat7()
-            self.set_branch_format(branch_format)
-            mutter("using %r for stacking" % (branch_format,))
-            from bzrlib.repofmt import pack_repo
-            if self.repository_format.rich_root_data:
-                bzrdir_format_name = '1.6.1-rich-root'
-                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
+            # We just checked the repo, now lets check if we need to
+            # upgrade the branch format
+            target_branch, _, do_upgrade = get_target_branch()
+            if target_branch is None:
+                if do_upgrade:
+                    # TODO: bad monkey, hard-coded formats...
+                    new_branch_format = branch.BzrBranchFormat7()
             else:
-                bzrdir_format_name = '1.6'
-                repo_format = pack_repo.RepositoryFormatKnitPack5()
-            note('Source format does not support stacking, using format:'
-                 ' \'%s\'\n  %s\n',
-                 bzrdir_format_name, repo_format.get_format_description())
-            self.repository_format = repo_format
+                new_branch_format = target_branch._format
+                if not new_branch_format.supports_stacking():
+                    new_branch_format = None
+            if new_branch_format is not None:
+                # Does support stacking, use its format.
+                self.set_branch_format(new_branch_format)
+                note('Source branch format does not support stacking,'
+                     ' using format:\n  %s',
+                     new_branch_format.get_format_description())
 
     def get_converter(self, format=None):
         """See BzrDirFormat.get_converter()."""
@@ -3049,7 +3118,10 @@
             return local_dir_format.initialize_on_transport(transport)
         client = _SmartClient(client_medium)
         path = client.remote_path_from_transport(transport)
-        response = client.call('BzrDirFormat.initialize', path)
+        try:
+            response = client.call('BzrDirFormat.initialize', path)
+        except errors.ErrorFromSmartServer, err:
+            remote._translate_error(err, path=path)
         if response[0] != 'ok':
             raise errors.SmartProtocolError('unexpected response code %s' % (response,))
         format = RemoteBzrDirFormat()
@@ -3115,6 +3187,13 @@
                 stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
                 make_working_trees=make_working_trees, shared_repo=shared_repo,
                 vfs_only=True)
+        return self._initialize_on_transport_ex_rpc(client, path, transport,
+            use_existing_dir, create_prefix, force_new_repo, stacked_on,
+            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
+
+    def _initialize_on_transport_ex_rpc(self, client, path, transport,
+        use_existing_dir, create_prefix, force_new_repo, stacked_on,
+        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
         args = []
         args.append(self._serialize_NoneTrueFalse(use_existing_dir))
         args.append(self._serialize_NoneTrueFalse(create_prefix))
@@ -3147,6 +3226,8 @@
                 stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
                 make_working_trees=make_working_trees, shared_repo=shared_repo,
                 vfs_only=True)
+        except errors.ErrorFromSmartServer, err:
+            remote._translate_error(err, path=path)
         repo_path = response[0]
         bzrdir_name = response[6]
         require_stacking = response[7]
@@ -3520,54 +3601,9 @@
         """
         stack_on = self._get_full_stack_on()
         if stack_on:
-            # Stacking is desired. requested by the target, but does the place it
-            # points at support stacking? If it doesn't then we should
-            # not implicitly upgrade. We check this here.
             format = self._bzrdir._format
-            if not (format.repository_format.supports_external_lookups
-                and format.get_branch_format().supports_stacking()):
-                # May need to upgrade - but only do if the target also
-                # supports stacking. Note that this currently wastes
-                # network round trips to check - but we only do this
-                # when the source can't stack so it will fade away
-                # as people do upgrade.
-                branch_format = None
-                repo_format = None
-                try:
-                    target_dir = BzrDir.open(stack_on,
-                        possible_transports=[self._bzrdir.root_transport])
-                except errors.NotBranchError:
-                    # Nothing there, don't change formats
-                    pass
-                except errors.JailBreak:
-                    # stack_on is inaccessible, JFDI.
-                    if format.repository_format.rich_root_data:
-                        repo_format = pack_repo.RepositoryFormatKnitPack6RichRoot()
-                    else:
-                        repo_format = pack_repo.RepositoryFormatKnitPack6()
-                    branch_format = branch.BzrBranchFormat7()
-                else:
-                    try:
-                        target_branch = target_dir.open_branch()
-                    except errors.NotBranchError:
-                        # No branch, don't change formats
-                        pass
-                    else:
-                        branch_format = target_branch._format
-                        repo_format = target_branch.repository._format
-                        if not (branch_format.supports_stacking()
-                            and repo_format.supports_external_lookups):
-                            # Doesn't stack itself, don't force an upgrade
-                            branch_format = None
-                            repo_format = None
-                if branch_format and repo_format:
-                    # Does support stacking, use its format.
-                    format.repository_format = repo_format
-                    format.set_branch_format(branch_format)
-                    note('Source format does not support stacking, '
-                        'using format: \'%s\'\n  %s\n',
-                        branch_format.get_format_description(),
-                        repo_format.get_format_description())
+            format.require_stacking(stack_on=stack_on,
+                                    possible_transports=[self._bzrdir.root_transport])
             if not self._require_stacking:
                 # We have picked up automatic stacking somewhere.
                 note('Using default stacking branch %s at %s', self._stack_on,

=== modified file 'bzrlib/diff.py'
--- a/bzrlib/diff.py	2009-05-27 07:18:20 +0000
+++ b/bzrlib/diff.py	2009-06-03 05:44:18 +0000
@@ -735,7 +735,12 @@
         return old_disk_path, new_disk_path
 
     def finish(self):
-        osutils.rmtree(self._root)
+        try:
+            osutils.rmtree(self._root)
+        except OSError, e:
+            if e.errno != errno.ENOENT:
+                mutter("The temporary directory \"%s\" was not "
+                        "cleanly removed: %s." % (self._root, e))
 
     def diff(self, file_id, old_path, new_path, old_kind, new_kind):
         if (old_kind, new_kind) != ('file', 'file'):

=== modified file 'bzrlib/inventory.py'
--- a/bzrlib/inventory.py	2009-05-26 10:08:17 +0000
+++ b/bzrlib/inventory.py	2009-06-02 23:53:06 +0000
@@ -747,8 +747,13 @@
             [parent.name for parent in
              self._iter_file_id_parents(file_id)][:-1]))
 
-    def iter_entries(self, from_dir=None):
-        """Return (path, entry) pairs, in order by name."""
+    def iter_entries(self, from_dir=None, recursive=True):
+        """Return (path, entry) pairs, in order by name.
+        
+        :param from_dir: if None, start from the root,
+          otherwise start from this directory (either file-id or entry)
+        :param recursive: recurse into directories or not
+        """
         if from_dir is None:
             if self.root is None:
                 return
@@ -761,6 +766,10 @@
         # 440ms/663ms (inline/total) to 116ms/116ms
         children = from_dir.children.items()
         children.sort()
+        if not recursive:
+            for name, ie in children:
+                yield name, ie
+            return
         children = collections.deque(children)
         stack = [(u'', children)]
         while stack:

=== modified file 'bzrlib/mail_client.py'
--- a/bzrlib/mail_client.py	2009-05-11 18:35:20 +0000
+++ b/bzrlib/mail_client.py	2009-06-04 21:05:44 +0000
@@ -155,7 +155,7 @@
                       extension, **kwargs)
 
     def _compose(self, prompt, to, subject, attach_path, mime_subtype,
-                extension, body=None):
+                 extension, body=None, from_=None):
         """Invoke a mail client as a commandline process.
 
         Overridden by MAPIClient.
@@ -166,6 +166,8 @@
             "text", but the precise subtype can be specified here
         :param extension: A file extension (including period) associated with
             the attachment type.
+        :param body: Optional body text.
+        :param from_: Optional From: header.
         """
         for name in self._get_client_commands():
             cmdline = [self._encode_path(name, 'executable')]
@@ -173,6 +175,8 @@
                 kwargs = {'body': body}
             else:
                 kwargs = {}
+            if from_ is not None:
+                kwargs['from_'] = from_
             cmdline.extend(self._get_compose_commandline(to, subject,
                                                          attach_path,
                                                          **kwargs))
@@ -331,25 +335,45 @@
 class Claws(ExternalMailClient):
     """Claws mail client."""
 
+    supports_body = True
+
     _client_commands = ['claws-mail']
 
-    def _get_compose_commandline(self, to, subject, attach_path):
+    def _get_compose_commandline(self, to, subject, attach_path, body=None,
+                                 from_=None):
         """See ExternalMailClient._get_compose_commandline"""
-        compose_url = ['mailto:']
-        if to is not None:
-            compose_url.append(self._encode_safe(to))
-        compose_url.append('?')
+        compose_url = []
+        if from_ is not None:
+            compose_url.append('from=' + urllib.quote(from_))
         if subject is not None:
             # Don't use urllib.quote_plus because Claws doesn't seem
             # to recognise spaces encoded as "+".
             compose_url.append(
-                'subject=%s' % urllib.quote(self._encode_safe(subject)))
+                'subject=' + urllib.quote(self._encode_safe(subject)))
+        if body is not None:
+            compose_url.append(
+                'body=' + urllib.quote(self._encode_safe(body)))
+        # to must be supplied for the claws-mail --compose syntax to work.
+        if to is None:
+            raise errors.NoMailAddressSpecified()
+        compose_url = 'mailto:%s?%s' % (
+            self._encode_safe(to), '&'.join(compose_url))
         # Collect command-line options.
-        message_options = ['--compose', ''.join(compose_url)]
+        message_options = ['--compose', compose_url]
         if attach_path is not None:
             message_options.extend(
                 ['--attach', self._encode_path(attach_path, 'attachment')])
         return message_options
+
+    def _compose(self, prompt, to, subject, attach_path, mime_subtype,
+                 extension, body=None, from_=None):
+        """See ExternalMailClient._compose"""
+        if from_ is None:
+            from_ = self.config.get_user_option('email')
+        super(Claws, self)._compose(prompt, to, subject, attach_path,
+                                    mime_subtype, extension, body, from_)
+
+
 mail_client_registry.register('claws', Claws,
                               help=Claws.__doc__)
 
@@ -506,6 +530,8 @@
     """Default mail handling.  Tries XDGEmail (or MAPIClient on Windows),
     falls back to Editor"""
 
+    supports_body = True
+
     def _mail_client(self):
         """Determine the preferred mail client for this platform"""
         if osutils.supports_mapi():

=== modified file 'bzrlib/reconcile.py'
--- a/bzrlib/reconcile.py	2009-04-09 20:23:07 +0000
+++ b/bzrlib/reconcile.py	2009-06-02 01:27:37 +0000
@@ -137,8 +137,13 @@
     def _reconcile_revision_history(self):
         repo = self.branch.repository
         last_revno, last_revision_id = self.branch.last_revision_info()
-        real_history = list(repo.iter_reverse_revision_history(
-                                last_revision_id))
+        real_history = []
+        try:
+            for revid in repo.iter_reverse_revision_history(
+                    last_revision_id):
+                real_history.append(revid)
+        except errors.RevisionNotPresent:
+            pass # Hit a ghost left hand parent
         real_history.reverse()
         if last_revno != len(real_history):
             self.fixed_history = True

=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py	2009-05-28 09:35:53 +0000
+++ b/bzrlib/repofmt/pack_repo.py	2009-06-03 21:28:52 +0000
@@ -1306,7 +1306,7 @@
         # space (we only topo sort the revisions, which is smaller).
         topo_order = tsort.topo_sort(ancestors)
         rev_order = dict(zip(topo_order, range(len(topo_order))))
-        bad_texts.sort(key=lambda key:rev_order[key[0][1]])
+        bad_texts.sort(key=lambda key:rev_order.get(key[0][1], 0))
         transaction = repo.get_transaction()
         file_id_index = GraphIndexPrefixAdapter(
             self.new_pack.text_index,

=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2009-06-03 01:43:22 +0000
+++ b/bzrlib/repository.py	2009-06-04 21:25:46 +0000
@@ -2245,13 +2245,11 @@
         while True:
             if next_id in (None, _mod_revision.NULL_REVISION):
                 return
+            try:
+                parents = graph.get_parent_map([next_id])[next_id]
+            except KeyError:
+                raise errors.RevisionNotPresent(next_id, self)
             yield next_id
-            # Note: The following line may raise KeyError in the event of
-            # truncated history. We decided not to have a try:except:raise
-            # RevisionNotPresent here until we see a use for it, because of the
-            # cost in an inner loop that is by its very nature O(history).
-            # Robert Collins 20080326
-            parents = graph.get_parent_map([next_id])[next_id]
             if len(parents) == 0:
                 return
             else:

=== modified file 'bzrlib/serializer.py'
--- a/bzrlib/serializer.py	2009-04-03 21:50:40 +0000
+++ b/bzrlib/serializer.py	2009-06-03 20:02:46 +0000
@@ -75,3 +75,5 @@
 format_registry.register_lazy('6', 'bzrlib.xml6', 'serializer_v6')
 format_registry.register_lazy('7', 'bzrlib.xml7', 'serializer_v7')
 format_registry.register_lazy('8', 'bzrlib.xml8', 'serializer_v8')
+format_registry.register_lazy('9', 'bzrlib.chk_serializer', 
+    'chk_serializer_255_bigpage')

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-06-03 01:43:22 +0000
+++ b/bzrlib/tests/__init__.py	2009-06-04 21:25:46 +0000
@@ -3062,8 +3062,18 @@
     try:
         content = file('/proc/cpuinfo', 'rb').read()
         concurrency = cpucount(content)
-    except Exception, e:
+        return concurrency
+    except IOError:
+        pass
+
+    try:
+       output = Popen(['sysctl', '-n', 'hw.availcpu'],
+                      stdout=PIPE).communicate()[0]
+       concurrency = int(output)
+       return concurrency
+    except (OSError, IOError):
         concurrency = 1
+
     return concurrency
 
 

=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- a/bzrlib/tests/blackbox/test_branch.py	2009-04-15 04:45:06 +0000
+++ b/bzrlib/tests/blackbox/test_branch.py	2009-06-03 20:03:55 +0000
@@ -237,9 +237,10 @@
             ['branch', '--stacked', 'trunk', 'shallow'])
         # We should notify the user that we upgraded their format
         self.assertEqualDiff(
-            'Source format does not support stacking, using format: \'1.6\'\n'
+            'Source repository format does not support stacking, using format:\n'
             '  Packs 5 (adds stacking support, requires bzr 1.6)\n'
-            '\n'
+            'Source branch format does not support stacking, using format:\n'
+            '  Branch format 7\n'
             'Created new stacked branch referring to %s.\n' % (trunk.base,),
             err)
 
@@ -249,10 +250,10 @@
             ['branch', '--stacked', 'trunk', 'shallow'])
         # We should notify the user that we upgraded their format
         self.assertEqualDiff(
-            'Source format does not support stacking, using format:'
-            ' \'1.6.1-rich-root\'\n'
+            'Source repository format does not support stacking, using format:\n'
             '  Packs 5 rich-root (adds stacking support, requires bzr 1.6.1)\n'
-            '\n'
+            'Source branch format does not support stacking, using format:\n'
+            '  Branch format 7\n'
             'Created new stacked branch referring to %s.\n' % (trunk.base,),
             err)
 

=== modified file 'bzrlib/tests/blackbox/test_export.py'
--- a/bzrlib/tests/blackbox/test_export.py	2009-04-06 14:18:33 +0000
+++ b/bzrlib/tests/blackbox/test_export.py	2009-06-03 10:16:23 +0000
@@ -60,7 +60,7 @@
 
         if sys.version_info < (2, 5, 2) and sys.platform == 'darwin':
             raise tests.KnownFailure('python %r has a tar related bug, upgrade'
-                                     % sys.version_info)
+                                     % (sys.version_info,))
         out, err = self.run_bzr('export --format=tgz --root=test -')
         ball = tarfile.open('', fileobj=StringIO(out))
         self.assertEqual(['test/a'], sorted(ball.getnames()))

=== modified file 'bzrlib/tests/branch_implementations/test_check.py'
--- a/bzrlib/tests/branch_implementations/test_check.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/branch_implementations/test_check.py	2009-05-28 15:22:13 +0000
@@ -67,4 +67,11 @@
         result.report_results(verbose=True)
         result.report_results(verbose=False)
 
+    def test_check_detects_ghosts_in_mainline(self):
+        tree = self.make_branch_and_tree('test')
+        tree.set_parent_ids(['thisisaghost'], allow_leftmost_as_ghost=True)
+        r1 = tree.commit('one')
+        r2 = tree.commit('two')
+        result = tree.branch.check()
+        self.assertEquals(True, result.ghosts_in_mainline)
 

=== modified file 'bzrlib/tests/branch_implementations/test_reconcile.py'
--- a/bzrlib/tests/branch_implementations/test_reconcile.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/branch_implementations/test_reconcile.py	2009-06-02 01:27:37 +0000
@@ -70,3 +70,13 @@
         a_branch = self.make_branch('a_branch')
         a_branch.reconcile(thorough=False)
         a_branch.reconcile(thorough=True)
+
+    def test_reconcile_handles_ghosts_in_revhistory(self):
+        tree = self.make_branch_and_tree('test')
+        tree.set_parent_ids(["spooky"], allow_leftmost_as_ghost=True)
+        r1 = tree.commit('one')
+        r2 = tree.commit('two')
+        tree.branch.set_last_revision_info(2, r2)
+
+        reconciler = tree.branch.reconcile()
+        self.assertEquals([r1, r2], tree.branch.revision_history())

=== modified file 'bzrlib/tests/branch_implementations/test_sprout.py'
--- a/bzrlib/tests/branch_implementations/test_sprout.py	2009-05-06 05:36:28 +0000
+++ b/bzrlib/tests/branch_implementations/test_sprout.py	2009-05-28 16:04:39 +0000
@@ -155,6 +155,14 @@
         self.assertEqual(target,
                          tree.basis_tree().get_symlink_target('link-id'))
 
+    def test_sprout_with_ghost_in_mainline(self):
+        tree = self.make_branch_and_tree('tree1')
+        tree.set_parent_ids(["spooky"], allow_leftmost_as_ghost=True)
+        tree.add('')
+        tree.commit('msg1', rev_id='rev1')
+        tree.commit('msg2', rev_id='rev2')
+        tree.bzrdir.sprout('target', revision_id='rev1')
+
     def assertBranchHookBranchIsStacked(self, pre_change_params):
         # Just calling will either succeed or fail.
         pre_change_params.branch.get_stacked_on_url()

=== modified file 'bzrlib/tests/inventory_implementations/basics.py'
--- a/bzrlib/tests/inventory_implementations/basics.py	2009-04-09 20:23:07 +0000
+++ b/bzrlib/tests/inventory_implementations/basics.py	2009-05-18 03:12:38 +0000
@@ -211,8 +211,12 @@
                      ('doc', 'directory', 'doc-id'),
                      ('src/hello.c', 'file', 'hello-id'),
                      ('src/bye.c', 'file', 'bye-id'),
+                     ('src/sub', 'directory', 'sub-id'),
+                     ('src/sub/a', 'file', 'a-id'),
                      ('Makefile', 'file', 'makefile-id')]:
             inv.add_path(*args)
+
+        # Test all entries
         self.assertEqual([
             ('', 'tree-root'),
             ('Makefile', 'makefile-id'),
@@ -220,8 +224,36 @@
             ('src', 'src-id'),
             ('src/bye.c', 'bye-id'),
             ('src/hello.c', 'hello-id'),
+            ('src/sub', 'sub-id'),
+            ('src/sub/a', 'a-id'),
             ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
 
+        # Test a subdirectory
+        self.assertEqual([
+            ('bye.c', 'bye-id'),
+            ('hello.c', 'hello-id'),
+            ('sub', 'sub-id'),
+            ('sub/a', 'a-id'),
+            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
+            from_dir='src-id')])
+
+        # Test not recursing at the root level
+        self.assertEqual([
+            ('', 'tree-root'),
+            ('Makefile', 'makefile-id'),
+            ('doc', 'doc-id'),
+            ('src', 'src-id'),
+            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
+            recursive=False)])
+
+        # Test not recursing at a subdirectory level
+        self.assertEqual([
+            ('bye.c', 'bye-id'),
+            ('hello.c', 'hello-id'),
+            ('sub', 'sub-id'),
+            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
+            from_dir='src-id', recursive=False)])
+
     def test_iter_just_entries(self):
         inv = self.make_inventory('tree-root')
         for args in [('src', 'directory', 'src-id'),

=== modified file 'bzrlib/tests/per_repository/test_iter_reverse_revision_history.py'
--- a/bzrlib/tests/per_repository/test_iter_reverse_revision_history.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_repository/test_iter_reverse_revision_history.py	2009-06-02 01:27:37 +0000
@@ -145,3 +145,23 @@
                                   repo, 'rev-2-4')
         self.assertRevHistoryList(['rev-2-5', 'rev-2-4', 'rev-2-3', 'rev-2-2',
                                    'rev-1-1'], repo, 'rev-2-5')
+
+    def test_ghost(self):
+        tree = self.make_branch_and_memory_tree('tree')
+        tree.lock_write()
+        try:
+            tree.add('')
+            tree.set_parent_ids(['spooky'], allow_leftmost_as_ghost=True)
+            tree.commit('1', rev_id='rev1')
+            tree.commit('2', rev_id='rev2')
+        finally:
+            tree.unlock()
+        iter = tree.branch.repository.iter_reverse_revision_history('rev2')
+        tree.branch.repository.lock_read()
+        try:
+            self.assertEquals('rev2', iter.next())
+            self.assertEquals('rev1', iter.next())
+            self.assertRaises(errors.RevisionNotPresent, iter.next)
+        finally:
+            tree.branch.repository.unlock()
+

=== modified file 'bzrlib/tests/per_repository/test_reconcile.py'
--- a/bzrlib/tests/per_repository/test_reconcile.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/per_repository/test_reconcile.py	2009-05-28 15:05:58 +0000
@@ -264,6 +264,40 @@
         self.assertEqual([None, 'the_ghost', 'ghost'], repo.get_ancestry('ghost'))
         self.assertEqual([None, 'the_ghost'], repo.get_ancestry('the_ghost'))
 
+    def test_text_from_ghost_revision(self):
+        repo = self.make_repository('text-from-ghost')
+        inv = Inventory(revision_id='final-revid')
+        inv.root.revision = 'root-revid'
+        ie = inv.add_path('bla', 'file', 'myfileid')
+        ie.revision = 'ghostrevid'
+        ie.text_size = 42
+        ie.text_sha1 = "bee68c8acd989f5f1765b4660695275948bf5c00"
+        rev = bzrlib.revision.Revision(timestamp=0,
+                                       timezone=None,
+                                       committer="Foo Bar <foo at example.com>",
+                                       message="Message",
+                                       revision_id='final-revid')
+        repo.lock_write()
+        try:
+            repo.start_write_group()
+            try:
+                repo.add_revision('final-revid', rev, inv)
+                try:
+                    repo.texts.add_lines(('myfileid', 'ghostrevid'),
+                        (('myfileid', 'ghost-text-parent'),),
+                        ["line1\n", "line2\n"])
+                except errors.RevisionNotPresent:
+                    raise TestSkipped("text ghost parents not supported")
+                if repo.supports_rich_root():
+                    root_id = inv.root.file_id
+                    repo.texts.add_lines((inv.root.file_id, inv.root.revision),
+                        [], [])
+            finally:
+                repo.commit_write_group()
+        finally:
+            repo.unlock()
+        repo.reconcile(thorough=True)
+
 
 class TestReconcileWithIncorrectRevisionCache(TestReconcile):
     """Ancestry data gets cached in knits and weaves should be reconcilable.

=== modified file 'bzrlib/tests/per_repository_reference/test_initialize.py'
--- a/bzrlib/tests/per_repository_reference/test_initialize.py	2009-05-29 09:56:12 +0000
+++ b/bzrlib/tests/per_repository_reference/test_initialize.py	2009-06-03 18:08:53 +0000
@@ -52,8 +52,4 @@
         trans = self.make_smart_server('stacked')
         repo = self.initialize_and_check_on_transport(base, trans)
         network_name = base.repository._format.network_name()
-        if network_name != repo._format.network_name():
-            raise tests.KnownFailure('Remote initialize_on_transport_ex()'
-                ' tries to "upgrade" the format because it doesn\'t have a'
-                ' branch format, and hard-codes the new repository format.')
         self.assertEqual(network_name, repo._format.network_name())

=== modified file 'bzrlib/tests/test_mail_client.py'
--- a/bzrlib/tests/test_mail_client.py	2009-05-11 18:35:20 +0000
+++ b/bzrlib/tests/test_mail_client.py	2009-06-04 19:56:42 +0000
@@ -191,9 +191,10 @@
     def test_commandline(self):
         claws = mail_client.Claws(None)
         commandline = claws._get_compose_commandline(
-            None, None, 'file%')
+            'jrandom at example.org', None, 'file%')
         self.assertEqual(
-            ['--compose', 'mailto:?', '--attach', 'file%'], commandline)
+            ['--compose', 'mailto:jrandom at example.org?', '--attach', 'file%'],
+            commandline)
         commandline = claws._get_compose_commandline(
             'jrandom at example.org', 'Hi there!', None)
         self.assertEqual(
@@ -217,6 +218,30 @@
             self.assertFalse(isinstance(item, unicode),
                 'Command-line item %r is unicode!' % item)
 
+    def test_with_from(self):
+        claws = mail_client.Claws(None)
+        cmdline = claws._get_compose_commandline(
+            u'jrandom at example.org', None, None, None, u'qrandom at example.com')
+        self.assertEqual(
+            ['--compose',
+             'mailto:jrandom at example.org?from=qrandom%40example.com'],
+            cmdline)
+
+    def test_to_required(self):
+        claws = mail_client.Claws(None)
+        self.assertRaises(errors.NoMailAddressSpecified,
+                          claws._get_compose_commandline,
+                          None, None, 'file%')
+
+    def test_with_body(self):
+        claws = mail_client.Claws(None)
+        cmdline = claws._get_compose_commandline(
+            u'jrandom at example.org', None, None, 'This is some body text')
+        self.assertEqual(
+            ['--compose',
+             'mailto:jrandom at example.org?body=This%20is%20some%20body%20text'],
+            cmdline)
+
 
 class TestEditor(tests.TestCase):
 

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-05-07 05:08:46 +0000
+++ b/bzrlib/tests/test_remote.py	2009-06-03 04:40:53 +0000
@@ -741,6 +741,61 @@
         self.assertEqual(network_name, repo._format.network_name())
 
 
+class TestBzrDirFormatInitializeEx(TestRemote):
+
+    def test_success(self):
+        """Simple test for typical successful call."""
+        fmt = bzrdir.RemoteBzrDirFormat()
+        default_format_name = BzrDirFormat.get_default_format().network_name()
+        transport = self.get_transport()
+        client = FakeClient(transport.base)
+        client.add_expected_call(
+            'BzrDirFormat.initialize_ex',
+                (default_format_name, 'path', 'False', 'False', 'False', '',
+                 '', '', '', 'False'),
+            'success',
+                ('.', 'no', 'no', 'yes', 'repo fmt', 'repo bzrdir fmt',
+                 'bzrdir fmt', 'False', '', '', 'repo lock token'))
+        # XXX: It would be better to call fmt.initialize_on_transport_ex, but
+        # it's currently hard to test that without supplying a real remote
+        # transport connected to a real server.
+        result = fmt._initialize_on_transport_ex_rpc(client, 'path',
+            transport, False, False, False, None, None, None, None, False)
+        client.finished_test()
+
+    def test_error(self):
+        """Error responses are translated, e.g. 'PermissionDenied' raises the
+        corresponding error from the client.
+        """
+        fmt = bzrdir.RemoteBzrDirFormat()
+        default_format_name = BzrDirFormat.get_default_format().network_name()
+        transport = self.get_transport()
+        client = FakeClient(transport.base)
+        client.add_expected_call(
+            'BzrDirFormat.initialize_ex',
+                (default_format_name, 'path', 'False', 'False', 'False', '',
+                 '', '', '', 'False'),
+            'error',
+                ('PermissionDenied', 'path', 'extra info'))
+        # XXX: It would be better to call fmt.initialize_on_transport_ex, but
+        # it's currently hard to test that without supplying a real remote
+        # transport connected to a real server.
+        err = self.assertRaises(errors.PermissionDenied,
+            fmt._initialize_on_transport_ex_rpc, client, 'path', transport,
+            False, False, False, None, None, None, None, False)
+        self.assertEqual('path', err.path)
+        self.assertEqual(': extra info', err.extra)
+        client.finished_test()
+
+    def test_error_from_real_server(self):
+        """Integration test for error translation."""
+        transport = self.make_smart_server('foo')
+        transport = transport.clone('no-such-path')
+        fmt = bzrdir.RemoteBzrDirFormat()
+        err = self.assertRaises(errors.NoSuchFile,
+            fmt.initialize_on_transport_ex, transport, create_prefix=False)
+
+
 class OldSmartClient(object):
     """A fake smart client for test_old_version that just returns a version one
     response to the 'hello' (query version) command.

=== modified file 'bzrlib/tests/test_serializer.py'
--- a/bzrlib/tests/test_serializer.py	2009-04-03 21:50:40 +0000
+++ b/bzrlib/tests/test_serializer.py	2009-06-03 20:02:46 +0000
@@ -19,6 +19,7 @@
 
 
 from bzrlib import (
+    chk_serializer,
     serializer,
     xml4,
     xml5,
@@ -43,3 +44,5 @@
                       serializer.format_registry.get('7'))
         self.assertIs(xml8.serializer_v8,
                       serializer.format_registry.get('8'))
+        self.assertIs(chk_serializer.chk_serializer_255_bigpage,
+                      serializer.format_registry.get('9'))



More information about the bazaar-commits mailing list