27
revision as _mod_revision,
30
from bzrlib.builtins import _merge_helper
22
from bzrlib import inventory, treebuilder
23
from bzrlib.builtins import merge
31
24
from bzrlib.bzrdir import BzrDir
32
25
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
33
26
from bzrlib.bundle.bundle_data import BundleTree
34
27
from bzrlib.bundle.serializer import write_bundle, read_bundle
35
from bzrlib.bundle.serializer.v08 import BundleSerializerV08
36
from bzrlib.bundle.serializer.v09 import BundleSerializerV09
37
28
from bzrlib.branch import Branch
38
29
from bzrlib.diff import internal_diff
39
30
from bzrlib.errors import (BzrError, TestamentMismatch, NotABundle, BadBundle,
41
32
from bzrlib.merge import Merge3Merger
42
from bzrlib.repofmt import knitrepo
43
33
from bzrlib.osutils import has_symlinks, sha_file
44
34
from bzrlib.tests import (TestCaseInTempDir, TestCaseWithTransport,
45
35
TestCase, TestSkipped)
311
301
[inventory.ROOT_ID, 'a', 'b', 'd', 'e'])
314
class BundleTester1(TestCaseWithTransport):
316
def test_mismatched_bundle(self):
317
format = bzrdir.BzrDirMetaFormat1()
318
format.repository_format = knitrepo.RepositoryFormatKnit3()
319
serializer = BundleSerializerV08('0.8')
320
b = self.make_branch('.', format=format)
321
self.assertRaises(errors.IncompatibleBundleFormat, serializer.write,
322
b.repository, [], {}, StringIO())
324
def test_matched_bundle(self):
325
"""Don't raise IncompatibleBundleFormat for knit2 and bundle0.9"""
326
format = bzrdir.BzrDirMetaFormat1()
327
format.repository_format = knitrepo.RepositoryFormatKnit3()
328
serializer = BundleSerializerV09('0.9')
329
b = self.make_branch('.', format=format)
330
serializer.write(b.repository, [], {}, StringIO())
332
def test_mismatched_model(self):
333
"""Try copying a bundle from knit2 to knit1"""
334
format = bzrdir.BzrDirMetaFormat1()
335
format.repository_format = knitrepo.RepositoryFormatKnit3()
336
source = self.make_branch_and_tree('source', format=format)
337
source.commit('one', rev_id='one-id')
338
source.commit('two', rev_id='two-id')
340
write_bundle(source.branch.repository, 'two-id', 'null:', text,
344
format = bzrdir.BzrDirMetaFormat1()
345
format.repository_format = knitrepo.RepositoryFormatKnit1()
346
target = self.make_branch('target', format=format)
347
self.assertRaises(errors.IncompatibleRevision, install_bundle,
348
target.repository, read_bundle(text))
351
class V08BundleTester(TestCaseWithTransport):
355
def bzrdir_format(self):
356
format = bzrdir.BzrDirMetaFormat1()
357
format.repository_format = knitrepo.RepositoryFormatKnit1()
360
def make_branch_and_tree(self, path, format=None):
362
format = self.bzrdir_format()
363
return TestCaseWithTransport.make_branch_and_tree(self, path, format)
365
def make_branch(self, path, format=None):
367
format = self.bzrdir_format()
368
return TestCaseWithTransport.make_branch(self, path, format)
304
class BundleTester(TestCaseWithTransport):
370
306
def create_bundle_text(self, base_rev_id, rev_id):
371
307
bundle_txt = StringIO()
372
308
rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id,
373
bundle_txt, format=self.format)
374
310
bundle_txt.seek(0)
375
311
self.assertEqual(bundle_txt.readline(),
376
'# Bazaar revision bundle v%s\n' % self.format)
312
'# Bazaar revision bundle v0.8\n')
377
313
self.assertEqual(bundle_txt.readline(), '#\n')
379
315
rev = self.b1.repository.get_revision(rev_id)
785
714
u'William Dod\xe9\n').encode('utf-8'))
788
self.tree1.add([u'with Dod\xe9'], ['withdod-id'])
789
self.tree1.commit(u'i18n commit from William Dod\xe9',
717
self.tree1.add([u'with Dod\xe9'])
718
self.tree1.commit(u'i18n commit from William Dod\xe9',
790
719
rev_id='i18n-1', committer=u'William Dod\xe9')
792
if sys.platform == 'darwin':
793
# On Mac the '\xe9' gets changed to 'e\u0301'
794
self.assertEqual([u'.bzr', u'with Dode\u0301'],
795
sorted(os.listdir(u'b1')))
796
delta = self.tree1.changes_from(self.tree1.basis_tree())
797
self.assertEqual([(u'with Dod\xe9', 'withdod-id', 'file')],
799
self.knownFailure("Mac OSX doesn't preserve unicode"
800
" combining characters.")
803
bundle = self.get_valid_bundle('null:', 'i18n-1')
722
bundle = self.get_valid_bundle(None, 'i18n-1')
806
725
f = open(u'b1/with Dod\xe9', 'wb')
891
810
self.tree1 = self.make_branch_and_tree('b1')
892
811
self.b1 = self.tree1.branch
893
812
self.tree1.commit('message', rev_id='revid1')
894
bundle = self.get_valid_bundle('null:', 'revid1')
813
bundle = self.get_valid_bundle(None, 'revid1')
895
814
tree = bundle.revision_tree(self.b1.repository, 'revid1')
896
815
self.assertEqual('revid1', tree.inventory.root.revision)
898
def test_install_revisions(self):
899
self.tree1 = self.make_branch_and_tree('b1')
900
self.b1 = self.tree1.branch
901
self.tree1.commit('message', rev_id='rev2a')
902
bundle = self.get_valid_bundle('null:', 'rev2a')
903
branch2 = self.make_branch('b2')
904
self.assertFalse(branch2.repository.has_revision('rev2a'))
905
target_revision = bundle.install_revisions(branch2.repository)
906
self.assertTrue(branch2.repository.has_revision('rev2a'))
907
self.assertEqual('rev2a', target_revision)
909
def test_bundle_empty_property(self):
910
"""Test serializing revision properties with an empty value."""
911
tree = self.make_branch_and_memory_tree('tree')
913
self.addCleanup(tree.unlock)
914
tree.add([''], ['TREE_ROOT'])
915
tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
916
self.b1 = tree.branch
917
bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
918
self.assertContainsRe(bundle_sio.getvalue(),
920
'# branch-nick: tree\n'
924
bundle = read_bundle(bundle_sio)
925
revision_info = bundle.revisions[0]
926
self.assertEqual('rev1', revision_info.revision_id)
927
rev = revision_info.as_revision()
928
self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
931
def test_bundle_empty_property_alt(self):
932
"""Test serializing revision properties with an empty value.
934
Older readers had a bug when reading an empty property.
935
They assumed that all keys ended in ': \n'. However they would write an
936
empty value as ':\n'. This tests make sure that all newer bzr versions
937
can handle th second form.
939
tree = self.make_branch_and_memory_tree('tree')
941
self.addCleanup(tree.unlock)
942
tree.add([''], ['TREE_ROOT'])
943
tree.commit('One', revprops={'one':'two', 'empty':''}, rev_id='rev1')
944
self.b1 = tree.branch
945
bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
946
txt = bundle_sio.getvalue()
947
loc = txt.find('# empty: ') + len('# empty:')
948
# Create a new bundle, which strips the trailing space after empty
949
bundle_sio = StringIO(txt[:loc] + txt[loc+1:])
951
self.assertContainsRe(bundle_sio.getvalue(),
953
'# branch-nick: tree\n'
957
bundle = read_bundle(bundle_sio)
958
revision_info = bundle.revisions[0]
959
self.assertEqual('rev1', revision_info.revision_id)
960
rev = revision_info.as_revision()
961
self.assertEqual({'branch-nick':'tree', 'empty':'', 'one':'two'},
964
def test_bundle_sorted_properties(self):
965
"""For stability the writer should write properties in sorted order."""
966
tree = self.make_branch_and_memory_tree('tree')
968
self.addCleanup(tree.unlock)
970
tree.add([''], ['TREE_ROOT'])
971
tree.commit('One', rev_id='rev1',
972
revprops={'a':'4', 'b':'3', 'c':'2', 'd':'1'})
973
self.b1 = tree.branch
974
bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
975
self.assertContainsRe(bundle_sio.getvalue(),
979
'# branch-nick: tree\n'
983
bundle = read_bundle(bundle_sio)
984
revision_info = bundle.revisions[0]
985
self.assertEqual('rev1', revision_info.revision_id)
986
rev = revision_info.as_revision()
987
self.assertEqual({'branch-nick':'tree', 'a':'4', 'b':'3', 'c':'2',
988
'd':'1'}, rev.properties)
990
def test_bundle_unicode_properties(self):
991
"""We should be able to round trip a non-ascii property."""
992
tree = self.make_branch_and_memory_tree('tree')
994
self.addCleanup(tree.unlock)
996
tree.add([''], ['TREE_ROOT'])
997
# Revisions themselves do not require anything about revision property
998
# keys, other than that they are a basestring, and do not contain
1000
# However, Testaments assert than they are str(), and thus should not
1002
tree.commit('One', rev_id='rev1',
1003
revprops={'omega':u'\u03a9', 'alpha':u'\u03b1'})
1004
self.b1 = tree.branch
1005
bundle_sio, revision_ids = self.create_bundle_text('null:', 'rev1')
1006
self.assertContainsRe(bundle_sio.getvalue(),
1008
'# alpha: \xce\xb1\n'
1009
'# branch-nick: tree\n'
1010
'# omega: \xce\xa9\n'
1012
bundle = read_bundle(bundle_sio)
1013
revision_info = bundle.revisions[0]
1014
self.assertEqual('rev1', revision_info.revision_id)
1015
rev = revision_info.as_revision()
1016
self.assertEqual({'branch-nick':'tree', 'omega':u'\u03a9',
1017
'alpha':u'\u03b1'}, rev.properties)
1020
class V09BundleKnit2Tester(V08BundleTester):
1024
def bzrdir_format(self):
1025
format = bzrdir.BzrDirMetaFormat1()
1026
format.repository_format = knitrepo.RepositoryFormatKnit3()
1030
class V09BundleKnit1Tester(V08BundleTester):
1034
def bzrdir_format(self):
1035
format = bzrdir.BzrDirMetaFormat1()
1036
format.repository_format = knitrepo.RepositoryFormatKnit1()
1040
818
class MungedBundleTester(TestCaseWithTransport):