Rev 2466: (John Arbash Meinel) Fix bug #109613 by teaching Bundle how to properly read/write revision properties with no value. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Apr 26 22:11:05 BST 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 2466
revision-id: pqm at pqm.ubuntu.com-20070426211103-h84prqh7a4ad3ez2
parent: pqm at pqm.ubuntu.com-20070426181928-ot99t6eyhjjfj5h3
parent: john at arbash-meinel.com-20070426185333-i1xlyaeyf049kdxc
committer: Canonical.com Patch Queue Manager<pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2007-04-26 22:11:03 +0100
message:
(John Arbash Meinel) Fix bug #109613 by teaching Bundle how to properly read/write revision properties with no value.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/bundle/bundle_data.py read_changeset.py-20050619171944-c0d95aa685537640
bzrlib/bundle/serializer/v08.py v06.py-20051119041339-ee43f97270b01823
bzrlib/tests/test_bundle.py test.py-20050630184834-092aa401ab9f039c
------------------------------------------------------------
revno: 2447.1.7
merged: john at arbash-meinel.com-20070426185333-i1xlyaeyf049kdxc
parent: john at arbash-meinel.com-20070426145512-xnda2pxcpfa86yld
parent: pqm at pqm.ubuntu.com-20070426181928-ot99t6eyhjjfj5h3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Thu 2007-04-26 13:53:33 -0500
message:
[merge] bzr.dev 2465
------------------------------------------------------------
revno: 2447.1.6
merged: john at arbash-meinel.com-20070426145512-xnda2pxcpfa86yld
parent: john at arbash-meinel.com-20070425175514-il068rykvdulkm2k
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Thu 2007-04-26 09:55:12 -0500
message:
NEWS update for fixing bug #109613
------------------------------------------------------------
revno: 2447.1.5
merged: john at arbash-meinel.com-20070425175514-il068rykvdulkm2k
parent: john at arbash-meinel.com-20070425174944-mti4294wv55nimd3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Wed 2007-04-25 12:55:14 -0500
message:
NEWS
------------------------------------------------------------
revno: 2447.1.4
merged: john at arbash-meinel.com-20070425174944-mti4294wv55nimd3
parent: john at arbash-meinel.com-20070425165625-d2act28kmjn5avel
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Wed 2007-04-25 12:49:44 -0500
message:
Add a test that we properly round-trip unicode properties.
And fix the (unreported) bug :)
------------------------------------------------------------
revno: 2447.1.3
merged: john at arbash-meinel.com-20070425165625-d2act28kmjn5avel
parent: john at arbash-meinel.com-20070425164125-nr7pmz4tfp5qkze2
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Wed 2007-04-25 11:56:25 -0500
message:
Change the default serializer to include a trailing whitespace for empty properties.
This means that new bundles can be read by old versions of bzr
(though they cannot read their own).
On the flip side, the new bzr can read old outputs correctly.
------------------------------------------------------------
revno: 2447.1.2
merged: john at arbash-meinel.com-20070425164125-nr7pmz4tfp5qkze2
parent: john at arbash-meinel.com-20070425143231-wy5jkw8g9tr471ji
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Wed 2007-04-25 11:41:25 -0500
message:
Add tests that we handle empty values whether they end in ': \n' or ':\n'.
And fix the reader to handle the ':\n' case.
------------------------------------------------------------
revno: 2447.1.1
merged: john at arbash-meinel.com-20070425143231-wy5jkw8g9tr471ji
parent: pqm at pqm.ubuntu.com-20070423170758-qd512ltqglzfo6w9
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bundle_empty_properties
timestamp: Wed 2007-04-25 09:32:31 -0500
message:
For stability and ease of testing, write properties in sorted order.
This doesn't really change the bundle format, since we read the
properties into a dictionary, so their position in the file doesn't
matter. Plus the Revision xml serializer also writes them in sorted
order.
=== modified file 'NEWS'
--- a/NEWS 2007-04-26 16:52:32 +0000
+++ b/NEWS 2007-04-26 18:53:33 +0000
@@ -7,6 +7,10 @@
status`` should show the removed file and an unknown file in its
place. (John Arbash Meinel, #109993)
+ * Bundles properly read and write revision properties that have an
+ empty value. And when the value is not ASCII.
+ (John Arbash Meinel, #109613)
+
bzr 0.16rc1 2007-04-26
=== modified file 'bzrlib/bundle/bundle_data.py'
--- a/bzrlib/bundle/bundle_data.py 2007-04-05 09:35:26 +0000
+++ b/bzrlib/bundle/bundle_data.py 2007-04-25 17:49:44 +0000
@@ -76,9 +76,13 @@
if self.properties:
for property in self.properties:
key_end = property.find(': ')
- assert key_end is not None
- key = property[:key_end].encode('utf-8')
- value = property[key_end+2:].encode('utf-8')
+ if key_end == -1:
+ assert property.endswith(':')
+ key = str(property[:-1])
+ value = ''
+ else:
+ key = str(property[:key_end])
+ value = property[key_end+2:]
rev.properties[key] = value
return rev
=== modified file 'bzrlib/bundle/serializer/v08.py'
--- a/bzrlib/bundle/serializer/v08.py 2007-03-16 15:14:40 +0000
+++ b/bzrlib/bundle/serializer/v08.py 2007-04-25 16:56:25 +0000
@@ -135,14 +135,24 @@
f.write('0.8\n')
f.write('#\n')
- def _write(self, key, value, indent=1):
- """Write out meta information, with proper indenting, etc"""
+ def _write(self, key, value, indent=1, trailing_space_when_empty=False):
+ """Write out meta information, with proper indenting, etc.
+
+ :param trailing_space_when_empty: To work around a bug in earlier
+ bundle readers, when writing an empty property, we use "prop: \n"
+ rather than writing "prop:\n".
+ If this parameter is True, and value is the empty string, we will
+ write an extra space.
+ """
assert indent > 0, 'indentation must be greater than 0'
f = self.to_file
f.write('#' + (' ' * indent))
f.write(key.encode('utf-8'))
if not value:
- f.write(':\n')
+ if trailing_space_when_empty and value == '':
+ f.write(': \n')
+ else:
+ f.write(':\n')
elif isinstance(value, str):
f.write(': ')
f.write(value)
@@ -225,8 +235,9 @@
w('base id', base_rev)
if rev.properties:
self._write('properties', None, indent=1)
- for name, value in rev.properties.items():
- self._write(name, value, indent=3)
+ for name, value in sorted(rev.properties.items()):
+ self._write(name, value, indent=3,
+ trailing_space_when_empty=True)
# Add an extra blank space at the end
self.to_file.write('\n')
=== modified file 'bzrlib/tests/test_bundle.py'
--- a/bzrlib/tests/test_bundle.py 2007-04-04 21:39:03 +0000
+++ b/bzrlib/tests/test_bundle.py 2007-04-25 17:49:44 +0000
@@ -905,6 +905,116 @@
self.assertTrue(branch2.repository.has_revision('rev2a'))
self.assertEqual('rev2a', target_revision)
+ def test_bundle_empty_property(self):
+ """Test serializing revision properties with an empty value."""
+ tree = self.make_branch_and_memory_tree('tree')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ tree.add([''], ['TREE_ROOT'])
+ tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
+ self.b1 = tree.branch
+ bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
+ self.assertContainsRe(bundle_sio.getvalue(),
+ '# properties:\n'
+ '# branch-nick: tree\n'
+ '# empty: \n'
+ '# one: two\n'
+ )
+ bundle = read_bundle(bundle_sio)
+ revision_info = bundle.revisions[0]
+ self.assertEqual('rev1', revision_info.revision_id)
+ rev = revision_info.as_revision()
+ self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
+ rev.properties)
+
+ def test_bundle_empty_property_alt(self):
+ """Test serializing revision properties with an empty value.
+
+ Older readers had a bug when reading an empty property.
+ They assumed that all keys ended in ': \n'. However they would write an
+ empty value as ':\n'. This tests make sure that all newer bzr versions
+ can handle th second form.
+ """
+ tree = self.make_branch_and_memory_tree('tree')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ tree.add([''], ['TREE_ROOT'])
+ tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
+ self.b1 = tree.branch
+ bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
+ txt = bundle_sio.getvalue()
+ loc = txt.find('# empty: ') + len('# empty:')
+ # Create a new bundle, which strips the trailing space after empty
+ bundle_sio = StringIO(txt[:loc] + txt[loc+1:])
+
+ self.assertContainsRe(bundle_sio.getvalue(),
+ '# properties:\n'
+ '# branch-nick: tree\n'
+ '# empty:\n'
+ '# one: two\n'
+ )
+ bundle = read_bundle(bundle_sio)
+ revision_info = bundle.revisions[0]
+ self.assertEqual('rev1', revision_info.revision_id)
+ rev = revision_info.as_revision()
+ self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
+ rev.properties)
+
+ def test_bundle_sorted_properties(self):
+ """For stability the writer should write properties in sorted order."""
+ tree = self.make_branch_and_memory_tree('tree')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+
+ tree.add([''], ['TREE_ROOT'])
+ tree.commit('One', rev_id='rev1',
+ revprops={'a':'4', 'b':'3', 'c':'2', 'd':'1'})
+ self.b1 = tree.branch
+ bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
+ self.assertContainsRe(bundle_sio.getvalue(),
+ '# properties:\n'
+ '# a: 4\n'
+ '# b: 3\n'
+ '# branch-nick: tree\n'
+ '# c: 2\n'
+ '# d: 1\n'
+ )
+ bundle = read_bundle(bundle_sio)
+ revision_info = bundle.revisions[0]
+ self.assertEqual('rev1', revision_info.revision_id)
+ rev = revision_info.as_revision()
+ self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
+ 'd':'1'}, rev.properties)
+
+ def test_bundle_unicode_properties(self):
+ """We should be able to round trip a non-ascii property."""
+ tree = self.make_branch_and_memory_tree('tree')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+
+ tree.add([''], ['TREE_ROOT'])
+ # Revisions themselves do not require anything about revision property
+ # keys, other than that they are a basestring, and do not contain
+ # whitespace.
+ # However, Testaments assert than they are str(), and thus should not
+ # be Unicode.
+ tree.commit('One', rev_id='rev1',
+ revprops={'omega':u'\u03a9', 'alpha':u'\u03b1'})
+ self.b1 = tree.branch
+ bundle_sio, revision_ids = self.create_bundle_text(None, 'rev1')
+ self.assertContainsRe(bundle_sio.getvalue(),
+ '# properties:\n'
+ '# alpha: \xce\xb1\n'
+ '# branch-nick: tree\n'
+ '# omega: \xce\xa9\n'
+ )
+ bundle = read_bundle(bundle_sio)
+ revision_info = bundle.revisions[0]
+ self.assertEqual('rev1', revision_info.revision_id)
+ rev = revision_info.as_revision()
+ self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
+ 'alpha':u'\u03b1'}, rev.properties)
+
class V09BundleKnit2Tester(V08BundleTester):
More information about the bazaar-commits
mailing list