14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from cStringIO import StringIO
21
import SocketServer as socketserver
29
29
revision as _mod_revision,
37
from ..bundle import read_mergeable_from_url
38
from ..bundle.apply_bundle import install_bundle, merge_bundle
39
from ..bundle.bundle_data import BundleTree
40
from ..directory_service import directories
41
from ..bundle.serializer import write_bundle, read_bundle, v09, v4
42
from ..bundle.serializer.v08 import BundleSerializerV08
43
from ..bundle.serializer.v09 import BundleSerializerV09
44
from ..bundle.serializer.v4 import BundleSerializerV4
45
from ..bzr import knitrepo
46
from ..sixish import (
33
from bzrlib.bundle import read_mergeable_from_url
34
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
35
from bzrlib.bundle.bundle_data import BundleTree
36
from bzrlib.directory_service import directories
37
from bzrlib.bundle.serializer import write_bundle, read_bundle, v09, v4
38
from bzrlib.bundle.serializer.v08 import BundleSerializerV08
39
from bzrlib.bundle.serializer.v09 import BundleSerializerV09
40
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
41
from bzrlib.repofmt import knitrepo
42
from bzrlib.tests import (
55
from ..transform import TreeTransform
48
from bzrlib.transform import TreeTransform
58
51
def get_text(vf, key):
59
52
"""Get the fulltext for a given revision id that is present in the vf"""
60
53
stream = vf.get_record_stream([key], 'unordered', True)
54
record = stream.next()
62
55
return record.get_bytes_as('fulltext')
158
146
def has_id(self, file_id):
159
147
return self.id2path(file_id) is not None
161
def get_file(self, path, file_id=None):
163
file_id = self.path2id(path)
166
result.write(self.contents[file_id])
168
raise errors.NoSuchFile(path)
149
def get_file(self, file_id):
151
result.write(self.contents[file_id])
172
def get_file_revision(self, path, file_id=None):
174
file_id = self.path2id(path)
155
def get_file_revision(self, file_id):
175
156
return self.inventory[file_id].revision
177
def get_file_size(self, path, file_id=None):
179
file_id = self.path2id(path)
158
def get_file_size(self, file_id):
180
159
return self.inventory[file_id].text_size
182
def get_file_sha1(self, path, file_id=None):
184
file_id = self.path2id(path)
161
def get_file_sha1(self, file_id):
185
162
return self.inventory[file_id].text_sha1
187
def contents_stats(self, path, file_id):
164
def contents_stats(self, file_id):
188
165
if file_id not in self.contents:
189
166
return None, None
190
text_sha1 = osutils.sha_file(self.get_file(path, file_id))
167
text_sha1 = osutils.sha_file(self.get_file(file_id))
191
168
return text_sha1, len(self.contents[file_id])
211
188
self.assertEqual(btree.old_path("grandparent/parent/file"),
212
189
"grandparent/parent/file")
214
self.assertEqual(btree.id2path(b"a"), "grandparent")
215
self.assertEqual(btree.id2path(b"b"), "grandparent/parent")
216
self.assertEqual(btree.id2path(b"c"), "grandparent/parent/file")
218
self.assertEqual(btree.path2id("grandparent"), b"a")
219
self.assertEqual(btree.path2id("grandparent/parent"), b"b")
220
self.assertEqual(btree.path2id("grandparent/parent/file"), b"c")
222
self.assertIs(btree.path2id("grandparent2"), None)
223
self.assertIs(btree.path2id("grandparent2/parent"), None)
224
self.assertIs(btree.path2id("grandparent2/parent/file"), None)
191
self.assertEqual(btree.id2path("a"), "grandparent")
192
self.assertEqual(btree.id2path("b"), "grandparent/parent")
193
self.assertEqual(btree.id2path("c"), "grandparent/parent/file")
195
self.assertEqual(btree.path2id("grandparent"), "a")
196
self.assertEqual(btree.path2id("grandparent/parent"), "b")
197
self.assertEqual(btree.path2id("grandparent/parent/file"), "c")
199
self.assertTrue(btree.path2id("grandparent2") is None)
200
self.assertTrue(btree.path2id("grandparent2/parent") is None)
201
self.assertTrue(btree.path2id("grandparent2/parent/file") is None)
226
203
btree.note_rename("grandparent", "grandparent2")
227
self.assertIs(btree.old_path("grandparent"), None)
228
self.assertIs(btree.old_path("grandparent/parent"), None)
229
self.assertIs(btree.old_path("grandparent/parent/file"), None)
231
self.assertEqual(btree.id2path(b"a"), "grandparent2")
232
self.assertEqual(btree.id2path(b"b"), "grandparent2/parent")
233
self.assertEqual(btree.id2path(b"c"), "grandparent2/parent/file")
235
self.assertEqual(btree.path2id("grandparent2"), b"a")
236
self.assertEqual(btree.path2id("grandparent2/parent"), b"b")
237
self.assertEqual(btree.path2id("grandparent2/parent/file"), b"c")
204
self.assertTrue(btree.old_path("grandparent") is None)
205
self.assertTrue(btree.old_path("grandparent/parent") is None)
206
self.assertTrue(btree.old_path("grandparent/parent/file") is None)
208
self.assertEqual(btree.id2path("a"), "grandparent2")
209
self.assertEqual(btree.id2path("b"), "grandparent2/parent")
210
self.assertEqual(btree.id2path("c"), "grandparent2/parent/file")
212
self.assertEqual(btree.path2id("grandparent2"), "a")
213
self.assertEqual(btree.path2id("grandparent2/parent"), "b")
214
self.assertEqual(btree.path2id("grandparent2/parent/file"), "c")
239
216
self.assertTrue(btree.path2id("grandparent") is None)
240
217
self.assertTrue(btree.path2id("grandparent/parent") is None)
241
218
self.assertTrue(btree.path2id("grandparent/parent/file") is None)
243
220
btree.note_rename("grandparent/parent", "grandparent2/parent2")
244
self.assertEqual(btree.id2path(b"a"), "grandparent2")
245
self.assertEqual(btree.id2path(b"b"), "grandparent2/parent2")
246
self.assertEqual(btree.id2path(b"c"), "grandparent2/parent2/file")
221
self.assertEqual(btree.id2path("a"), "grandparent2")
222
self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
223
self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file")
248
self.assertEqual(btree.path2id("grandparent2"), b"a")
249
self.assertEqual(btree.path2id("grandparent2/parent2"), b"b")
250
self.assertEqual(btree.path2id("grandparent2/parent2/file"), b"c")
225
self.assertEqual(btree.path2id("grandparent2"), "a")
226
self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
227
self.assertEqual(btree.path2id("grandparent2/parent2/file"), "c")
252
229
self.assertTrue(btree.path2id("grandparent2/parent") is None)
253
230
self.assertTrue(btree.path2id("grandparent2/parent/file") is None)
255
232
btree.note_rename("grandparent/parent/file",
256
233
"grandparent2/parent2/file2")
257
self.assertEqual(btree.id2path(b"a"), "grandparent2")
258
self.assertEqual(btree.id2path(b"b"), "grandparent2/parent2")
259
self.assertEqual(btree.id2path(b"c"), "grandparent2/parent2/file2")
234
self.assertEqual(btree.id2path("a"), "grandparent2")
235
self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
236
self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file2")
261
self.assertEqual(btree.path2id("grandparent2"), b"a")
262
self.assertEqual(btree.path2id("grandparent2/parent2"), b"b")
263
self.assertEqual(btree.path2id("grandparent2/parent2/file2"), b"c")
238
self.assertEqual(btree.path2id("grandparent2"), "a")
239
self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
240
self.assertEqual(btree.path2id("grandparent2/parent2/file2"), "c")
265
242
self.assertTrue(btree.path2id("grandparent2/parent2/file") is None)
269
246
btree = self.make_tree_1()[0]
270
247
btree.note_rename("grandparent/parent/file",
271
248
"grandparent/alt_parent/file")
272
self.assertEqual(btree.id2path(b"c"), "grandparent/alt_parent/file")
273
self.assertEqual(btree.path2id("grandparent/alt_parent/file"), b"c")
249
self.assertEqual(btree.id2path("c"), "grandparent/alt_parent/file")
250
self.assertEqual(btree.path2id("grandparent/alt_parent/file"), "c")
274
251
self.assertTrue(btree.path2id("grandparent/parent/file") is None)
276
253
def unified_diff(self, old, new):
278
255
diff.internal_diff("old", old, "new", new, out)
280
257
return out.read()
282
259
def make_tree_2(self):
283
260
btree = self.make_tree_1()[0]
284
261
btree.note_rename("grandparent/parent/file",
285
262
"grandparent/alt_parent/file")
286
self.assertTrue(btree.id2path(b"e") is None)
263
self.assertTrue(btree.id2path("e") is None)
287
264
self.assertTrue(btree.path2id("grandparent/parent/file") is None)
288
265
btree.note_id("e", "grandparent/parent/file")
293
270
btree = self.make_tree_2()
294
271
add_patch = self.unified_diff([], ["Extra cheese\n"])
295
272
btree.note_patch("grandparent/parent/file", add_patch)
296
btree.note_id(b'f', 'grandparent/parent/symlink', kind='symlink')
273
btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
297
274
btree.note_target('grandparent/parent/symlink', 'venus')
298
275
self.adds_test(btree)
300
277
def adds_test(self, btree):
301
self.assertEqual(btree.id2path(b"e"), "grandparent/parent/file")
302
self.assertEqual(btree.path2id("grandparent/parent/file"), b"e")
303
self.assertEqual(btree.get_file("grandparent/parent/file").read(),
306
btree.get_symlink_target('grandparent/parent/symlink'), 'venus')
278
self.assertEqual(btree.id2path("e"), "grandparent/parent/file")
279
self.assertEqual(btree.path2id("grandparent/parent/file"), "e")
280
self.assertEqual(btree.get_file("e").read(), "Extra cheese\n")
281
self.assertEqual(btree.get_symlink_target('f'), 'venus')
308
283
def test_adds2(self):
309
284
"""File/inventory adds, with patch-compatibile renames"""
386
362
format.repository_format = knitrepo.RepositoryFormatKnit3()
387
363
serializer = BundleSerializerV09('0.9')
388
364
b = self.make_branch('.', format=format)
389
serializer.write(b.repository, [], {}, BytesIO())
365
serializer.write(b.repository, [], {}, StringIO())
391
367
def test_mismatched_model(self):
392
368
"""Try copying a bundle from knit2 to knit1"""
393
369
format = bzrdir.BzrDirMetaFormat1()
394
370
format.repository_format = knitrepo.RepositoryFormatKnit3()
395
371
source = self.make_branch_and_tree('source', format=format)
396
source.commit('one', rev_id=b'one-id')
397
source.commit('two', rev_id=b'two-id')
372
source.commit('one', rev_id='one-id')
373
source.commit('two', rev_id='two-id')
399
375
write_bundle(source.branch.repository, 'two-id', 'null:', text,
481
457
bundle_txt, rev_ids = self.create_bundle_text(base_rev_id, rev_id)
482
458
new_text = bundle_txt.getvalue().replace('executable:no',
483
459
'executable:yes')
484
bundle_txt = BytesIO(new_text)
460
bundle_txt = StringIO(new_text)
485
461
bundle = read_bundle(bundle_txt)
486
462
self.valid_apply_bundle(base_rev_id, bundle)
489
465
def test_non_bundle(self):
490
466
self.assertRaises(errors.NotABundle,
491
read_bundle, BytesIO(b'#!/bin/sh\n'))
467
read_bundle, StringIO('#!/bin/sh\n'))
493
469
def test_malformed(self):
494
470
self.assertRaises(errors.BadBundle, read_bundle,
495
BytesIO(b'# Bazaar revision bundle v'))
471
StringIO('# Bazaar revision bundle v'))
497
473
def test_crlf_bundle(self):
499
read_bundle(BytesIO(b'# Bazaar revision bundle v0.8\r\n'))
475
read_bundle(StringIO('# Bazaar revision bundle v0.8\r\n'))
500
476
except errors.BadBundle:
501
477
# It is currently permitted for bundles with crlf line endings to
502
478
# make read_bundle raise a BadBundle, but this should be fixed.
567
545
original_parents = to_tree.get_parent_ids()
568
546
self.assertIs(repository.has_revision(base_rev_id), True)
569
547
for rev in info.real_revisions:
570
self.assertTrue(not repository.has_revision(rev.revision_id),
571
'Revision {%s} present before applying bundle'
548
self.assert_(not repository.has_revision(rev.revision_id),
549
'Revision {%s} present before applying bundle'
573
551
merge_bundle(info, to_tree, True, merge.Merge3Merger, False, False)
575
553
for rev in info.real_revisions:
576
self.assertTrue(repository.has_revision(rev.revision_id),
577
'Missing revision {%s} after applying bundle'
554
self.assert_(repository.has_revision(rev.revision_id),
555
'Missing revision {%s} after applying bundle'
580
self.assertTrue(to_tree.branch.repository.has_revision(info.target))
558
self.assert_(to_tree.branch.repository.has_revision(info.target))
581
559
# Do we also want to verify that all the texts have been added?
583
561
self.assertEqual(original_parents + [info.target],
584
to_tree.get_parent_ids())
562
to_tree.get_parent_ids())
586
564
rev = info.real_revisions[-1]
587
565
base_tree = self.b1.repository.revision_tree(rev.revision_id)
599
577
for path, status, kind, fileid, entry in base_files:
600
578
# Check that the meta information is the same
601
self.assertEqual(base_tree.get_file_size(path, fileid),
602
to_tree.get_file_size(to_tree.id2path(fileid)))
603
self.assertEqual(base_tree.get_file_sha1(path, fileid),
604
to_tree.get_file_sha1(to_tree.id2path(fileid)))
579
self.assertEqual(base_tree.get_file_size(fileid),
580
to_tree.get_file_size(fileid))
581
self.assertEqual(base_tree.get_file_sha1(fileid),
582
to_tree.get_file_sha1(fileid))
605
583
# Check that the contents are the same
606
584
# This is pretty expensive
607
585
# self.assertEqual(base_tree.get_file(fileid).read(),
611
589
self.tree1 = self.make_branch_and_tree('b1')
612
590
self.b1 = self.tree1.branch
614
self.build_tree_contents([('b1/one', b'one\n')])
615
self.tree1.add('one', b'one-id')
616
self.tree1.set_root_id(b'root-id')
617
self.tree1.commit('add one', rev_id=b'a@cset-0-1')
592
self.build_tree_contents([('b1/one', 'one\n')])
593
self.tree1.add('one', 'one-id')
594
self.tree1.set_root_id('root-id')
595
self.tree1.commit('add one', rev_id='a@cset-0-1')
619
bundle = self.get_valid_bundle('null:', b'a@cset-0-1')
597
bundle = self.get_valid_bundle('null:', 'a@cset-0-1')
621
599
# Make sure we can handle files with spaces, tabs, other
622
600
# bogus characters
691
669
with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write('\n')
692
670
self.tree1.rename_one('sub/dir/ pre space',
693
671
'sub/ start space')
694
self.tree1.commit('Modified files', rev_id=b'a@cset-0-5')
672
self.tree1.commit('Modified files', rev_id='a@cset-0-5')
695
673
bundle = self.get_valid_bundle('a@cset-0-4', 'a@cset-0-5')
697
675
self.tree1.rename_one('sub/dir/WithCaps.txt', 'temp')
698
676
self.tree1.rename_one('with space.txt', 'WithCaps.txt')
699
677
self.tree1.rename_one('temp', 'with space.txt')
700
self.tree1.commit(u'swap filenames', rev_id=b'a@cset-0-6',
678
self.tree1.commit(u'swap filenames', rev_id='a@cset-0-6',
702
680
bundle = self.get_valid_bundle('a@cset-0-5', 'a@cset-0-6')
703
681
other = self.get_checkout('a@cset-0-5')
723
701
tt = TreeTransform(self.tree1)
724
702
tt.new_symlink(link_name, tt.root, link_target, link_id)
726
self.tree1.commit('add symlink', rev_id=b'l@cset-0-1')
704
self.tree1.commit('add symlink', rev_id='l@cset-0-1')
727
705
bundle = self.get_valid_bundle('null:', 'l@cset-0-1')
728
if getattr(bundle, 'revision_tree', None) is not None:
706
if getattr(bundle ,'revision_tree', None) is not None:
729
707
# Not all bundle formats supports revision_tree
730
708
bund_tree = bundle.revision_tree(self.b1.repository, 'l@cset-0-1')
731
self.assertEqual(link_target, bund_tree.get_symlink_target(link_name))
709
self.assertEqual(link_target, bund_tree.get_symlink_target(link_id))
733
711
tt = TreeTransform(self.tree1)
734
trans_id = tt.trans_id_tree_path(link_name)
712
trans_id = tt.trans_id_tree_file_id(link_id)
735
713
tt.adjust_path('link2', tt.root, trans_id)
736
714
tt.delete_contents(trans_id)
737
715
tt.create_symlink(new_link_target, trans_id)
739
self.tree1.commit('rename and change symlink', rev_id=b'l@cset-0-2')
717
self.tree1.commit('rename and change symlink', rev_id='l@cset-0-2')
740
718
bundle = self.get_valid_bundle('l@cset-0-1', 'l@cset-0-2')
741
if getattr(bundle, 'revision_tree', None) is not None:
719
if getattr(bundle ,'revision_tree', None) is not None:
742
720
# Not all bundle formats supports revision_tree
743
721
bund_tree = bundle.revision_tree(self.b1.repository, 'l@cset-0-2')
744
722
self.assertEqual(new_link_target,
745
bund_tree.get_symlink_target('link2'))
723
bund_tree.get_symlink_target(link_id))
747
725
tt = TreeTransform(self.tree1)
748
trans_id = tt.trans_id_tree_path('link2')
726
trans_id = tt.trans_id_tree_file_id(link_id)
749
727
tt.delete_contents(trans_id)
750
728
tt.create_symlink('jupiter', trans_id)
752
self.tree1.commit('just change symlink target', rev_id=b'l@cset-0-3')
730
self.tree1.commit('just change symlink target', rev_id='l@cset-0-3')
753
731
bundle = self.get_valid_bundle('l@cset-0-2', 'l@cset-0-3')
755
733
tt = TreeTransform(self.tree1)
756
trans_id = tt.trans_id_tree_path('link2')
734
trans_id = tt.trans_id_tree_file_id(link_id)
757
735
tt.delete_contents(trans_id)
759
self.tree1.commit('Delete symlink', rev_id=b'l@cset-0-4')
737
self.tree1.commit('Delete symlink', rev_id='l@cset-0-4')
760
738
bundle = self.get_valid_bundle('l@cset-0-3', 'l@cset-0-4')
762
740
def test_symlink_bundle(self):
778
756
tt.new_file('file2', tt.root, '\x01\n\x02\r\x03\n\x04\r\xff',
781
self.tree1.commit('add binary', rev_id=b'b@cset-0-1')
759
self.tree1.commit('add binary', rev_id='b@cset-0-1')
782
760
self.get_valid_bundle('null:', 'b@cset-0-1')
785
763
tt = TreeTransform(self.tree1)
786
trans_id = tt.trans_id_tree_path('file')
764
trans_id = tt.trans_id_tree_file_id('binary-1')
787
765
tt.delete_contents(trans_id)
789
self.tree1.commit('delete binary', rev_id=b'b@cset-0-2')
767
self.tree1.commit('delete binary', rev_id='b@cset-0-2')
790
768
self.get_valid_bundle('b@cset-0-1', 'b@cset-0-2')
792
770
# Rename & modify
793
771
tt = TreeTransform(self.tree1)
794
trans_id = tt.trans_id_tree_path('file2')
772
trans_id = tt.trans_id_tree_file_id('binary-2')
795
773
tt.adjust_path('file3', tt.root, trans_id)
796
774
tt.delete_contents(trans_id)
797
775
tt.create_file('file\rcontents\x00\n\x00', trans_id)
799
self.tree1.commit('rename and modify binary', rev_id=b'b@cset-0-3')
777
self.tree1.commit('rename and modify binary', rev_id='b@cset-0-3')
800
778
self.get_valid_bundle('b@cset-0-2', 'b@cset-0-3')
803
781
tt = TreeTransform(self.tree1)
804
trans_id = tt.trans_id_tree_path('file3')
782
trans_id = tt.trans_id_tree_file_id('binary-2')
805
783
tt.delete_contents(trans_id)
806
784
tt.create_file('\x00file\rcontents', trans_id)
808
self.tree1.commit('just modify binary', rev_id=b'b@cset-0-4')
786
self.tree1.commit('just modify binary', rev_id='b@cset-0-4')
809
787
self.get_valid_bundle('b@cset-0-3', 'b@cset-0-4')
817
795
tt = TreeTransform(self.tree1)
818
796
tt.new_file('file', tt.root, 'file', 'file')
820
self.tree1.commit('create file', rev_id=b'a@lmod-0-1')
798
self.tree1.commit('create file', rev_id='a@lmod-0-1')
822
800
tt = TreeTransform(self.tree1)
823
trans_id = tt.trans_id_tree_path('file')
801
trans_id = tt.trans_id_tree_file_id('file')
824
802
tt.delete_contents(trans_id)
825
803
tt.create_file('file2', trans_id)
827
self.tree1.commit('modify text', rev_id=b'a@lmod-0-2a')
805
self.tree1.commit('modify text', rev_id='a@lmod-0-2a')
829
807
other = self.get_checkout('a@lmod-0-1')
830
808
tt = TreeTransform(other)
831
trans_id = tt.trans_id_tree_path('file2')
809
trans_id = tt.trans_id_tree_file_id('file')
832
810
tt.delete_contents(trans_id)
833
811
tt.create_file('file2', trans_id)
835
other.commit('modify text in another tree', rev_id=b'a@lmod-0-2b')
813
other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
836
814
self.tree1.merge_from_branch(other.branch)
837
self.tree1.commit(u'Merge', rev_id=b'a@lmod-0-3',
815
self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
839
self.tree1.commit(u'Merge', rev_id=b'a@lmod-0-4')
817
self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
840
818
bundle = self.get_valid_bundle('a@lmod-0-2a', 'a@lmod-0-4')
842
820
def test_hide_history(self):
843
821
self.tree1 = self.make_branch_and_tree('b1')
844
822
self.b1 = self.tree1.branch
846
with open('b1/one', 'wb') as f: f.write(b'one\n')
824
with open('b1/one', 'wb') as f: f.write('one\n')
847
825
self.tree1.add('one')
848
self.tree1.commit('add file', rev_id=b'a@cset-0-1')
849
with open('b1/one', 'wb') as f: f.write(b'two\n')
850
self.tree1.commit('modify', rev_id=b'a@cset-0-2')
851
with open('b1/one', 'wb') as f: f.write(b'three\n')
852
self.tree1.commit('modify', rev_id=b'a@cset-0-3')
853
bundle_file = BytesIO()
826
self.tree1.commit('add file', rev_id='a@cset-0-1')
827
with open('b1/one', 'wb') as f: f.write('two\n')
828
self.tree1.commit('modify', rev_id='a@cset-0-2')
829
with open('b1/one', 'wb') as f: f.write('three\n')
830
self.tree1.commit('modify', rev_id='a@cset-0-3')
831
bundle_file = StringIO()
854
832
rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
855
833
'a@cset-0-1', bundle_file, format=self.format)
856
834
self.assertNotContainsRe(bundle_file.getvalue(), '\btwo\b')
894
872
f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
895
873
f.write(u'Modified \xb5\n'.encode('utf8'))
897
self.tree1.commit(u'modified', rev_id=b'i18n-2')
875
self.tree1.commit(u'modified', rev_id='i18n-2')
899
877
bundle = self.get_valid_bundle('i18n-1', 'i18n-2')
902
880
self.tree1.rename_one(u'with Dod\N{Euro Sign}', u'B\N{Euro Sign}gfors')
903
self.tree1.commit(u'renamed, the new i18n man', rev_id=b'i18n-3',
881
self.tree1.commit(u'renamed, the new i18n man', rev_id='i18n-3',
904
882
committer=u'Erik B\xe5gfors')
906
884
bundle = self.get_valid_bundle('i18n-2', 'i18n-3')
909
887
self.tree1.remove([u'B\N{Euro Sign}gfors'])
910
self.tree1.commit(u'removed', rev_id=b'i18n-4')
888
self.tree1.commit(u'removed', rev_id='i18n-4')
912
890
bundle = self.get_valid_bundle('i18n-3', 'i18n-4')
928
906
# once we actually support them
931
self.tree1.commit('funky whitespace', rev_id=b'white-1')
909
self.tree1.commit('funky whitespace', rev_id='white-1')
933
911
bundle = self.get_valid_bundle('null:', 'white-1')
936
914
with open('b1/trailing space ', 'ab') as f: f.write('add some text\n')
937
self.tree1.commit('add text', rev_id=b'white-2')
915
self.tree1.commit('add text', rev_id='white-2')
939
917
bundle = self.get_valid_bundle('white-1', 'white-2')
942
920
self.tree1.rename_one('trailing space ', ' start and end space ')
943
self.tree1.commit('rename', rev_id=b'white-3')
921
self.tree1.commit('rename', rev_id='white-3')
945
923
bundle = self.get_valid_bundle('white-2', 'white-3')
948
926
self.tree1.remove([' start and end space '])
949
self.tree1.commit('removed', rev_id=b'white-4')
927
self.tree1.commit('removed', rev_id='white-4')
951
929
bundle = self.get_valid_bundle('white-3', 'white-4')
978
956
def test_bundle_root_id(self):
979
957
self.tree1 = self.make_branch_and_tree('b1')
980
958
self.b1 = self.tree1.branch
981
self.tree1.commit('message', rev_id=b'revid1')
959
self.tree1.commit('message', rev_id='revid1')
982
960
bundle = self.get_valid_bundle('null:', 'revid1')
983
961
tree = self.get_bundle_tree(bundle, 'revid1')
984
root_revision = tree.get_file_revision(u'', tree.get_root_id())
962
root_revision = tree.get_file_revision(tree.get_root_id())
985
963
self.assertEqual('revid1', root_revision)
987
965
def test_install_revisions(self):
988
966
self.tree1 = self.make_branch_and_tree('b1')
989
967
self.b1 = self.tree1.branch
990
self.tree1.commit('message', rev_id=b'rev2a')
968
self.tree1.commit('message', rev_id='rev2a')
991
969
bundle = self.get_valid_bundle('null:', 'rev2a')
992
970
branch2 = self.make_branch('b2')
993
971
self.assertFalse(branch2.repository.has_revision('rev2a'))
1055
1033
def test_bundle_with_ghosts(self):
1056
1034
tree = self.make_branch_and_tree('tree')
1057
1035
self.b1 = tree.branch
1058
self.build_tree_contents([('tree/file', b'content1')])
1036
self.build_tree_contents([('tree/file', 'content1')])
1059
1037
tree.add(['file'])
1060
1038
tree.commit('rev1')
1061
self.build_tree_contents([('tree/file', b'content2')])
1062
tree.add_parent_tree_id(b'ghost')
1063
tree.commit('rev2', rev_id=b'rev2')
1064
bundle = self.get_valid_bundle(b'null:', b'rev2')
1039
self.build_tree_contents([('tree/file', 'content2')])
1040
tree.add_parent_tree_id('ghost')
1041
tree.commit('rev2', rev_id='rev2')
1042
bundle = self.get_valid_bundle('null:', 'rev2')
1066
1044
def make_simple_tree(self, format=None):
1067
1045
tree = self.make_branch_and_tree('b1', format=format)
1165
1143
self.tree1 = self.make_branch_and_tree('tree')
1166
1144
self.b1 = self.tree1.branch
1167
1145
# rev1 is not present in bundle, done by fetch
1168
self.build_tree_contents([('tree/file2', b'contents1')])
1169
self.tree1.add('file2', b'file2-id')
1170
self.tree1.commit('rev1', rev_id=b'reva')
1171
self.build_tree_contents([('tree/file3', b'contents2')])
1146
self.build_tree_contents([('tree/file2', 'contents1')])
1147
self.tree1.add('file2', 'file2-id')
1148
self.tree1.commit('rev1', rev_id='reva')
1149
self.build_tree_contents([('tree/file3', 'contents2')])
1172
1150
# rev2 is present in bundle, and done by fetch
1173
1151
# having file1 in the bunle causes file1's versionedfile to be opened.
1174
self.tree1.add('file3', b'file3-id')
1152
self.tree1.add('file3', 'file3-id')
1175
1153
self.tree1.commit('rev2')
1176
1154
# Updating file2 should not cause an attempt to add to file1's vf
1177
target = self.tree1.controldir.sprout('target').open_workingtree()
1178
self.build_tree_contents([('tree/file2', b'contents3')])
1179
self.tree1.commit('rev3', rev_id=b'rev3')
1155
target = self.tree1.bzrdir.sprout('target').open_workingtree()
1156
self.build_tree_contents([('tree/file2', 'contents3')])
1157
self.tree1.commit('rev3', rev_id='rev3')
1180
1158
bundle = self.get_valid_bundle('reva', 'rev3')
1181
1159
if getattr(bundle, 'get_bundle_reader', None) is None:
1182
1160
raise tests.TestSkipped('Bundle format cannot provide reader')
1183
1161
# be sure that file1 comes before file2
1184
1162
for b, m, k, r, f in bundle.get_bundle_reader().iter_records():
1185
if f == b'file3-id':
1187
self.assertNotEqual(f, b'file2-id')
1165
self.assertNotEqual(f, 'file2-id')
1188
1166
bundle.install_revisions(target.branch.repository)
1404
1382
def test_creation(self):
1405
1383
tree = self.make_branch_and_tree('tree')
1406
self.build_tree_contents([('tree/file', b'contents1\nstatic\n')])
1384
self.build_tree_contents([('tree/file', 'contents1\nstatic\n')])
1407
1385
tree.add('file', 'fileid-2')
1408
tree.commit('added file', rev_id=b'rev1')
1409
self.build_tree_contents([('tree/file', b'contents2\nstatic\n')])
1410
tree.commit('changed file', rev_id=b'rev2')
1386
tree.commit('added file', rev_id='rev1')
1387
self.build_tree_contents([('tree/file', 'contents2\nstatic\n')])
1388
tree.commit('changed file', rev_id='rev2')
1412
1390
serializer = BundleSerializerV4('1.0')
1413
1391
serializer.write(tree.branch.repository, ['rev1', 'rev2'], {}, s)
1445
1423
def test_copy_signatures(self):
1446
1424
tree_a = self.make_branch_and_tree('tree_a')
1448
import breezy.commit as commit
1449
oldstrategy = breezy.gpg.GPGStrategy
1426
import bzrlib.commit as commit
1427
oldstrategy = bzrlib.gpg.GPGStrategy
1450
1428
branch = tree_a.branch
1451
1429
repo_a = branch.repository
1452
tree_a.commit("base", allow_pointless=True, rev_id=b'A')
1430
tree_a.commit("base", allow_pointless=True, rev_id='A')
1453
1431
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
1455
from ..testament import Testament
1433
from bzrlib.testament import Testament
1456
1434
# monkey patch gpg signing mechanism
1457
breezy.gpg.GPGStrategy = breezy.gpg.LoopbackGPGStrategy
1435
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
1458
1436
new_config = test_commit.MustSignConfig()
1459
1437
commit.Commit(config_stack=new_config).commit(message="base",
1460
1438
allow_pointless=True,
1462
1440
working_tree=tree_a)
1463
1441
def sign(text):
1464
return breezy.gpg.LoopbackGPGStrategy(None).sign(text)
1442
return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
1465
1443
self.assertTrue(repo_a.has_signature_for_revision_id('B'))
1467
breezy.gpg.GPGStrategy = oldstrategy
1445
bzrlib.gpg.GPGStrategy = oldstrategy
1468
1446
tree_b = self.make_branch_and_tree('tree_b')
1469
1447
repo_b = tree_b.branch.repository
1471
1449
serializer = BundleSerializerV4('4')
1472
1450
serializer.write(tree_a.branch.repository, ['A', 'B'], {}, s)
1512
1490
def make_merged_branch(self):
1513
1491
builder = self.make_branch_builder('source')
1514
1492
builder.start_series()
1515
builder.build_snapshot(None, [
1493
builder.build_snapshot('a@cset-0-1', None, [
1516
1494
('add', ('', 'root-id', 'directory', None)),
1517
1495
('add', ('file', 'file-id', 'file', 'original content\n')),
1518
], revision_id='a@cset-0-1')
1519
builder.build_snapshot(['a@cset-0-1'], [
1520
('modify', ('file', 'new-content\n')),
1521
], revision_id='a@cset-0-2a')
1522
builder.build_snapshot(['a@cset-0-1'], [
1523
('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1524
], revision_id='a@cset-0-2b')
1525
builder.build_snapshot(['a@cset-0-2a', 'a@cset-0-2b'], [
1526
('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1527
], revision_id='a@cset-0-3')
1497
builder.build_snapshot('a@cset-0-2a', ['a@cset-0-1'], [
1498
('modify', ('file-id', 'new-content\n')),
1500
builder.build_snapshot('a@cset-0-2b', ['a@cset-0-1'], [
1501
('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1503
builder.build_snapshot('a@cset-0-3', ['a@cset-0-2a', 'a@cset-0-2b'], [
1504
('add', ('other-file', 'file2-id', 'file', 'file2-content\n')),
1528
1506
builder.finish_series()
1529
1507
self.b1 = builder.get_branch()
1530
1508
self.b1.lock_read()
1782
1760
fileobj.seek(0)
1783
1761
reader = v4.BundleReader(fileobj, stream_input=True)
1784
1762
record_iter = reader.iter_records()
1785
record = next(record_iter)
1763
record = record_iter.next()
1786
1764
self.assertEqual((None, {'foo': 'bar', 'storage_kind': 'header'},
1787
1765
'info', None, None), record)
1788
record = next(record_iter)
1766
record = record_iter.next()
1789
1767
self.assertEqual(("Record body", {'storage_kind': 'fulltext',
1790
1768
'parents': ['1', '3']}, 'file', 'revid', 'fileid'),
1793
1771
def test_roundtrip_record_memory_hungry(self):
1772
fileobj = StringIO()
1795
1773
writer = v4.BundleWriter(fileobj)
1797
1775
writer.add_info_record(foo='bar')