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