142
140
self.assertEqual(imaginary_id, imaginary_id2)
143
141
self.assertEqual(root, transform.get_tree_parent(imaginary_id))
144
142
self.assertEqual('directory', transform.final_kind(root))
145
self.assertEqual(self.wt.path2id(''), transform.final_file_id(root))
143
self.assertEqual(self.wt.get_root_id(), transform.final_file_id(root))
146
144
trans_id = transform.create_path('name', root)
147
145
self.assertIs(transform.final_file_id(trans_id), None)
148
146
self.assertIs(None, transform.final_kind(trans_id))
149
transform.create_file([b'contents'], trans_id)
147
transform.create_file('contents', trans_id)
150
148
transform.set_executability(True, trans_id)
151
transform.version_file(b'my_pretties', trans_id)
149
transform.version_file('my_pretties', trans_id)
152
150
self.assertRaises(DuplicateKey, transform.version_file,
153
b'my_pretties', trans_id)
154
self.assertEqual(transform.final_file_id(trans_id), b'my_pretties')
151
'my_pretties', trans_id)
152
self.assertEqual(transform.final_file_id(trans_id), 'my_pretties')
155
153
self.assertEqual(transform.final_parent(trans_id), root)
156
154
self.assertIs(transform.final_parent(root), ROOT_PARENT)
157
155
self.assertIs(transform.get_tree_parent(root), ROOT_PARENT)
158
156
oz_id = transform.create_path('oz', root)
159
157
transform.create_directory(oz_id)
160
transform.version_file(b'ozzie', oz_id)
158
transform.version_file('ozzie', oz_id)
161
159
trans_id2 = transform.create_path('name2', root)
162
transform.create_file([b'contents'], trans_id2)
160
transform.create_file('contents', trans_id2)
163
161
transform.set_executability(False, trans_id2)
164
transform.version_file(b'my_pretties2', trans_id2)
162
transform.version_file('my_pretties2', trans_id2)
165
163
modified_paths = transform.apply().modified_paths
166
with self.wt.get_file('name') as f:
167
self.assertEqual(b'contents', f.read())
168
self.assertEqual(self.wt.path2id('name'), b'my_pretties')
169
self.assertIs(self.wt.is_executable('name'), True)
170
self.assertIs(self.wt.is_executable('name2'), False)
164
self.assertEqual('contents', self.wt.get_file_byname('name').read())
165
self.assertEqual(self.wt.path2id('name'), 'my_pretties')
166
self.assertIs(self.wt.is_executable('my_pretties'), True)
167
self.assertIs(self.wt.is_executable('my_pretties2'), False)
171
168
self.assertEqual('directory', file_kind(self.wt.abspath('oz')))
172
169
self.assertEqual(len(modified_paths), 3)
173
tree_mod_paths = [self.wt.abspath(self.wt.id2path(f)) for f in
174
(b'ozzie', b'my_pretties', b'my_pretties2')]
170
tree_mod_paths = [self.wt.id2abspath(f) for f in
171
('ozzie', 'my_pretties', 'my_pretties2')]
175
172
self.assertSubset(tree_mod_paths, modified_paths)
176
173
# is it safe to finalize repeatedly?
177
174
transform.finalize()
246
242
# Roll back the clock, so that we know everything is being set to the
248
244
transform._creation_mtime = creation_mtime = time.time() - 20.0
249
transform.create_file([b'content-one'],
245
transform.create_file('content-one',
250
246
transform.create_path('one', root))
251
time.sleep(1) # *ugly*
252
transform.create_file([b'content-two'],
247
time.sleep(1) # *ugly*
248
transform.create_file('content-two',
253
249
transform.create_path('two', root))
254
250
transform.apply()
255
fo, st1 = self.wt.get_file_with_stat('one', filtered=False)
251
fo, st1 = self.wt.get_file_with_stat(None, path='one', filtered=False)
257
fo, st2 = self.wt.get_file_with_stat('two', filtered=False)
253
fo, st2 = self.wt.get_file_with_stat(None, path='two', filtered=False)
259
255
# We only guarantee 2s resolution
261
abs(creation_mtime - st1.st_mtime) < 2.0,
256
self.assertTrue(abs(creation_mtime - st1.st_mtime) < 2.0,
262
257
"%s != %s within 2 seconds" % (creation_mtime, st1.st_mtime))
263
258
# But if we have more than that, all files should get the same result
264
259
self.assertEqual(st1.st_mtime, st2.st_mtime)
266
261
def test_change_root_id(self):
267
262
transform, root = self.get_transform()
268
self.assertNotEqual(b'new-root-id', self.wt.path2id(''))
269
transform.new_directory('', ROOT_PARENT, b'new-root-id')
263
self.assertNotEqual('new-root-id', self.wt.get_root_id())
264
transform.new_directory('', ROOT_PARENT, 'new-root-id')
270
265
transform.delete_contents(root)
271
266
transform.unversion_file(root)
272
267
transform.fixup_new_roots()
273
268
transform.apply()
274
self.assertEqual(b'new-root-id', self.wt.path2id(''))
269
self.assertEqual('new-root-id', self.wt.get_root_id())
276
271
def test_change_root_id_add_files(self):
277
272
transform, root = self.get_transform()
278
self.assertNotEqual(b'new-root-id', self.wt.path2id(''))
279
new_trans_id = transform.new_directory('', ROOT_PARENT, b'new-root-id')
280
transform.new_file('file', new_trans_id, [b'new-contents\n'],
273
self.assertNotEqual('new-root-id', self.wt.get_root_id())
274
new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
275
transform.new_file('file', new_trans_id, ['new-contents\n'],
282
277
transform.delete_contents(root)
283
278
transform.unversion_file(root)
284
279
transform.fixup_new_roots()
285
280
transform.apply()
286
self.assertEqual(b'new-root-id', self.wt.path2id(''))
287
self.assertEqual(b'new-file-id', self.wt.path2id('file'))
288
self.assertFileEqual(b'new-contents\n', self.wt.abspath('file'))
281
self.assertEqual('new-root-id', self.wt.get_root_id())
282
self.assertEqual('new-file-id', self.wt.path2id('file'))
283
self.assertFileEqual('new-contents\n', self.wt.abspath('file'))
290
285
def test_add_two_roots(self):
291
286
transform, root = self.get_transform()
292
transform.new_directory('', ROOT_PARENT, b'new-root-id')
293
transform.new_directory('', ROOT_PARENT, b'alt-root-id')
287
new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
288
new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
294
289
self.assertRaises(ValueError, transform.fixup_new_roots)
296
291
def test_retain_existing_root(self):
297
292
tt, root = self.get_transform()
299
tt.new_directory('', ROOT_PARENT, b'new-root-id')
294
tt.new_directory('', ROOT_PARENT, 'new-root-id')
300
295
tt.fixup_new_roots()
301
self.assertNotEqual(b'new-root-id', tt.final_file_id(tt.root))
296
self.assertNotEqual('new-root-id', tt.final_file_id(tt.root))
303
298
def test_retain_existing_root_added_file(self):
304
299
tt, root = self.get_transform()
305
new_trans_id = tt.new_directory('', ROOT_PARENT, b'new-root-id')
306
child = tt.new_directory('child', new_trans_id, b'child-id')
300
new_trans_id = tt.new_directory('', ROOT_PARENT, 'new-root-id')
301
child = tt.new_directory('child', new_trans_id, 'child-id')
307
302
tt.fixup_new_roots()
308
303
self.assertEqual(tt.root, tt.final_parent(child))
310
305
def test_add_unversioned_root(self):
311
306
transform, root = self.get_transform()
312
transform.new_directory('', ROOT_PARENT, None)
307
new_trans_id = transform.new_directory('', ROOT_PARENT, None)
313
308
transform.delete_contents(transform.root)
314
309
transform.fixup_new_roots()
315
310
self.assertNotIn(transform.root, transform._new_id)
317
312
def test_remove_root_fixup(self):
318
313
transform, root = self.get_transform()
319
old_root_id = self.wt.path2id('')
320
self.assertNotEqual(b'new-root-id', old_root_id)
314
old_root_id = self.wt.get_root_id()
315
self.assertNotEqual('new-root-id', old_root_id)
321
316
transform.delete_contents(root)
322
317
transform.unversion_file(root)
323
318
transform.fixup_new_roots()
324
319
transform.apply()
325
self.assertEqual(old_root_id, self.wt.path2id(''))
320
self.assertEqual(old_root_id, self.wt.get_root_id())
327
322
transform, root = self.get_transform()
328
transform.new_directory('', ROOT_PARENT, b'new-root-id')
329
transform.new_directory('', ROOT_PARENT, b'alt-root-id')
323
new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
324
new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
330
325
self.assertRaises(ValueError, transform.fixup_new_roots)
332
327
def test_fixup_new_roots_permits_empty_tree(self):
374
369
transform, root = self.get_transform()
375
370
self.wt.lock_tree_write()
376
371
self.addCleanup(self.wt.unlock)
377
transform.new_file('name', root, [b'contents'], b'my_pretties', True)
378
oz = transform.new_directory('oz', root, b'oz-id')
379
dorothy = transform.new_directory('dorothy', oz, b'dorothy-id')
380
transform.new_file('toto', dorothy, [b'toto-contents'], b'toto-id',
372
trans_id = transform.new_file('name', root, 'contents',
374
oz = transform.new_directory('oz', root, 'oz-id')
375
dorothy = transform.new_directory('dorothy', oz, 'dorothy-id')
376
toto = transform.new_file('toto', dorothy, 'toto-contents',
383
379
self.assertEqual(len(transform.find_conflicts()), 0)
384
380
transform.apply()
385
381
self.assertRaises(ReusingTransform, transform.find_conflicts)
386
with open(self.wt.abspath('name'), 'r') as f:
387
self.assertEqual('contents', f.read())
388
self.assertEqual(self.wt.path2id('name'), b'my_pretties')
389
self.assertIs(self.wt.is_executable('name'), True)
390
self.assertEqual(self.wt.path2id('oz'), b'oz-id')
391
self.assertEqual(self.wt.path2id('oz/dorothy'), b'dorothy-id')
392
self.assertEqual(self.wt.path2id('oz/dorothy/toto'), b'toto-id')
382
self.assertEqual('contents', file(self.wt.abspath('name')).read())
383
self.assertEqual(self.wt.path2id('name'), 'my_pretties')
384
self.assertIs(self.wt.is_executable('my_pretties'), True)
385
self.assertEqual(self.wt.path2id('oz'), 'oz-id')
386
self.assertEqual(self.wt.path2id('oz/dorothy'), 'dorothy-id')
387
self.assertEqual(self.wt.path2id('oz/dorothy/toto'), 'toto-id')
394
self.assertEqual(b'toto-contents',
395
self.wt.get_file('oz/dorothy/toto').read())
396
self.assertIs(self.wt.is_executable('oz/dorothy/toto'), False)
389
self.assertEqual('toto-contents',
390
self.wt.get_file_byname('oz/dorothy/toto').read())
391
self.assertIs(self.wt.is_executable('toto-id'), False)
398
393
def test_tree_reference(self):
399
394
transform, root = self.get_transform()
400
395
tree = transform._tree
401
trans_id = transform.new_directory('reference', root, b'subtree-id')
402
transform.set_tree_reference(b'subtree-revision', trans_id)
396
trans_id = transform.new_directory('reference', root, 'subtree-id')
397
transform.set_tree_reference('subtree-revision', trans_id)
403
398
transform.apply()
405
400
self.addCleanup(tree.unlock)
408
tree.root_inventory.get_entry(b'subtree-id').reference_revision)
401
self.assertEqual('subtree-revision',
402
tree.root_inventory['subtree-id'].reference_revision)
410
404
def test_conflicts(self):
411
405
transform, root = self.get_transform()
412
trans_id = transform.new_file('name', root, [b'contents'],
406
trans_id = transform.new_file('name', root, 'contents',
414
408
self.assertEqual(len(transform.find_conflicts()), 0)
415
trans_id2 = transform.new_file('name', root, [b'Crontents'], b'toto')
409
trans_id2 = transform.new_file('name', root, 'Crontents', 'toto')
416
410
self.assertEqual(transform.find_conflicts(),
417
411
[('duplicate', trans_id, trans_id2, 'name')])
418
412
self.assertRaises(MalformedTransform, transform.apply)
630
623
create_tree, root = self.get_transform()
632
625
root = create_tree.root
633
create_tree.new_file('name1', root, [b'hello1'], b'name1')
634
create_tree.new_file('name2', root, [b'hello2'], b'name2')
635
ddir = create_tree.new_directory('dying_directory', root, b'ddir')
636
create_tree.new_file('dying_file', ddir, [b'goodbye1'], b'dfile')
637
create_tree.new_file('moving_file', ddir, [b'later1'], b'mfile')
638
create_tree.new_file('moving_file2', root, [b'later2'], b'mfile2')
626
create_tree.new_file('name1', root, 'hello1', 'name1')
627
create_tree.new_file('name2', root, 'hello2', 'name2')
628
ddir = create_tree.new_directory('dying_directory', root, 'ddir')
629
create_tree.new_file('dying_file', ddir, 'goodbye1', 'dfile')
630
create_tree.new_file('moving_file', ddir, 'later1', 'mfile')
631
create_tree.new_file('moving_file2', root, 'later2', 'mfile2')
639
632
create_tree.apply()
641
mangle_tree, root = self.get_transform()
634
mangle_tree,root = self.get_transform()
642
635
root = mangle_tree.root
644
name1 = mangle_tree.trans_id_tree_path('name1')
645
name2 = mangle_tree.trans_id_tree_path('name2')
637
name1 = mangle_tree.trans_id_tree_file_id('name1')
638
name2 = mangle_tree.trans_id_tree_file_id('name2')
646
639
mangle_tree.adjust_path('name2', root, name1)
647
640
mangle_tree.adjust_path('name1', root, name2)
649
# tests for deleting parent directories
650
ddir = mangle_tree.trans_id_tree_path('dying_directory')
642
#tests for deleting parent directories
643
ddir = mangle_tree.trans_id_tree_file_id('ddir')
651
644
mangle_tree.delete_contents(ddir)
652
dfile = mangle_tree.trans_id_tree_path('dying_directory/dying_file')
645
dfile = mangle_tree.trans_id_tree_file_id('dfile')
653
646
mangle_tree.delete_versioned(dfile)
654
647
mangle_tree.unversion_file(dfile)
655
mfile = mangle_tree.trans_id_tree_path('dying_directory/moving_file')
648
mfile = mangle_tree.trans_id_tree_file_id('mfile')
656
649
mangle_tree.adjust_path('mfile', root, mfile)
658
# tests for adding parent directories
659
newdir = mangle_tree.new_directory('new_directory', root, b'newdir')
660
mfile2 = mangle_tree.trans_id_tree_path('moving_file2')
651
#tests for adding parent directories
652
newdir = mangle_tree.new_directory('new_directory', root, 'newdir')
653
mfile2 = mangle_tree.trans_id_tree_file_id('mfile2')
661
654
mangle_tree.adjust_path('mfile2', newdir, mfile2)
662
mangle_tree.new_file('newfile', newdir, [b'hello3'], b'dfile')
663
self.assertEqual(mangle_tree.final_file_id(mfile2), b'mfile2')
655
mangle_tree.new_file('newfile', newdir, 'hello3', 'dfile')
656
self.assertEqual(mangle_tree.final_file_id(mfile2), 'mfile2')
664
657
self.assertEqual(mangle_tree.final_parent(mfile2), newdir)
665
self.assertEqual(mangle_tree.final_file_id(mfile2), b'mfile2')
658
self.assertEqual(mangle_tree.final_file_id(mfile2), 'mfile2')
666
659
mangle_tree.apply()
667
with open(self.wt.abspath('name1'), 'r') as f:
668
self.assertEqual(f.read(), 'hello2')
669
with open(self.wt.abspath('name2'), 'r') as f:
670
self.assertEqual(f.read(), 'hello1')
671
mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
660
self.assertEqual(file(self.wt.abspath('name1')).read(), 'hello2')
661
self.assertEqual(file(self.wt.abspath('name2')).read(), 'hello1')
662
mfile2_path = self.wt.abspath(pathjoin('new_directory','mfile2'))
672
663
self.assertEqual(mangle_tree.final_parent(mfile2), newdir)
673
with open(mfile2_path, 'r') as f:
674
self.assertEqual(f.read(), 'later2')
675
self.assertEqual(self.wt.id2path(b'mfile2'), 'new_directory/mfile2')
676
self.assertEqual(self.wt.path2id('new_directory/mfile2'), b'mfile2')
677
newfile_path = self.wt.abspath(pathjoin('new_directory', 'newfile'))
678
with open(newfile_path, 'r') as f:
679
self.assertEqual(f.read(), 'hello3')
680
self.assertEqual(self.wt.path2id('dying_directory'), b'ddir')
664
self.assertEqual(file(mfile2_path).read(), 'later2')
665
self.assertEqual(self.wt.id2path('mfile2'), 'new_directory/mfile2')
666
self.assertEqual(self.wt.path2id('new_directory/mfile2'), 'mfile2')
667
newfile_path = self.wt.abspath(pathjoin('new_directory','newfile'))
668
self.assertEqual(file(newfile_path).read(), 'hello3')
669
self.assertEqual(self.wt.path2id('dying_directory'), 'ddir')
681
670
self.assertIs(self.wt.path2id('dying_directory/dying_file'), None)
682
mfile2_path = self.wt.abspath(pathjoin('new_directory', 'mfile2'))
671
mfile2_path = self.wt.abspath(pathjoin('new_directory','mfile2'))
684
673
def test_both_rename(self):
685
create_tree, root = self.get_transform()
686
newdir = create_tree.new_directory('selftest', root, b'selftest-id')
687
create_tree.new_file('blackbox.py', newdir, [
688
b'hello1'], b'blackbox-id')
674
create_tree,root = self.get_transform()
675
newdir = create_tree.new_directory('selftest', root, 'selftest-id')
676
create_tree.new_file('blackbox.py', newdir, 'hello1', 'blackbox-id')
689
677
create_tree.apply()
690
mangle_tree, root = self.get_transform()
691
selftest = mangle_tree.trans_id_tree_path('selftest')
692
blackbox = mangle_tree.trans_id_tree_path('selftest/blackbox.py')
678
mangle_tree,root = self.get_transform()
679
selftest = mangle_tree.trans_id_tree_file_id('selftest-id')
680
blackbox = mangle_tree.trans_id_tree_file_id('blackbox-id')
693
681
mangle_tree.adjust_path('test', root, selftest)
694
682
mangle_tree.adjust_path('test_too_much', root, selftest)
695
683
mangle_tree.set_executability(True, blackbox)
696
684
mangle_tree.apply()
698
686
def test_both_rename2(self):
699
create_tree, root = self.get_transform()
700
breezy = create_tree.new_directory('breezy', root, b'breezy-id')
701
tests = create_tree.new_directory('tests', breezy, b'tests-id')
702
blackbox = create_tree.new_directory('blackbox', tests, b'blackbox-id')
703
create_tree.new_file('test_too_much.py', blackbox, [b'hello1'],
687
create_tree,root = self.get_transform()
688
brzlib = create_tree.new_directory('brzlib', root, 'bzrlib-id')
689
tests = create_tree.new_directory('tests', brzlib, 'tests-id')
690
blackbox = create_tree.new_directory('blackbox', tests, 'blackbox-id')
691
create_tree.new_file('test_too_much.py', blackbox, 'hello1',
705
693
create_tree.apply()
706
mangle_tree, root = self.get_transform()
707
breezy = mangle_tree.trans_id_tree_path('breezy')
708
tests = mangle_tree.trans_id_tree_path('breezy/tests')
709
test_too_much = mangle_tree.trans_id_tree_path(
710
'breezy/tests/blackbox/test_too_much.py')
711
mangle_tree.adjust_path('selftest', breezy, tests)
694
mangle_tree,root = self.get_transform()
695
brzlib = mangle_tree.trans_id_tree_file_id('brzlib-id')
696
tests = mangle_tree.trans_id_tree_file_id('tests-id')
697
test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id')
698
mangle_tree.adjust_path('selftest', brzlib, tests)
712
699
mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
713
700
mangle_tree.set_executability(True, test_too_much)
714
701
mangle_tree.apply()
716
703
def test_both_rename3(self):
717
create_tree, root = self.get_transform()
718
tests = create_tree.new_directory('tests', root, b'tests-id')
719
create_tree.new_file('test_too_much.py', tests, [b'hello1'],
704
create_tree,root = self.get_transform()
705
tests = create_tree.new_directory('tests', root, 'tests-id')
706
create_tree.new_file('test_too_much.py', tests, 'hello1',
721
708
create_tree.apply()
722
mangle_tree, root = self.get_transform()
723
tests = mangle_tree.trans_id_tree_path('tests')
724
test_too_much = mangle_tree.trans_id_tree_path(
725
'tests/test_too_much.py')
709
mangle_tree,root = self.get_transform()
710
tests = mangle_tree.trans_id_tree_file_id('tests-id')
711
test_too_much = mangle_tree.trans_id_tree_file_id('test_too_much-id')
726
712
mangle_tree.adjust_path('selftest', root, tests)
727
713
mangle_tree.adjust_path('blackbox.py', tests, test_too_much)
728
714
mangle_tree.set_executability(True, test_too_much)
925
913
def test_resolve_conflicts_wrong_existing_parent_kind(self):
926
914
tt = self.prepare_wrong_parent_kind()
927
915
raw_conflicts = resolve_conflicts(tt)
928
self.assertEqual({('non-directory parent', 'Created directory',
929
'new-3')}, raw_conflicts)
916
self.assertEqual(set([('non-directory parent', 'Created directory',
917
'new-3')]), raw_conflicts)
930
918
cooked_conflicts = cook_conflicts(raw_conflicts, tt)
931
919
self.assertEqual([NonDirectoryParent('Created directory', 'parent.new',
932
b'parent-id')], cooked_conflicts)
920
'parent-id')], cooked_conflicts)
934
self.assertFalse(self.wt.is_versioned('parent'))
935
self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
922
self.assertEqual(None, self.wt.path2id('parent'))
923
self.assertEqual('parent-id', self.wt.path2id('parent.new'))
937
925
def test_resolve_conflicts_wrong_new_parent_kind(self):
938
926
tt, root = self.get_transform()
939
parent_id = tt.new_directory('parent', root, b'parent-id')
940
tt.new_file('child,', parent_id, [b'contents2'], b'file-id')
927
parent_id = tt.new_directory('parent', root, 'parent-id')
928
tt.new_file('child,', parent_id, 'contents2', 'file-id')
942
930
tt, root = self.get_transform()
943
parent_id = tt.trans_id_file_id(b'parent-id')
931
parent_id = tt.trans_id_file_id('parent-id')
944
932
tt.delete_contents(parent_id)
945
tt.create_file([b'contents'], parent_id)
933
tt.create_file('contents', parent_id)
946
934
raw_conflicts = resolve_conflicts(tt)
947
self.assertEqual({('non-directory parent', 'Created directory',
948
'new-3')}, raw_conflicts)
935
self.assertEqual(set([('non-directory parent', 'Created directory',
936
'new-3')]), raw_conflicts)
950
self.assertFalse(self.wt.is_versioned('parent'))
951
self.assertEqual(b'parent-id', self.wt.path2id('parent.new'))
938
self.assertEqual(None, self.wt.path2id('parent'))
939
self.assertEqual('parent-id', self.wt.path2id('parent.new'))
953
941
def test_resolve_conflicts_wrong_parent_kind_unversioned(self):
954
942
tt, root = self.get_transform()
955
943
parent_id = tt.new_directory('parent', root)
956
tt.new_file('child,', parent_id, [b'contents2'])
944
tt.new_file('child,', parent_id, 'contents2')
958
946
tt, root = self.get_transform()
959
947
parent_id = tt.trans_id_tree_path('parent')
960
948
tt.delete_contents(parent_id)
961
tt.create_file([b'contents'], parent_id)
949
tt.create_file('contents', parent_id)
962
950
resolve_conflicts(tt)
964
self.assertFalse(self.wt.is_versioned('parent'))
965
self.assertFalse(self.wt.is_versioned('parent.new'))
952
self.assertIs(None, self.wt.path2id('parent'))
953
self.assertIs(None, self.wt.path2id('parent.new'))
967
955
def test_resolve_conflicts_missing_parent(self):
968
956
wt = self.make_branch_and_tree('.')
969
957
tt = TreeTransform(wt)
970
958
self.addCleanup(tt.finalize)
971
parent = tt.trans_id_file_id(b'parent-id')
972
tt.new_file('file', parent, [b'Contents'])
959
parent = tt.trans_id_file_id('parent-id')
960
tt.new_file('file', parent, 'Contents')
973
961
raw_conflicts = resolve_conflicts(tt)
974
962
# Since the directory doesn't exist it's seen as 'missing'. So
975
963
# 'resolve_conflicts' create a conflict asking for it to be created.
1130
1116
self.assertEqual([bar1_abspath], stat_paths)
1132
1118
def test_iter_changes(self):
1133
self.wt.set_root_id(b'eert_toor')
1119
self.wt.set_root_id('eert_toor')
1134
1120
transform, root = self.get_transform()
1135
transform.new_file('old', root, [b'blah'], b'id-1', True)
1121
transform.new_file('old', root, 'blah', 'id-1', True)
1136
1122
transform.apply()
1137
1123
transform, root = self.get_transform()
1139
1125
self.assertEqual([], list(transform.iter_changes()))
1140
old = transform.trans_id_tree_path('old')
1126
old = transform.trans_id_tree_file_id('id-1')
1141
1127
transform.unversion_file(old)
1142
self.assertEqual([(b'id-1', ('old', None), False, (True, False),
1143
(b'eert_toor', b'eert_toor'),
1144
('old', 'old'), ('file', 'file'),
1145
(True, True), False)],
1146
list(transform.iter_changes()))
1147
transform.new_directory('new', root, b'id-1')
1148
self.assertEqual([(b'id-1', ('old', 'new'), True, (True, True),
1149
(b'eert_toor', b'eert_toor'), ('old', 'new'),
1150
('file', 'directory'),
1151
(True, False), False)],
1152
list(transform.iter_changes()))
1128
self.assertEqual([('id-1', ('old', None), False, (True, False),
1129
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1130
(True, True))], list(transform.iter_changes()))
1131
transform.new_directory('new', root, 'id-1')
1132
self.assertEqual([('id-1', ('old', 'new'), True, (True, True),
1133
('eert_toor', 'eert_toor'), ('old', 'new'),
1134
('file', 'directory'),
1135
(True, False))], list(transform.iter_changes()))
1154
1137
transform.finalize()
1156
1139
def test_iter_changes_new(self):
1157
self.wt.set_root_id(b'eert_toor')
1140
self.wt.set_root_id('eert_toor')
1158
1141
transform, root = self.get_transform()
1159
transform.new_file('old', root, [b'blah'])
1142
transform.new_file('old', root, 'blah')
1160
1143
transform.apply()
1161
1144
transform, root = self.get_transform()
1163
1146
old = transform.trans_id_tree_path('old')
1164
transform.version_file(b'id-1', old)
1165
self.assertEqual([(b'id-1', (None, 'old'), False, (False, True),
1166
(b'eert_toor', b'eert_toor'),
1167
('old', 'old'), ('file', 'file'),
1168
(False, False), False)],
1169
list(transform.iter_changes()))
1147
transform.version_file('id-1', old)
1148
self.assertEqual([('id-1', (None, 'old'), False, (False, True),
1149
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1150
(False, False))], list(transform.iter_changes()))
1171
1152
transform.finalize()
1173
1154
def test_iter_changes_modifications(self):
1174
self.wt.set_root_id(b'eert_toor')
1155
self.wt.set_root_id('eert_toor')
1175
1156
transform, root = self.get_transform()
1176
transform.new_file('old', root, [b'blah'], b'id-1')
1177
transform.new_file('new', root, [b'blah'])
1178
transform.new_directory('subdir', root, b'subdir-id')
1157
transform.new_file('old', root, 'blah', 'id-1')
1158
transform.new_file('new', root, 'blah')
1159
transform.new_directory('subdir', root, 'subdir-id')
1179
1160
transform.apply()
1180
1161
transform, root = self.get_transform()
1182
1163
old = transform.trans_id_tree_path('old')
1183
subdir = transform.trans_id_tree_path('subdir')
1164
subdir = transform.trans_id_tree_file_id('subdir-id')
1184
1165
new = transform.trans_id_tree_path('new')
1185
1166
self.assertEqual([], list(transform.iter_changes()))
1188
1169
transform.delete_contents(old)
1189
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1190
(b'eert_toor', b'eert_toor'),
1191
('old', 'old'), ('file', None),
1192
(False, False), False)],
1193
list(transform.iter_changes()))
1170
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
1171
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', None),
1172
(False, False))], list(transform.iter_changes()))
1196
transform.create_file([b'blah'], old)
1197
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1198
(b'eert_toor', b'eert_toor'),
1199
('old', 'old'), ('file', 'file'),
1200
(False, False), False)],
1201
list(transform.iter_changes()))
1175
transform.create_file('blah', old)
1176
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
1177
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1178
(False, False))], list(transform.iter_changes()))
1202
1179
transform.cancel_deletion(old)
1203
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1204
(b'eert_toor', b'eert_toor'),
1205
('old', 'old'), ('file', 'file'),
1206
(False, False), False)],
1207
list(transform.iter_changes()))
1180
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
1181
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1182
(False, False))], list(transform.iter_changes()))
1208
1183
transform.cancel_creation(old)
1210
1185
# move file_id to a different file
1211
1186
self.assertEqual([], list(transform.iter_changes()))
1212
1187
transform.unversion_file(old)
1213
transform.version_file(b'id-1', new)
1188
transform.version_file('id-1', new)
1214
1189
transform.adjust_path('old', root, new)
1215
self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
1216
(b'eert_toor', b'eert_toor'),
1217
('old', 'old'), ('file', 'file'),
1218
(False, False), False)],
1219
list(transform.iter_changes()))
1190
self.assertEqual([('id-1', ('old', 'old'), True, (True, True),
1191
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1192
(False, False))], list(transform.iter_changes()))
1220
1193
transform.cancel_versioning(new)
1221
1194
transform._removed_id = set()
1224
1197
self.assertEqual([], list(transform.iter_changes()))
1225
1198
transform.set_executability(True, old)
1226
self.assertEqual([(b'id-1', ('old', 'old'), False, (True, True),
1227
(b'eert_toor', b'eert_toor'),
1228
('old', 'old'), ('file', 'file'),
1229
(False, True), False)],
1230
list(transform.iter_changes()))
1199
self.assertEqual([('id-1', ('old', 'old'), False, (True, True),
1200
('eert_toor', 'eert_toor'), ('old', 'old'), ('file', 'file'),
1201
(False, True))], list(transform.iter_changes()))
1231
1202
transform.set_executability(None, old)
1234
1205
self.assertEqual([], list(transform.iter_changes()))
1235
1206
transform.adjust_path('new', root, old)
1236
1207
transform._new_parent = {}
1237
self.assertEqual([(b'id-1', ('old', 'new'), False, (True, True),
1238
(b'eert_toor', b'eert_toor'),
1239
('old', 'new'), ('file', 'file'),
1240
(False, False), False)],
1241
list(transform.iter_changes()))
1208
self.assertEqual([('id-1', ('old', 'new'), False, (True, True),
1209
('eert_toor', 'eert_toor'), ('old', 'new'), ('file', 'file'),
1210
(False, False))], list(transform.iter_changes()))
1242
1211
transform._new_name = {}
1244
1213
# parent directory
1245
1214
self.assertEqual([], list(transform.iter_changes()))
1246
1215
transform.adjust_path('new', subdir, old)
1247
1216
transform._new_name = {}
1248
self.assertEqual([(b'id-1', ('old', 'subdir/old'), False,
1249
(True, True), (b'eert_toor',
1250
b'subdir-id'), ('old', 'old'),
1251
('file', 'file'), (False, False), False)],
1252
list(transform.iter_changes()))
1217
self.assertEqual([('id-1', ('old', 'subdir/old'), False,
1218
(True, True), ('eert_toor', 'subdir-id'), ('old', 'old'),
1219
('file', 'file'), (False, False))],
1220
list(transform.iter_changes()))
1253
1221
transform._new_path = {}
1256
1224
transform.finalize()
1258
1226
def test_iter_changes_modified_bleed(self):
1259
self.wt.set_root_id(b'eert_toor')
1227
self.wt.set_root_id('eert_toor')
1260
1228
"""Modified flag should not bleed from one change to another"""
1261
1229
# unfortunately, we have no guarantee that file1 (which is modified)
1262
1230
# will be applied before file2. And if it's applied after file2, it
1263
1231
# obviously can't bleed into file2's change output. But for now, it
1265
1233
transform, root = self.get_transform()
1266
transform.new_file('file1', root, [b'blah'], b'id-1')
1267
transform.new_file('file2', root, [b'blah'], b'id-2')
1234
transform.new_file('file1', root, 'blah', 'id-1')
1235
transform.new_file('file2', root, 'blah', 'id-2')
1268
1236
transform.apply()
1269
1237
transform, root = self.get_transform()
1271
transform.delete_contents(transform.trans_id_file_id(b'id-1'))
1239
transform.delete_contents(transform.trans_id_file_id('id-1'))
1272
1240
transform.set_executability(True,
1273
transform.trans_id_file_id(b'id-2'))
1275
[(b'id-1', (u'file1', u'file1'), True, (True, True),
1276
(b'eert_toor', b'eert_toor'), ('file1', u'file1'),
1277
('file', None), (False, False), False),
1278
(b'id-2', (u'file2', u'file2'), False, (True, True),
1279
(b'eert_toor', b'eert_toor'), ('file2', u'file2'),
1280
('file', 'file'), (False, True), False)],
1241
transform.trans_id_file_id('id-2'))
1242
self.assertEqual([('id-1', (u'file1', u'file1'), True, (True, True),
1243
('eert_toor', 'eert_toor'), ('file1', u'file1'),
1244
('file', None), (False, False)),
1245
('id-2', (u'file2', u'file2'), False, (True, True),
1246
('eert_toor', 'eert_toor'), ('file2', u'file2'),
1247
('file', 'file'), (False, True))],
1281
1248
list(transform.iter_changes()))
1283
1250
transform.finalize()
1285
1252
def test_iter_changes_move_missing(self):
1286
1253
"""Test moving ids with no files around"""
1287
self.wt.set_root_id(b'toor_eert')
1254
self.wt.set_root_id('toor_eert')
1288
1255
# Need two steps because versioning a non-existant file is a conflict.
1289
1256
transform, root = self.get_transform()
1290
transform.new_directory('floater', root, b'floater-id')
1257
transform.new_directory('floater', root, 'floater-id')
1291
1258
transform.apply()
1292
1259
transform, root = self.get_transform()
1293
1260
transform.delete_contents(transform.trans_id_tree_path('floater'))
1647
1593
self.assertPathExists("baz")
1649
1595
self.addCleanup(wt.unlock)
1650
self.assertEqual(wt.kind("foo"), "file")
1596
self.assertEqual(wt.kind(wt.path2id("foo")), "file")
1652
1598
def test_no_final_path(self):
1653
1599
transform, root = self.get_transform()
1654
trans_id = transform.trans_id_file_id(b'foo')
1655
transform.create_file([b'bar'], trans_id)
1600
trans_id = transform.trans_id_file_id('foo')
1601
transform.create_file('bar', trans_id)
1656
1602
transform.cancel_creation(trans_id)
1657
1603
transform.apply()
1659
1605
def test_create_from_tree(self):
1660
1606
tree1 = self.make_branch_and_tree('tree1')
1661
self.build_tree_contents([('tree1/foo/',), ('tree1/bar', b'baz')])
1662
tree1.add(['foo', 'bar'], [b'foo-id', b'bar-id'])
1607
self.build_tree_contents([('tree1/foo/',), ('tree1/bar', 'baz')])
1608
tree1.add(['foo', 'bar'], ['foo-id', 'bar-id'])
1663
1609
tree2 = self.make_branch_and_tree('tree2')
1664
1610
tt = TreeTransform(tree2)
1665
1611
foo_trans_id = tt.create_path('foo', tt.root)
1666
create_from_tree(tt, foo_trans_id, tree1, 'foo')
1612
create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
1667
1613
bar_trans_id = tt.create_path('bar', tt.root)
1668
create_from_tree(tt, bar_trans_id, tree1, 'bar')
1614
create_from_tree(tt, bar_trans_id, tree1, 'bar-id')
1670
1616
self.assertEqual('directory', osutils.file_kind('tree2/foo'))
1671
self.assertFileEqual(b'baz', 'tree2/bar')
1617
self.assertFileEqual('baz', 'tree2/bar')
1673
1619
def test_create_from_tree_bytes(self):
1674
1620
"""Provided lines are used instead of tree content."""
1675
1621
tree1 = self.make_branch_and_tree('tree1')
1676
self.build_tree_contents([('tree1/foo', b'bar'), ])
1677
tree1.add('foo', b'foo-id')
1622
self.build_tree_contents([('tree1/foo', 'bar'),])
1623
tree1.add('foo', 'foo-id')
1678
1624
tree2 = self.make_branch_and_tree('tree2')
1679
1625
tt = TreeTransform(tree2)
1680
1626
foo_trans_id = tt.create_path('foo', tt.root)
1681
create_from_tree(tt, foo_trans_id, tree1, 'foo', chunks=[b'qux'])
1627
create_from_tree(tt, foo_trans_id, tree1, 'foo-id', bytes='qux')
1683
self.assertFileEqual(b'qux', 'tree2/foo')
1629
self.assertFileEqual('qux', 'tree2/foo')
1685
1631
def test_create_from_tree_symlink(self):
1686
1632
self.requireFeature(SymlinkFeature)
1687
1633
tree1 = self.make_branch_and_tree('tree1')
1688
1634
os.symlink('bar', 'tree1/foo')
1689
tree1.add('foo', b'foo-id')
1635
tree1.add('foo', 'foo-id')
1690
1636
tt = TreeTransform(self.make_branch_and_tree('tree2'))
1691
1637
foo_trans_id = tt.create_path('foo', tt.root)
1692
create_from_tree(tt, foo_trans_id, tree1, 'foo')
1638
create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
1694
1640
self.assertEqual('bar', os.readlink('tree2/foo'))
1748
1694
def test_text_merge(self):
1749
1695
root_id = generate_ids.gen_root_id()
1750
1696
base = TransformGroup("base", root_id)
1751
base.tt.new_file('a', base.root, [b'a\nb\nc\nd\be\n'], b'a')
1752
base.tt.new_file('b', base.root, [b'b1'], b'b')
1753
base.tt.new_file('c', base.root, [b'c'], b'c')
1754
base.tt.new_file('d', base.root, [b'd'], b'd')
1755
base.tt.new_file('e', base.root, [b'e'], b'e')
1756
base.tt.new_file('f', base.root, [b'f'], b'f')
1757
base.tt.new_directory('g', base.root, b'g')
1758
base.tt.new_directory('h', base.root, b'h')
1697
base.tt.new_file('a', base.root, 'a\nb\nc\nd\be\n', 'a')
1698
base.tt.new_file('b', base.root, 'b1', 'b')
1699
base.tt.new_file('c', base.root, 'c', 'c')
1700
base.tt.new_file('d', base.root, 'd', 'd')
1701
base.tt.new_file('e', base.root, 'e', 'e')
1702
base.tt.new_file('f', base.root, 'f', 'f')
1703
base.tt.new_directory('g', base.root, 'g')
1704
base.tt.new_directory('h', base.root, 'h')
1759
1705
base.tt.apply()
1760
1706
other = TransformGroup("other", root_id)
1761
other.tt.new_file('a', other.root, [b'y\nb\nc\nd\be\n'], b'a')
1762
other.tt.new_file('b', other.root, [b'b2'], b'b')
1763
other.tt.new_file('c', other.root, [b'c2'], b'c')
1764
other.tt.new_file('d', other.root, [b'd'], b'd')
1765
other.tt.new_file('e', other.root, [b'e2'], b'e')
1766
other.tt.new_file('f', other.root, [b'f'], b'f')
1767
other.tt.new_file('g', other.root, [b'g'], b'g')
1768
other.tt.new_file('h', other.root, [b'h\ni\nj\nk\n'], b'h')
1769
other.tt.new_file('i', other.root, [b'h\ni\nj\nk\n'], b'i')
1707
other.tt.new_file('a', other.root, 'y\nb\nc\nd\be\n', 'a')
1708
other.tt.new_file('b', other.root, 'b2', 'b')
1709
other.tt.new_file('c', other.root, 'c2', 'c')
1710
other.tt.new_file('d', other.root, 'd', 'd')
1711
other.tt.new_file('e', other.root, 'e2', 'e')
1712
other.tt.new_file('f', other.root, 'f', 'f')
1713
other.tt.new_file('g', other.root, 'g', 'g')
1714
other.tt.new_file('h', other.root, 'h\ni\nj\nk\n', 'h')
1715
other.tt.new_file('i', other.root, 'h\ni\nj\nk\n', 'i')
1770
1716
other.tt.apply()
1771
1717
this = TransformGroup("this", root_id)
1772
this.tt.new_file('a', this.root, [b'a\nb\nc\nd\bz\n'], b'a')
1773
this.tt.new_file('b', this.root, [b'b'], b'b')
1774
this.tt.new_file('c', this.root, [b'c'], b'c')
1775
this.tt.new_file('d', this.root, [b'd2'], b'd')
1776
this.tt.new_file('e', this.root, [b'e2'], b'e')
1777
this.tt.new_file('f', this.root, [b'f'], b'f')
1778
this.tt.new_file('g', this.root, [b'g'], b'g')
1779
this.tt.new_file('h', this.root, [b'1\n2\n3\n4\n'], b'h')
1780
this.tt.new_file('i', this.root, [b'1\n2\n3\n4\n'], b'i')
1718
this.tt.new_file('a', this.root, 'a\nb\nc\nd\bz\n', 'a')
1719
this.tt.new_file('b', this.root, 'b', 'b')
1720
this.tt.new_file('c', this.root, 'c', 'c')
1721
this.tt.new_file('d', this.root, 'd2', 'd')
1722
this.tt.new_file('e', this.root, 'e2', 'e')
1723
this.tt.new_file('f', this.root, 'f', 'f')
1724
this.tt.new_file('g', this.root, 'g', 'g')
1725
this.tt.new_file('h', this.root, '1\n2\n3\n4\n', 'h')
1726
this.tt.new_file('i', this.root, '1\n2\n3\n4\n', 'i')
1781
1727
this.tt.apply()
1782
1728
Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1784
1730
# textual merge
1785
with this.wt.get_file(this.wt.id2path(b'a')) as f:
1786
self.assertEqual(f.read(), b'y\nb\nc\nd\bz\n')
1731
self.assertEqual(this.wt.get_file('a').read(), 'y\nb\nc\nd\bz\n')
1787
1732
# three-way text conflict
1788
with this.wt.get_file(this.wt.id2path(b'b')) as f:
1789
self.assertEqual(f.read(), conflict_text(b'b', b'b2'))
1733
self.assertEqual(this.wt.get_file('b').read(),
1734
conflict_text('b', 'b2'))
1791
self.assertEqual(this.wt.get_file(this.wt.id2path(b'c')).read(), b'c2')
1736
self.assertEqual(this.wt.get_file('c').read(), 'c2')
1793
self.assertEqual(this.wt.get_file(this.wt.id2path(b'd')).read(), b'd2')
1738
self.assertEqual(this.wt.get_file('d').read(), 'd2')
1794
1739
# Ambigious clean merge
1795
self.assertEqual(this.wt.get_file(this.wt.id2path(b'e')).read(), b'e2')
1740
self.assertEqual(this.wt.get_file('e').read(), 'e2')
1797
self.assertEqual(this.wt.get_file(this.wt.id2path(b'f')).read(), b'f')
1742
self.assertEqual(this.wt.get_file('f').read(), 'f')
1798
1743
# Correct correct results when THIS == OTHER
1799
self.assertEqual(this.wt.get_file(this.wt.id2path(b'g')).read(), b'g')
1744
self.assertEqual(this.wt.get_file('g').read(), 'g')
1800
1745
# Text conflict when THIS & OTHER are text and BASE is dir
1801
self.assertEqual(this.wt.get_file(this.wt.id2path(b'h')).read(),
1802
conflict_text(b'1\n2\n3\n4\n', b'h\ni\nj\nk\n'))
1803
self.assertEqual(this.wt.get_file('h.THIS').read(),
1805
self.assertEqual(this.wt.get_file('h.OTHER').read(),
1746
self.assertEqual(this.wt.get_file('h').read(),
1747
conflict_text('1\n2\n3\n4\n', 'h\ni\nj\nk\n'))
1748
self.assertEqual(this.wt.get_file_byname('h.THIS').read(),
1750
self.assertEqual(this.wt.get_file_byname('h.OTHER').read(),
1807
1752
self.assertEqual(file_kind(this.wt.abspath('h.BASE')), 'directory')
1808
self.assertEqual(this.wt.get_file(this.wt.id2path(b'i')).read(),
1809
conflict_text(b'1\n2\n3\n4\n', b'h\ni\nj\nk\n'))
1810
self.assertEqual(this.wt.get_file('i.THIS').read(),
1812
self.assertEqual(this.wt.get_file('i.OTHER').read(),
1753
self.assertEqual(this.wt.get_file('i').read(),
1754
conflict_text('1\n2\n3\n4\n', 'h\ni\nj\nk\n'))
1755
self.assertEqual(this.wt.get_file_byname('i.THIS').read(),
1757
self.assertEqual(this.wt.get_file_byname('i.OTHER').read(),
1814
1759
self.assertEqual(os.path.exists(this.wt.abspath('i.BASE')), False)
1815
1760
modified = ['a', 'b', 'c', 'h', 'i']
1816
1761
merge_modified = this.wt.merge_modified()
1817
1762
self.assertSubset(merge_modified, modified)
1818
1763
self.assertEqual(len(merge_modified), len(modified))
1819
with open(this.wt.abspath(this.wt.id2path(b'a')), 'wb') as f:
1764
with file(this.wt.id2abspath('a'), 'wb') as f: f.write('booga')
1821
1765
modified.pop(0)
1822
1766
merge_modified = this.wt.merge_modified()
1823
1767
self.assertSubset(merge_modified, modified)
1874
1816
base = TransformGroup("BASE", root_id)
1875
1817
this = TransformGroup("THIS", root_id)
1876
1818
other = TransformGroup("OTHER", root_id)
1877
base_a, this_a, other_a = [t.tt.new_directory('a', t.root, b'a')
1878
for t in [base, this, other]]
1879
base_b, this_b, other_b = [t.tt.new_directory('b', t.root, b'b')
1880
for t in [base, this, other]]
1881
base.tt.new_directory('c', base_a, b'c')
1882
this.tt.new_directory('c1', this_a, b'c')
1883
other.tt.new_directory('c', other_b, b'c')
1885
base.tt.new_directory('d', base_a, b'd')
1886
this.tt.new_directory('d1', this_b, b'd')
1887
other.tt.new_directory('d', other_a, b'd')
1889
base.tt.new_directory('e', base_a, b'e')
1890
this.tt.new_directory('e', this_a, b'e')
1891
other.tt.new_directory('e1', other_b, b'e')
1893
base.tt.new_directory('f', base_a, b'f')
1894
this.tt.new_directory('f1', this_b, b'f')
1895
other.tt.new_directory('f1', other_b, b'f')
1819
base_a, this_a, other_a = [t.tt.new_directory('a', t.root, 'a')
1820
for t in [base, this, other]]
1821
base_b, this_b, other_b = [t.tt.new_directory('b', t.root, 'b')
1822
for t in [base, this, other]]
1823
base.tt.new_directory('c', base_a, 'c')
1824
this.tt.new_directory('c1', this_a, 'c')
1825
other.tt.new_directory('c', other_b, 'c')
1827
base.tt.new_directory('d', base_a, 'd')
1828
this.tt.new_directory('d1', this_b, 'd')
1829
other.tt.new_directory('d', other_a, 'd')
1831
base.tt.new_directory('e', base_a, 'e')
1832
this.tt.new_directory('e', this_a, 'e')
1833
other.tt.new_directory('e1', other_b, 'e')
1835
base.tt.new_directory('f', base_a, 'f')
1836
this.tt.new_directory('f1', this_b, 'f')
1837
other.tt.new_directory('f1', other_b, 'f')
1897
1839
for tg in [this, base, other]:
1899
1841
Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1900
self.assertEqual(this.wt.id2path(b'c'), pathjoin('b/c1'))
1901
self.assertEqual(this.wt.id2path(b'd'), pathjoin('b/d1'))
1902
self.assertEqual(this.wt.id2path(b'e'), pathjoin('b/e1'))
1903
self.assertEqual(this.wt.id2path(b'f'), pathjoin('b/f1'))
1842
self.assertEqual(this.wt.id2path('c'), pathjoin('b/c1'))
1843
self.assertEqual(this.wt.id2path('d'), pathjoin('b/d1'))
1844
self.assertEqual(this.wt.id2path('e'), pathjoin('b/e1'))
1845
self.assertEqual(this.wt.id2path('f'), pathjoin('b/f1'))
1905
1847
def test_filename_merge_conflicts(self):
1906
1848
root_id = generate_ids.gen_root_id()
1907
1849
base = TransformGroup("BASE", root_id)
1908
1850
this = TransformGroup("THIS", root_id)
1909
1851
other = TransformGroup("OTHER", root_id)
1910
base_a, this_a, other_a = [t.tt.new_directory('a', t.root, b'a')
1911
for t in [base, this, other]]
1912
base_b, this_b, other_b = [t.tt.new_directory('b', t.root, b'b')
1913
for t in [base, this, other]]
1915
base.tt.new_file('g', base_a, [b'g'], b'g')
1916
other.tt.new_file('g1', other_b, [b'g1'], b'g')
1918
base.tt.new_file('h', base_a, [b'h'], b'h')
1919
this.tt.new_file('h1', this_b, [b'h1'], b'h')
1921
base.tt.new_file('i', base.root, [b'i'], b'i')
1922
other.tt.new_directory('i1', this_b, b'i')
1852
base_a, this_a, other_a = [t.tt.new_directory('a', t.root, 'a')
1853
for t in [base, this, other]]
1854
base_b, this_b, other_b = [t.tt.new_directory('b', t.root, 'b')
1855
for t in [base, this, other]]
1857
base.tt.new_file('g', base_a, 'g', 'g')
1858
other.tt.new_file('g1', other_b, 'g1', 'g')
1860
base.tt.new_file('h', base_a, 'h', 'h')
1861
this.tt.new_file('h1', this_b, 'h1', 'h')
1863
base.tt.new_file('i', base.root, 'i', 'i')
1864
other.tt.new_directory('i1', this_b, 'i')
1924
1866
for tg in [this, base, other]:
1926
1868
Merge3Merger(this.wt, this.wt, base.wt, other.wt)
1928
self.assertEqual(this.wt.id2path(b'g'), pathjoin('b/g1.OTHER'))
1870
self.assertEqual(this.wt.id2path('g'), pathjoin('b/g1.OTHER'))
1929
1871
self.assertIs(os.path.lexists(this.wt.abspath('b/g1.BASE')), True)
1930
1872
self.assertIs(os.path.lexists(this.wt.abspath('b/g1.THIS')), False)
1931
self.assertEqual(this.wt.id2path(b'h'), pathjoin('b/h1.THIS'))
1873
self.assertEqual(this.wt.id2path('h'), pathjoin('b/h1.THIS'))
1932
1874
self.assertIs(os.path.lexists(this.wt.abspath('b/h1.BASE')), True)
1933
1875
self.assertIs(os.path.lexists(this.wt.abspath('b/h1.OTHER')), False)
1934
self.assertEqual(this.wt.id2path(b'i'), pathjoin('b/i1.OTHER'))
1876
self.assertEqual(this.wt.id2path('i'), pathjoin('b/i1.OTHER'))
1937
1879
class TestBuildTree(tests.TestCaseWithTransport):
2395
2330
tt = TransformPreview(branch.basis_tree())
2396
2331
self.addCleanup(tt.finalize)
2397
2332
e = self.assertRaises(ValueError, tt.commit, branch,
2398
'my message', [b'rev1b-id'])
2333
'my message', ['rev1b-id'])
2399
2334
self.assertEqual('Cannot supply merge parents for first commit.',
2401
2336
self.assertEqual(_mod_revision.NULL_REVISION, branch.last_revision())
2403
2338
def test_add_files(self):
2404
2339
branch, tt = self.get_branch_and_transform()
2405
tt.new_file('file', tt.root, [b'contents'], b'file-id')
2406
trans_id = tt.new_directory('dir', tt.root, b'dir-id')
2340
tt.new_file('file', tt.root, 'contents', 'file-id')
2341
trans_id = tt.new_directory('dir', tt.root, 'dir-id')
2407
2342
if SymlinkFeature.available():
2408
tt.new_symlink('symlink', trans_id, 'target', b'symlink-id')
2409
tt.commit(branch, 'message')
2343
tt.new_symlink('symlink', trans_id, 'target', 'symlink-id')
2344
rev = tt.commit(branch, 'message')
2410
2345
tree = branch.basis_tree()
2411
self.assertEqual('file', tree.id2path(b'file-id'))
2412
self.assertEqual(b'contents', tree.get_file_text('file'))
2413
self.assertEqual('dir', tree.id2path(b'dir-id'))
2346
self.assertEqual('file', tree.id2path('file-id'))
2347
self.assertEqual('contents', tree.get_file_text('file-id'))
2348
self.assertEqual('dir', tree.id2path('dir-id'))
2414
2349
if SymlinkFeature.available():
2415
self.assertEqual('dir/symlink', tree.id2path(b'symlink-id'))
2416
self.assertEqual('target', tree.get_symlink_target('dir/symlink'))
2350
self.assertEqual('dir/symlink', tree.id2path('symlink-id'))
2351
self.assertEqual('target', tree.get_symlink_target('symlink-id'))
2418
2353
def test_add_unversioned(self):
2419
2354
branch, tt = self.get_branch_and_transform()
2420
tt.new_file('file', tt.root, [b'contents'])
2355
tt.new_file('file', tt.root, 'contents')
2421
2356
self.assertRaises(errors.StrictCommitFailed, tt.commit, branch,
2422
2357
'message', strict=True)
2424
2359
def test_modify_strict(self):
2425
2360
branch, tt = self.get_branch_and_transform()
2426
tt.new_file('file', tt.root, [b'contents'], b'file-id')
2361
tt.new_file('file', tt.root, 'contents', 'file-id')
2427
2362
tt.commit(branch, 'message', strict=True)
2428
2363
tt = TransformPreview(branch.basis_tree())
2429
2364
self.addCleanup(tt.finalize)
2430
trans_id = tt.trans_id_file_id(b'file-id')
2365
trans_id = tt.trans_id_file_id('file-id')
2431
2366
tt.delete_contents(trans_id)
2432
tt.create_file([b'contents'], trans_id)
2367
tt.create_file('contents', trans_id)
2433
2368
tt.commit(branch, 'message', strict=True)
2435
2370
def test_commit_malformed(self):
2797
2728
revision_tree = self.create_tree()
2798
2729
preview = TransformPreview(revision_tree)
2799
2730
self.addCleanup(preview.finalize)
2800
preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
2731
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2801
2732
preview_tree = preview.get_preview_tree()
2802
self.assertEqual(preview_tree.kind('file2'), 'file')
2803
with preview_tree.get_file('file2') as f:
2804
self.assertEqual(f.read(), b'content B\n')
2733
self.assertEqual(preview_tree.kind('file2-id'), 'file')
2735
preview_tree.get_file('file2-id').read(), 'content B\n')
2806
2737
def test_diff_preview_tree(self):
2807
2738
revision_tree = self.create_tree()
2808
2739
preview = TransformPreview(revision_tree)
2809
2740
self.addCleanup(preview.finalize)
2810
preview.new_file('file2', preview.root, [b'content B\n'], b'file2-id')
2741
preview.new_file('file2', preview.root, 'content B\n', 'file2-id')
2811
2742
preview_tree = preview.get_preview_tree()
2813
2744
show_diff_trees(revision_tree, preview_tree, out)
2814
2745
lines = out.getvalue().splitlines()
2815
self.assertEqual(lines[0], b"=== added file 'file2'")
2746
self.assertEqual(lines[0], "=== added file 'file2'")
2816
2747
# 3 lines of diff administrivia
2817
self.assertEqual(lines[4], b"+content B")
2819
def test_unsupported_symlink_diff(self):
2820
self.requireFeature(SymlinkFeature)
2821
tree = self.make_branch_and_tree('.')
2822
self.build_tree_contents([('a', 'content 1')])
2823
tree.set_root_id(b'TREE_ROOT')
2824
tree.add('a', b'a-id')
2825
os.symlink('a', 'foo')
2826
tree.add('foo', b'foo-id')
2827
tree.commit('rev1', rev_id=b'rev1')
2828
revision_tree = tree.branch.repository.revision_tree(b'rev1')
2829
preview = TransformPreview(revision_tree)
2830
self.addCleanup(preview.finalize)
2831
preview.delete_versioned(preview.trans_id_tree_path('foo'))
2832
preview_tree = preview.get_preview_tree()
2835
trace.push_log_file(log)
2836
os_symlink = getattr(os, 'symlink', None)
2839
show_diff_trees(revision_tree, preview_tree, out)
2840
lines = out.getvalue().splitlines()
2842
os.symlink = os_symlink
2843
self.assertContainsRe(
2845
b'Ignoring "foo" as symlinks are not supported on this filesystem')
2748
self.assertEqual(lines[4], "+content B")
2847
2750
def test_transform_conflicts(self):
2848
2751
revision_tree = self.create_tree()
2849
2752
preview = TransformPreview(revision_tree)
2850
2753
self.addCleanup(preview.finalize)
2851
preview.new_file('a', preview.root, [b'content 2'])
2754
preview.new_file('a', preview.root, 'content 2')
2852
2755
resolve_conflicts(preview)
2853
trans_id = preview.trans_id_file_id(b'a-id')
2756
trans_id = preview.trans_id_file_id('a-id')
2854
2757
self.assertEqual('a.moved', preview.final_name(trans_id))
2856
2759
def get_tree_and_preview_tree(self):
2857
2760
revision_tree = self.create_tree()
2858
2761
preview = TransformPreview(revision_tree)
2859
2762
self.addCleanup(preview.finalize)
2860
a_trans_id = preview.trans_id_file_id(b'a-id')
2763
a_trans_id = preview.trans_id_file_id('a-id')
2861
2764
preview.delete_contents(a_trans_id)
2862
preview.create_file([b'b content'], a_trans_id)
2765
preview.create_file('b content', a_trans_id)
2863
2766
preview_tree = preview.get_preview_tree()
2864
2767
return revision_tree, preview_tree
2866
2769
def test_iter_changes(self):
2867
2770
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2868
root = revision_tree.path2id('')
2869
self.assertEqual([(b'a-id', ('a', 'a'), True, (True, True),
2870
(root, root), ('a', 'a'), ('file', 'file'),
2871
(False, False), False)],
2872
list(preview_tree.iter_changes(revision_tree)))
2771
root = revision_tree.get_root_id()
2772
self.assertEqual([('a-id', ('a', 'a'), True, (True, True),
2773
(root, root), ('a', 'a'), ('file', 'file'),
2775
list(preview_tree.iter_changes(revision_tree)))
2874
2777
def test_include_unchanged_succeeds(self):
2875
2778
revision_tree, preview_tree = self.get_tree_and_preview_tree()
2876
2779
changes = preview_tree.iter_changes(revision_tree,
2877
2780
include_unchanged=True)
2781
root = revision_tree.get_root_id()
2878
2783
self.assertEqual([ROOT_ENTRY, A_ENTRY], list(changes))
2880
2785
def test_specific_files(self):
2909
2814
revision_tree = self.create_tree()
2910
2815
preview = TransformPreview(revision_tree)
2911
2816
self.addCleanup(preview.finalize)
2912
preview.new_file('file', preview.root, [b'contents'], b'file-id')
2913
preview.new_directory('directory', preview.root, b'dir-id')
2817
preview.new_file('file', preview.root, 'contents', 'file-id')
2818
preview.new_directory('directory', preview.root, 'dir-id')
2914
2819
preview_tree = preview.get_preview_tree()
2915
self.assertEqual('file', preview_tree.kind('file'))
2916
self.assertEqual('directory', preview_tree.kind('directory'))
2820
self.assertEqual('file', preview_tree.kind('file-id'))
2821
self.assertEqual('directory', preview_tree.kind('dir-id'))
2918
2823
def test_get_file_mtime(self):
2919
2824
preview = self.get_empty_preview()
2920
file_trans_id = preview.new_file('file', preview.root, [b'contents'],
2825
file_trans_id = preview.new_file('file', preview.root, 'contents',
2922
2827
limbo_path = preview._limbo_name(file_trans_id)
2923
2828
preview_tree = preview.get_preview_tree()
2924
2829
self.assertEqual(os.stat(limbo_path).st_mtime,
2925
preview_tree.get_file_mtime('file'))
2830
preview_tree.get_file_mtime('file-id'))
2927
2832
def test_get_file_mtime_renamed(self):
2928
2833
work_tree = self.make_branch_and_tree('tree')
2929
2834
self.build_tree(['tree/file'])
2930
work_tree.add('file', b'file-id')
2835
work_tree.add('file', 'file-id')
2931
2836
preview = TransformPreview(work_tree)
2932
2837
self.addCleanup(preview.finalize)
2933
file_trans_id = preview.trans_id_tree_path('file')
2838
file_trans_id = preview.trans_id_tree_file_id('file-id')
2934
2839
preview.adjust_path('renamed', preview.root, file_trans_id)
2935
2840
preview_tree = preview.get_preview_tree()
2936
preview_mtime = preview_tree.get_file_mtime('renamed')
2937
work_mtime = work_tree.get_file_mtime('file')
2841
preview_mtime = preview_tree.get_file_mtime('file-id', 'renamed')
2842
work_mtime = work_tree.get_file_mtime('file-id', 'file')
2939
2844
def test_get_file_size(self):
2940
2845
work_tree = self.make_branch_and_tree('tree')
2941
self.build_tree_contents([('tree/old', b'old')])
2942
work_tree.add('old', b'old-id')
2846
self.build_tree_contents([('tree/old', 'old')])
2847
work_tree.add('old', 'old-id')
2943
2848
preview = TransformPreview(work_tree)
2944
2849
self.addCleanup(preview.finalize)
2945
preview.new_file('name', preview.root, [b'contents'], b'new-id',
2850
new_id = preview.new_file('name', preview.root, 'contents', 'new-id',
2947
2852
tree = preview.get_preview_tree()
2948
self.assertEqual(len('old'), tree.get_file_size('old'))
2949
self.assertEqual(len('contents'), tree.get_file_size('name'))
2853
self.assertEqual(len('old'), tree.get_file_size('old-id'))
2854
self.assertEqual(len('contents'), tree.get_file_size('new-id'))
2951
2856
def test_get_file(self):
2952
2857
preview = self.get_empty_preview()
2953
preview.new_file('file', preview.root, [b'contents'], b'file-id')
2858
preview.new_file('file', preview.root, 'contents', 'file-id')
2954
2859
preview_tree = preview.get_preview_tree()
2955
with preview_tree.get_file('file') as tree_file:
2956
self.assertEqual(b'contents', tree_file.read())
2860
tree_file = preview_tree.get_file('file-id')
2862
self.assertEqual('contents', tree_file.read())
2958
2866
def test_get_symlink_target(self):
2959
2867
self.requireFeature(SymlinkFeature)
2960
2868
preview = self.get_empty_preview()
2961
preview.new_symlink('symlink', preview.root, 'target', b'symlink-id')
2869
preview.new_symlink('symlink', preview.root, 'target', 'symlink-id')
2962
2870
preview_tree = preview.get_preview_tree()
2963
2871
self.assertEqual('target',
2964
preview_tree.get_symlink_target('symlink'))
2872
preview_tree.get_symlink_target('symlink-id'))
2966
2874
def test_all_file_ids(self):
2967
2875
tree = self.make_branch_and_tree('tree')
2968
2876
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
2969
tree.add(['a', 'b', 'c'], [b'a-id', b'b-id', b'c-id'])
2877
tree.add(['a', 'b', 'c'], ['a-id', 'b-id', 'c-id'])
2970
2878
preview = TransformPreview(tree)
2971
2879
self.addCleanup(preview.finalize)
2972
preview.unversion_file(preview.trans_id_file_id(b'b-id'))
2973
c_trans_id = preview.trans_id_file_id(b'c-id')
2880
preview.unversion_file(preview.trans_id_file_id('b-id'))
2881
c_trans_id = preview.trans_id_file_id('c-id')
2974
2882
preview.unversion_file(c_trans_id)
2975
preview.version_file(b'c-id', c_trans_id)
2883
preview.version_file('c-id', c_trans_id)
2976
2884
preview_tree = preview.get_preview_tree()
2977
self.assertEqual({b'a-id', b'c-id', tree.path2id('')},
2885
self.assertEqual(set(['a-id', 'c-id', tree.get_root_id()]),
2978
2886
preview_tree.all_file_ids())
2980
2888
def test_path2id_deleted_unchanged(self):
2981
2889
tree = self.make_branch_and_tree('tree')
2982
2890
self.build_tree(['tree/unchanged', 'tree/deleted'])
2983
tree.add(['unchanged', 'deleted'], [b'unchanged-id', b'deleted-id'])
2891
tree.add(['unchanged', 'deleted'], ['unchanged-id', 'deleted-id'])
2984
2892
preview = TransformPreview(tree)
2985
2893
self.addCleanup(preview.finalize)
2986
preview.unversion_file(preview.trans_id_file_id(b'deleted-id'))
2894
preview.unversion_file(preview.trans_id_file_id('deleted-id'))
2987
2895
preview_tree = preview.get_preview_tree()
2988
self.assertEqual(b'unchanged-id', preview_tree.path2id('unchanged'))
2989
self.assertFalse(preview_tree.is_versioned('deleted'))
2896
self.assertEqual('unchanged-id', preview_tree.path2id('unchanged'))
2897
self.assertIs(None, preview_tree.path2id('deleted'))
2991
2899
def test_path2id_created(self):
2992
2900
tree = self.make_branch_and_tree('tree')
2993
2901
self.build_tree(['tree/unchanged'])
2994
tree.add(['unchanged'], [b'unchanged-id'])
2902
tree.add(['unchanged'], ['unchanged-id'])
2995
2903
preview = TransformPreview(tree)
2996
2904
self.addCleanup(preview.finalize)
2997
preview.new_file('new', preview.trans_id_file_id(b'unchanged-id'),
2998
[b'contents'], b'new-id')
2905
preview.new_file('new', preview.trans_id_file_id('unchanged-id'),
2906
'contents', 'new-id')
2999
2907
preview_tree = preview.get_preview_tree()
3000
self.assertEqual(b'new-id', preview_tree.path2id('unchanged/new'))
2908
self.assertEqual('new-id', preview_tree.path2id('unchanged/new'))
3002
2910
def test_path2id_moved(self):
3003
2911
tree = self.make_branch_and_tree('tree')
3004
2912
self.build_tree(['tree/old_parent/', 'tree/old_parent/child'])
3005
2913
tree.add(['old_parent', 'old_parent/child'],
3006
[b'old_parent-id', b'child-id'])
2914
['old_parent-id', 'child-id'])
3007
2915
preview = TransformPreview(tree)
3008
2916
self.addCleanup(preview.finalize)
3009
2917
new_parent = preview.new_directory('new_parent', preview.root,
3011
2919
preview.adjust_path('child', new_parent,
3012
preview.trans_id_file_id(b'child-id'))
2920
preview.trans_id_file_id('child-id'))
3013
2921
preview_tree = preview.get_preview_tree()
3014
self.assertFalse(preview_tree.is_versioned('old_parent/child'))
3015
self.assertEqual(b'child-id', preview_tree.path2id('new_parent/child'))
2922
self.assertIs(None, preview_tree.path2id('old_parent/child'))
2923
self.assertEqual('child-id', preview_tree.path2id('new_parent/child'))
3017
2925
def test_path2id_renamed_parent(self):
3018
2926
tree = self.make_branch_and_tree('tree')
3019
2927
self.build_tree(['tree/old_name/', 'tree/old_name/child'])
3020
2928
tree.add(['old_name', 'old_name/child'],
3021
[b'parent-id', b'child-id'])
2929
['parent-id', 'child-id'])
3022
2930
preview = TransformPreview(tree)
3023
2931
self.addCleanup(preview.finalize)
3024
2932
preview.adjust_path('new_name', preview.root,
3025
preview.trans_id_file_id(b'parent-id'))
2933
preview.trans_id_file_id('parent-id'))
3026
2934
preview_tree = preview.get_preview_tree()
3027
self.assertFalse(preview_tree.is_versioned('old_name/child'))
3028
self.assertEqual(b'child-id', preview_tree.path2id('new_name/child'))
2935
self.assertIs(None, preview_tree.path2id('old_name/child'))
2936
self.assertEqual('child-id', preview_tree.path2id('new_name/child'))
3030
def assertMatchingIterEntries(self, tt, specific_files=None):
2938
def assertMatchingIterEntries(self, tt, specific_file_ids=None):
3031
2939
preview_tree = tt.get_preview_tree()
3032
2940
preview_result = list(preview_tree.iter_entries_by_dir(
3033
specific_files=specific_files))
3034
2942
tree = tt._tree
3036
actual_result = list(tree.iter_entries_by_dir(
3037
specific_files=specific_files))
2944
actual_result = list(tree.iter_entries_by_dir(specific_file_ids))
3038
2945
self.assertEqual(actual_result, preview_result)
3040
2947
def test_iter_entries_by_dir_new(self):
3041
2948
tree = self.make_branch_and_tree('tree')
3042
2949
tt = TreeTransform(tree)
3043
tt.new_file('new', tt.root, [b'contents'], b'new-id')
2950
tt.new_file('new', tt.root, 'contents', 'new-id')
3044
2951
self.assertMatchingIterEntries(tt)
3046
2953
def test_iter_entries_by_dir_deleted(self):
3047
2954
tree = self.make_branch_and_tree('tree')
3048
2955
self.build_tree(['tree/deleted'])
3049
tree.add('deleted', b'deleted-id')
2956
tree.add('deleted', 'deleted-id')
3050
2957
tt = TreeTransform(tree)
3051
tt.delete_contents(tt.trans_id_file_id(b'deleted-id'))
2958
tt.delete_contents(tt.trans_id_file_id('deleted-id'))
3052
2959
self.assertMatchingIterEntries(tt)
3054
2961
def test_iter_entries_by_dir_unversioned(self):
3055
2962
tree = self.make_branch_and_tree('tree')
3056
2963
self.build_tree(['tree/removed'])
3057
tree.add('removed', b'removed-id')
2964
tree.add('removed', 'removed-id')
3058
2965
tt = TreeTransform(tree)
3059
tt.unversion_file(tt.trans_id_file_id(b'removed-id'))
2966
tt.unversion_file(tt.trans_id_file_id('removed-id'))
3060
2967
self.assertMatchingIterEntries(tt)
3062
2969
def test_iter_entries_by_dir_moved(self):
3063
2970
tree = self.make_branch_and_tree('tree')
3064
2971
self.build_tree(['tree/moved', 'tree/new_parent/'])
3065
tree.add(['moved', 'new_parent'], [b'moved-id', b'new_parent-id'])
2972
tree.add(['moved', 'new_parent'], ['moved-id', 'new_parent-id'])
3066
2973
tt = TreeTransform(tree)
3067
tt.adjust_path('moved', tt.trans_id_file_id(b'new_parent-id'),
3068
tt.trans_id_file_id(b'moved-id'))
2974
tt.adjust_path('moved', tt.trans_id_file_id('new_parent-id'),
2975
tt.trans_id_file_id('moved-id'))
3069
2976
self.assertMatchingIterEntries(tt)
3071
def test_iter_entries_by_dir_specific_files(self):
2978
def test_iter_entries_by_dir_specific_file_ids(self):
3072
2979
tree = self.make_branch_and_tree('tree')
3073
tree.set_root_id(b'tree-root-id')
2980
tree.set_root_id('tree-root-id')
3074
2981
self.build_tree(['tree/parent/', 'tree/parent/child'])
3075
tree.add(['parent', 'parent/child'], [b'parent-id', b'child-id'])
2982
tree.add(['parent', 'parent/child'], ['parent-id', 'child-id'])
3076
2983
tt = TreeTransform(tree)
3077
self.assertMatchingIterEntries(tt, ['', 'parent/child'])
2984
self.assertMatchingIterEntries(tt, ['tree-root-id', 'child-id'])
3079
2986
def test_symlink_content_summary(self):
3080
2987
self.requireFeature(SymlinkFeature)
3081
2988
preview = self.get_empty_preview()
3082
preview.new_symlink('path', preview.root, 'target', b'path-id')
2989
preview.new_symlink('path', preview.root, 'target', 'path-id')
3083
2990
summary = preview.get_preview_tree().path_content_summary('path')
3084
2991
self.assertEqual(('symlink', None, None, 'target'), summary)
3140
3046
def test_dir_content_summary(self):
3141
3047
preview = self.get_empty_preview()
3142
preview.new_directory('path', preview.root, b'path-id')
3048
preview.new_directory('path', preview.root, 'path-id')
3143
3049
summary = preview.get_preview_tree().path_content_summary('path')
3144
3050
self.assertEqual(('directory', None, None, None), summary)
3146
3052
def test_tree_content_summary(self):
3147
3053
preview = self.get_empty_preview()
3148
path = preview.new_directory('path', preview.root, b'path-id')
3149
preview.set_tree_reference(b'rev-1', path)
3054
path = preview.new_directory('path', preview.root, 'path-id')
3055
preview.set_tree_reference('rev-1', path)
3150
3056
summary = preview.get_preview_tree().path_content_summary('path')
3151
3057
self.assertEqual(4, len(summary))
3152
3058
self.assertEqual('tree-reference', summary[0])
3154
3060
def test_annotate(self):
3155
3061
tree = self.make_branch_and_tree('tree')
3156
self.build_tree_contents([('tree/file', b'a\n')])
3157
tree.add('file', b'file-id')
3158
tree.commit('a', rev_id=b'one')
3159
self.build_tree_contents([('tree/file', b'a\nb\n')])
3062
self.build_tree_contents([('tree/file', 'a\n')])
3063
tree.add('file', 'file-id')
3064
tree.commit('a', rev_id='one')
3065
self.build_tree_contents([('tree/file', 'a\nb\n')])
3160
3066
preview = TransformPreview(tree)
3161
3067
self.addCleanup(preview.finalize)
3162
file_trans_id = preview.trans_id_file_id(b'file-id')
3068
file_trans_id = preview.trans_id_file_id('file-id')
3163
3069
preview.delete_contents(file_trans_id)
3164
preview.create_file([b'a\nb\nc\n'], file_trans_id)
3070
preview.create_file('a\nb\nc\n', file_trans_id)
3165
3071
preview_tree = preview.get_preview_tree()
3171
annotation = preview_tree.annotate_iter(
3172
'file', default_revision=b'me:')
3077
annotation = preview_tree.annotate_iter('file-id', 'me:')
3173
3078
self.assertEqual(expected, annotation)
3175
3080
def test_annotate_missing(self):
3176
3081
preview = self.get_empty_preview()
3177
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
3082
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
3178
3083
preview_tree = preview.get_preview_tree()
3184
annotation = preview_tree.annotate_iter(
3185
'file', default_revision=b'me:')
3089
annotation = preview_tree.annotate_iter('file-id', 'me:')
3186
3090
self.assertEqual(expected, annotation)
3188
3092
def test_annotate_rename(self):
3189
3093
tree = self.make_branch_and_tree('tree')
3190
self.build_tree_contents([('tree/file', b'a\n')])
3191
tree.add('file', b'file-id')
3192
tree.commit('a', rev_id=b'one')
3094
self.build_tree_contents([('tree/file', 'a\n')])
3095
tree.add('file', 'file-id')
3096
tree.commit('a', rev_id='one')
3193
3097
preview = TransformPreview(tree)
3194
3098
self.addCleanup(preview.finalize)
3195
file_trans_id = preview.trans_id_file_id(b'file-id')
3099
file_trans_id = preview.trans_id_file_id('file-id')
3196
3100
preview.adjust_path('newname', preview.root, file_trans_id)
3197
3101
preview_tree = preview.get_preview_tree()
3201
annotation = preview_tree.annotate_iter(
3202
'file', default_revision=b'me:')
3105
annotation = preview_tree.annotate_iter('file-id', 'me:')
3203
3106
self.assertEqual(expected, annotation)
3205
3108
def test_annotate_deleted(self):
3206
3109
tree = self.make_branch_and_tree('tree')
3207
self.build_tree_contents([('tree/file', b'a\n')])
3208
tree.add('file', b'file-id')
3209
tree.commit('a', rev_id=b'one')
3210
self.build_tree_contents([('tree/file', b'a\nb\n')])
3110
self.build_tree_contents([('tree/file', 'a\n')])
3111
tree.add('file', 'file-id')
3112
tree.commit('a', rev_id='one')
3113
self.build_tree_contents([('tree/file', 'a\nb\n')])
3211
3114
preview = TransformPreview(tree)
3212
3115
self.addCleanup(preview.finalize)
3213
file_trans_id = preview.trans_id_file_id(b'file-id')
3116
file_trans_id = preview.trans_id_file_id('file-id')
3214
3117
preview.delete_contents(file_trans_id)
3215
3118
preview_tree = preview.get_preview_tree()
3216
annotation = preview_tree.annotate_iter(
3217
'file', default_revision=b'me:')
3119
annotation = preview_tree.annotate_iter('file-id', 'me:')
3218
3120
self.assertIs(None, annotation)
3220
3122
def test_stored_kind(self):
3221
3123
preview = self.get_empty_preview()
3222
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
3124
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
3223
3125
preview_tree = preview.get_preview_tree()
3224
self.assertEqual('file', preview_tree.stored_kind('file'))
3126
self.assertEqual('file', preview_tree.stored_kind('file-id'))
3226
3128
def test_is_executable(self):
3227
3129
preview = self.get_empty_preview()
3228
preview.new_file('file', preview.root, [b'a\nb\nc\n'], b'file-id')
3229
preview.set_executability(True, preview.trans_id_file_id(b'file-id'))
3130
preview.new_file('file', preview.root, 'a\nb\nc\n', 'file-id')
3131
preview.set_executability(True, preview.trans_id_file_id('file-id'))
3230
3132
preview_tree = preview.get_preview_tree()
3231
self.assertEqual(True, preview_tree.is_executable('file'))
3133
self.assertEqual(True, preview_tree.is_executable('file-id'))
3233
3135
def test_get_set_parent_ids(self):
3234
3136
revision_tree, preview_tree = self.get_tree_and_preview_tree()
3235
3137
self.assertEqual([], preview_tree.get_parent_ids())
3236
preview_tree.set_parent_ids([b'rev-1'])
3237
self.assertEqual([b'rev-1'], preview_tree.get_parent_ids())
3138
preview_tree.set_parent_ids(['rev-1'])
3139
self.assertEqual(['rev-1'], preview_tree.get_parent_ids())
3239
3141
def test_plan_file_merge(self):
3240
3142
work_a = self.make_branch_and_tree('wta')
3241
self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3242
work_a.add('file', b'file-id')
3143
self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
3144
work_a.add('file', 'file-id')
3243
3145
base_id = work_a.commit('base version')
3244
tree_b = work_a.controldir.sprout('wtb').open_workingtree()
3146
tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
3245
3147
preview = TransformPreview(work_a)
3246
3148
self.addCleanup(preview.finalize)
3247
trans_id = preview.trans_id_file_id(b'file-id')
3149
trans_id = preview.trans_id_file_id('file-id')
3248
3150
preview.delete_contents(trans_id)
3249
preview.create_file([b'b\nc\nd\ne\n'], trans_id)
3250
self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
3151
preview.create_file('b\nc\nd\ne\n', trans_id)
3152
self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
3251
3153
tree_a = preview.get_preview_tree()
3252
3154
tree_a.set_parent_ids([base_id])
3253
3155
self.assertEqual([
3254
('killed-a', b'a\n'),
3255
('killed-b', b'b\n'),
3256
('unchanged', b'c\n'),
3257
('unchanged', b'd\n'),
3260
], list(tree_a.plan_file_merge('file', tree_b)))
3156
('killed-a', 'a\n'),
3157
('killed-b', 'b\n'),
3158
('unchanged', 'c\n'),
3159
('unchanged', 'd\n'),
3162
], list(tree_a.plan_file_merge('file-id', tree_b)))
3262
3164
def test_plan_file_merge_revision_tree(self):
3263
3165
work_a = self.make_branch_and_tree('wta')
3264
self.build_tree_contents([('wta/file', b'a\nb\nc\nd\n')])
3265
work_a.add('file', b'file-id')
3166
self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
3167
work_a.add('file', 'file-id')
3266
3168
base_id = work_a.commit('base version')
3267
tree_b = work_a.controldir.sprout('wtb').open_workingtree()
3169
tree_b = work_a.bzrdir.sprout('wtb').open_workingtree()
3268
3170
preview = TransformPreview(work_a.basis_tree())
3269
3171
self.addCleanup(preview.finalize)
3270
trans_id = preview.trans_id_file_id(b'file-id')
3172
trans_id = preview.trans_id_file_id('file-id')
3271
3173
preview.delete_contents(trans_id)
3272
preview.create_file([b'b\nc\nd\ne\n'], trans_id)
3273
self.build_tree_contents([('wtb/file', b'a\nc\nd\nf\n')])
3174
preview.create_file('b\nc\nd\ne\n', trans_id)
3175
self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
3274
3176
tree_a = preview.get_preview_tree()
3275
3177
tree_a.set_parent_ids([base_id])
3276
3178
self.assertEqual([
3277
('killed-a', b'a\n'),
3278
('killed-b', b'b\n'),
3279
('unchanged', b'c\n'),
3280
('unchanged', b'd\n'),
3283
], list(tree_a.plan_file_merge('file', tree_b)))
3179
('killed-a', 'a\n'),
3180
('killed-b', 'b\n'),
3181
('unchanged', 'c\n'),
3182
('unchanged', 'd\n'),
3185
], list(tree_a.plan_file_merge('file-id', tree_b)))
3285
3187
def test_walkdirs(self):
3286
3188
preview = self.get_empty_preview()
3287
preview.new_directory('', ROOT_PARENT, b'tree-root')
3189
root = preview.new_directory('', ROOT_PARENT, 'tree-root')
3288
3190
# FIXME: new_directory should mark root.
3289
3191
preview.fixup_new_roots()
3290
3192
preview_tree = preview.get_preview_tree()
3291
preview.new_file('a', preview.root, [b'contents'], b'a-id')
3292
expected = [(('', b'tree-root'),
3293
[('a', 'a', 'file', None, b'a-id', 'file')])]
3193
file_trans_id = preview.new_file('a', preview.root, 'contents',
3195
expected = [(('', 'tree-root'),
3196
[('a', 'a', 'file', None, 'a-id', 'file')])]
3294
3197
self.assertEqual(expected, list(preview_tree.walkdirs()))
3296
3199
def test_extras(self):
3803
3707
def test_pre_commit_hooks(self):
3806
3709
def record_pre_transform(tree, tt):
3807
3710
calls.append((tree, tt))
3808
MutableTree.hooks.install_named_hook(
3809
'pre_transform', record_pre_transform, "Pre transform")
3711
MutableTree.hooks.install_named_hook('pre_transform',
3712
record_pre_transform, "Pre transform")
3810
3713
transform, root = self.get_transform()
3811
3714
old_root_id = transform.tree_file_id(root)
3812
3715
transform.apply()
3813
self.assertEqual(old_root_id, self.wt.path2id(''))
3716
self.assertEqual(old_root_id, self.wt.get_root_id())
3814
3717
self.assertEqual([(self.wt, transform)], calls)
3816
3719
def test_post_commit_hooks(self):
3819
3721
def record_post_transform(tree, tt):
3820
3722
calls.append((tree, tt))
3821
MutableTree.hooks.install_named_hook(
3822
'post_transform', record_post_transform, "Post transform")
3723
MutableTree.hooks.install_named_hook('post_transform',
3724
record_post_transform, "Post transform")
3823
3725
transform, root = self.get_transform()
3824
3726
old_root_id = transform.tree_file_id(root)
3825
3727
transform.apply()
3826
self.assertEqual(old_root_id, self.wt.path2id(''))
3728
self.assertEqual(old_root_id, self.wt.get_root_id())
3827
3729
self.assertEqual([(self.wt, transform)], calls)
3830
class TestLinkTree(tests.TestCaseWithTransport):
3832
_test_needs_features = [HardlinkFeature]
3835
tests.TestCaseWithTransport.setUp(self)
3836
self.parent_tree = self.make_branch_and_tree('parent')
3837
self.parent_tree.lock_write()
3838
self.addCleanup(self.parent_tree.unlock)
3839
self.build_tree_contents([('parent/foo', b'bar')])
3840
self.parent_tree.add('foo')
3841
self.parent_tree.commit('added foo')
3842
child_controldir = self.parent_tree.controldir.sprout('child')
3843
self.child_tree = child_controldir.open_workingtree()
3845
def hardlinked(self):
3846
parent_stat = os.lstat(self.parent_tree.abspath('foo'))
3847
child_stat = os.lstat(self.child_tree.abspath('foo'))
3848
return parent_stat.st_ino == child_stat.st_ino
3850
def test_link_fails_if_modified(self):
3851
"""If the file to be linked has modified text, don't link."""
3852
self.build_tree_contents([('child/foo', b'baz')])
3853
transform.link_tree(self.child_tree, self.parent_tree)
3854
self.assertFalse(self.hardlinked())
3856
def test_link_fails_if_execute_bit_changed(self):
3857
"""If the file to be linked has modified execute bit, don't link."""
3858
tt = TreeTransform(self.child_tree)
3860
trans_id = tt.trans_id_tree_path('foo')
3861
tt.set_executability(True, trans_id)
3865
transform.link_tree(self.child_tree, self.parent_tree)
3866
self.assertFalse(self.hardlinked())
3868
def test_link_succeeds_if_unmodified(self):
3869
"""If the file to be linked is unmodified, link"""
3870
transform.link_tree(self.child_tree, self.parent_tree)
3871
self.assertTrue(self.hardlinked())