289
289
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
290
290
self.assertEqual(rev1, tree1.get_file_revision(u''))
291
291
if tree.branch.repository.supports_rich_root():
292
self.assertEqual(rev1,tree2.get_file_revision(u''))
292
self.assertEqual(rev1, tree2.get_file_revision(u''))
294
294
self.assertEqual(rev2, tree2.get_file_revision(u''))
296
def _add_commit_check_unchanged(self, tree, name, mini_commit=None):
296
def _add_commit_check_unchanged(self, tree, name):
298
self._commit_check_unchanged(tree, name, tree.path2id(name),
299
mini_commit=mini_commit)
298
self._commit_check_unchanged(tree, name, tree.path2id(name))
301
def _commit_check_unchanged(self, tree, name, file_id, mini_commit=None):
300
def _commit_check_unchanged(self, tree, name, file_id):
302
301
rev1 = tree.commit('')
303
rev2 = mini_commit(tree, name, name, False, False)
302
rev2 = self.mini_commit_record_iter_changes(tree, name, name, False, False)
304
303
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
305
self.assertEqual(rev1, tree1.get_file_revision(tree1.id2path(file_id)))
306
self.assertEqual(rev1, tree2.get_file_revision(tree2.id2path(file_id)))
304
self.assertEqual(rev1, tree1.get_file_revision(name))
305
self.assertEqual(rev1, tree2.get_file_revision(name))
307
306
expected_graph = {}
308
307
expected_graph[(file_id, rev1)] = ()
309
308
self.assertFileGraph(expected_graph, tree, (file_id, rev1))
311
310
def test_last_modified_revision_after_commit_dir_unchanged(self):
312
311
# committing without changing a dir does not change the last modified.
313
312
tree = self.make_branch_and_tree('.')
313
if not tree.has_versioned_directories():
314
raise tests.TestNotApplicable(
315
'Format does not support versioned directories')
314
316
self.build_tree(['dir/'])
315
self._add_commit_check_unchanged(tree, 'dir',
316
mini_commit=self.mini_commit_record_iter_changes)
317
self._add_commit_check_unchanged(tree, 'dir')
318
319
def test_last_modified_revision_after_commit_dir_contents_unchanged(self):
319
320
# committing without changing a dir does not change the last modified
320
321
# of the dir even the dirs contents are changed.
321
322
tree = self.make_branch_and_tree('.')
322
self.build_tree(['dir/'])
323
self.build_tree(['dir/', 'dir/orig'])
324
tree.add(['dir', 'dir/orig'])
324
325
dir_id = tree.path2id('dir')
325
326
rev1 = tree.commit('')
326
327
self.build_tree(['dir/content'])
327
328
tree.add(['dir/content'])
328
329
rev2 = tree.commit('')
329
330
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
330
if self.repository_format.supports_versioned_directories:
331
# In VCSes that don't support empty directories, 'dir' doesn't
333
self.assertEqual(rev1, tree1.get_file_revision('dir'))
331
self.assertEqual(rev1, tree1.get_file_revision('dir'))
334
332
self.assertEqual(rev1, tree2.get_file_revision('dir'))
336
expected_graph[(dir_id, rev1)] = ()
333
expected_graph = {(dir_id, rev1): ()}
337
334
self.assertFileGraph(expected_graph, tree, (dir_id, rev1))
339
336
def test_last_modified_revision_after_commit_file_unchanged(self):
340
337
# committing without changing a file does not change the last modified.
341
338
tree = self.make_branch_and_tree('.')
342
339
self.build_tree(['file'])
343
self._add_commit_check_unchanged(tree, 'file',
344
mini_commit=self.mini_commit_record_iter_changes)
340
self._add_commit_check_unchanged(tree, 'file')
346
342
def test_last_modified_revision_after_commit_link_unchanged(self):
347
343
# committing without changing a link does not change the last modified.
348
344
self.requireFeature(features.SymlinkFeature)
349
345
tree = self.make_branch_and_tree('.')
350
346
os.symlink('target', 'link')
351
self._add_commit_check_unchanged(tree, 'link',
352
mini_commit=self.mini_commit_record_iter_changes)
347
self._add_commit_check_unchanged(tree, 'link')
354
349
def test_last_modified_revision_after_commit_reference_unchanged(self):
355
350
# committing without changing a subtree does not change the last
360
355
tree.add_reference(subtree)
361
356
self._commit_check_unchanged(tree, 'reference',
362
subtree.get_root_id(),
363
mini_commit=self.mini_commit_record_iter_changes)
357
subtree.get_root_id())
364
358
except errors.UnsupportedOperation:
367
361
def _add_commit_renamed_check_changed(self, tree, name,
368
expect_fs_hash=False, mini_commit=None):
362
expect_fs_hash=False):
370
364
tree.rename_one(name, 'new_' + name)
371
self._add_commit_change_check_changed(tree, name, rename,
372
expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
365
self._add_commit_change_check_changed(tree,
366
(name, 'new_' + name), rename,
367
expect_fs_hash=expect_fs_hash)
374
def _commit_renamed_check_changed(self, tree, name, file_id,
375
expect_fs_hash=False, mini_commit=None):
369
def _commit_renamed_check_changed(self, tree, name,
370
expect_fs_hash=False):
377
372
tree.rename_one(name, 'new_' + name)
378
self._commit_change_check_changed(tree, name, file_id, rename,
379
expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
373
self._commit_change_check_changed(tree, [name, 'new_' + name],
374
rename, expect_fs_hash=expect_fs_hash)
381
376
def test_last_modified_revision_after_rename_dir_changes(self):
382
377
# renaming a dir changes the last modified.
383
378
tree = self.make_branch_and_tree('.')
384
379
self.build_tree(['dir/'])
385
self._add_commit_renamed_check_changed(tree, 'dir',
386
mini_commit=self.mini_commit_record_iter_changes)
380
self._add_commit_renamed_check_changed(tree, 'dir')
388
382
def test_last_modified_revision_after_rename_file_changes(self):
389
383
# renaming a file changes the last modified.
390
384
tree = self.make_branch_and_tree('.')
391
385
self.build_tree(['file'])
392
386
self._add_commit_renamed_check_changed(tree, 'file',
394
mini_commit=self.mini_commit_record_iter_changes)
396
389
def test_last_modified_revision_after_rename_link_changes(self):
397
390
# renaming a link changes the last modified.
398
391
self.requireFeature(features.SymlinkFeature)
399
392
tree = self.make_branch_and_tree('.')
400
393
os.symlink('target', 'link')
401
self._add_commit_renamed_check_changed(tree, 'link',
402
mini_commit=self.mini_commit_record_iter_changes)
394
self._add_commit_renamed_check_changed(tree, 'link')
404
396
def test_last_modified_revision_after_rename_ref_changes(self):
405
397
# renaming a reference changes the last modified.
407
399
subtree = self.make_reference('reference')
409
401
tree.add_reference(subtree)
410
self._commit_renamed_check_changed(tree, 'reference',
411
subtree.get_root_id(),
412
mini_commit=self.mini_commit_record_iter_changes)
402
self._commit_renamed_check_changed(tree, 'reference')
413
403
except errors.UnsupportedOperation:
416
406
def _add_commit_reparent_check_changed(self, tree, name,
417
expect_fs_hash=False, mini_commit=None):
407
expect_fs_hash=False):
418
408
self.build_tree(['newparent/'])
419
409
tree.add(['newparent'])
421
411
tree.rename_one(name, 'newparent/new_' + name)
422
self._add_commit_change_check_changed(tree, name, reparent,
423
expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
412
self._add_commit_change_check_changed(
413
tree, (name, 'newparent/new_' + name), reparent,
414
expect_fs_hash=expect_fs_hash)
425
416
def test_last_modified_revision_after_reparent_dir_changes(self):
426
417
# reparenting a dir changes the last modified.
427
418
tree = self.make_branch_and_tree('.')
428
419
self.build_tree(['dir/'])
429
self._add_commit_reparent_check_changed(tree, 'dir',
430
mini_commit=self.mini_commit_record_iter_changes)
420
self._add_commit_reparent_check_changed(tree, 'dir')
432
422
def test_last_modified_revision_after_reparent_file_changes(self):
433
423
# reparenting a file changes the last modified.
434
424
tree = self.make_branch_and_tree('.')
435
425
self.build_tree(['file'])
436
426
self._add_commit_reparent_check_changed(tree, 'file',
438
mini_commit=self.mini_commit_record_iter_changes)
440
429
def test_last_modified_revision_after_reparent_link_changes(self):
441
430
# reparenting a link changes the last modified.
442
431
self.requireFeature(features.SymlinkFeature)
443
432
tree = self.make_branch_and_tree('.')
444
433
os.symlink('target', 'link')
445
self._add_commit_reparent_check_changed(tree, 'link',
446
mini_commit=self.mini_commit_record_iter_changes)
434
self._add_commit_reparent_check_changed(tree, 'link')
448
def _add_commit_change_check_changed(self, tree, name, changer,
449
expect_fs_hash=False, mini_commit=None):
451
file_id = tree.path2id(name)
452
self.assertIsNot(None, file_id)
436
def _add_commit_change_check_changed(self, tree, names, changer,
437
expect_fs_hash=False):
439
self.assertTrue(tree.is_versioned(names[0]))
453
440
self._commit_change_check_changed(
455
changer, expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
442
changer, expect_fs_hash=expect_fs_hash)
457
def _commit_change_check_changed(self, tree, name, file_id, changer,
458
expect_fs_hash=False, mini_commit=None):
444
def _commit_change_check_changed(self, tree, names, changer,
445
expect_fs_hash=False):
459
446
rev1 = tree.commit('')
461
rev2 = mini_commit(tree, name, tree.id2path(file_id),
462
expect_fs_hash=expect_fs_hash)
448
rev2 = self.mini_commit_record_iter_changes(
449
tree, names[0], names[1], expect_fs_hash=expect_fs_hash)
463
450
tree1, tree2 = self._get_revtrees(tree, [rev1, rev2])
464
self.assertEqual(rev1, tree1.get_file_revision(tree1.id2path(file_id)))
465
self.assertEqual(rev2, tree2.get_file_revision(tree2.id2path(file_id)))
451
self.assertEqual(rev1, tree1.get_file_revision(names[0]))
452
self.assertEqual(rev2, tree2.get_file_revision(names[1]))
453
file_id = tree1.path2id(names[0])
466
454
expected_graph = {}
467
455
expected_graph[(file_id, rev1)] = ()
468
456
expected_graph[(file_id, rev2)] = ((file_id, rev1),)
484
472
:param expect_fs_hash: If true, looks for a fs hash output from
485
473
record_iter_changes.
475
with tree.lock_write():
489
476
# mini manual commit here so we can check the return of
490
477
# record_iter_changes
491
478
parent_ids = tree.get_parent_ids()
492
479
builder = tree.branch.get_commit_builder(parent_ids)
493
parent_tree = tree.basis_tree()
494
parent_tree.lock_read()
495
self.addCleanup(parent_tree.unlock)
496
parent_trees = [parent_tree]
497
for parent_id in parent_ids[1:]:
498
parent_trees.append(tree.branch.repository.revision_tree(
500
changes = list(tree.iter_changes(parent_tree))
501
result = list(builder.record_iter_changes(tree, parent_ids[0],
503
file_id = tree.path2id(new_name)
504
self.assertIsNot(None, file_id)
506
tree_file_stat = tree.get_file_with_stat(new_name)
507
tree_file_stat[0].close()
508
self.assertLength(1, result)
510
self.assertEqual(result[:2], (file_id, new_name))
511
self.assertEqual(result[2][0], tree.get_file_sha1(new_name))
512
self.assertEqualStat(result[2][1], tree_file_stat[1])
514
self.assertEqual([], result)
515
builder.finish_inventory()
516
if tree.branch.repository._format.supports_full_versioned_files:
517
inv_key = (builder._new_revision_id,)
518
inv_sha1 = tree.branch.repository.inventories.get_sha1s(
520
self.assertEqual(inv_sha1, builder.inv_sha1)
521
rev2 = builder.commit('')
481
parent_tree = tree.basis_tree()
482
with parent_tree.lock_read():
483
changes = list(tree.iter_changes(parent_tree))
484
result = list(builder.record_iter_changes(tree, parent_ids[0],
486
file_id = tree.path2id(new_name)
487
self.assertIsNot(None, file_id)
489
tree_file_stat = tree.get_file_with_stat(new_name)
490
tree_file_stat[0].close()
491
self.assertLength(1, result)
493
self.assertEqual(result[:2], (file_id, new_name))
494
self.assertEqual(result[2][0], tree.get_file_sha1(new_name))
495
self.assertEqualStat(result[2][1], tree_file_stat[1])
497
self.assertEqual([], result)
498
builder.finish_inventory()
499
if tree.branch.repository._format.supports_full_versioned_files:
500
inv_key = (builder._new_revision_id,)
501
inv_sha1 = tree.branch.repository.inventories.get_sha1s(
503
self.assertEqual(inv_sha1, builder.inv_sha1)
504
rev2 = builder.commit('')
505
except BaseException:
522
508
delta = builder.get_basis_delta()
523
509
delta_dict = dict((change[2], change) for change in delta)
524
510
version_recorded = (file_id in delta_dict and
530
516
self.assertFalse(version_recorded)
532
new_inventory = builder.revision_tree().root_inventory
533
new_entry = new_inventory[file_id]
518
revtree = builder.revision_tree()
519
new_entry = revtree.iter_entries_by_dir(specific_files=[new_name]).next()[1]
534
521
if delta_against_basis:
535
expected_delta = (name, new_name, file_id, new_entry)
522
if tree.supports_rename_tracking() or name == new_name:
523
expected_delta = (name, new_name, file_id, new_entry)
525
expected_delta = (None, new_name, file_id, new_entry)
536
526
self.assertEqual(expected_delta, delta_dict[file_id])
538
528
expected_delta = None
539
529
self.assertFalse(version_recorded)
540
530
tree.set_parent_ids([rev2])
549
533
def assertFileGraph(self, expected_graph, tree, tip):
605
586
rev2 = self._rename_in_tree(tree1, name)
606
587
rev3 = self._rename_in_tree(tree2, name)
607
588
tree1.merge_from_branch(tree2.branch)
608
rev4 = mini_commit(tree1, 'new_' + name, 'new_' + name,
589
rev4 = self.mini_commit_record_iter_changes(tree1, 'new_' + name, 'new_' + name,
609
590
expect_fs_hash=expect_fs_hash)
610
591
tree3, = self._get_revtrees(tree1, [rev4])
611
self.assertEqual(rev4, tree3.get_file_revision(tree3.id2path(file_id)))
592
self.assertEqual(rev4, tree3.get_file_revision('new_' + name))
612
593
expected_graph = {}
613
594
expected_graph[(file_id, rev1)] = ()
614
595
expected_graph[(file_id, rev2)] = ((file_id, rev1),)
619
600
def test_last_modified_revision_after_merge_dir_changes(self):
620
601
# merge a dir changes the last modified.
621
602
tree1 = self.make_branch_and_tree('t1')
603
if not tree1.has_versioned_directories():
604
raise tests.TestNotApplicable(
605
'Format does not support versioned directories')
622
606
self.build_tree(['t1/dir/'])
623
self._commit_sprout_rename_merge(tree1, 'dir',
624
mini_commit=self.mini_commit_record_iter_changes)
607
self._commit_sprout_rename_merge(tree1, 'dir')
626
609
def test_last_modified_revision_after_merge_file_changes(self):
627
610
# merge a file changes the last modified.
628
611
tree1 = self.make_branch_and_tree('t1')
629
612
self.build_tree(['t1/file'])
630
self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True,
631
mini_commit=self.mini_commit_record_iter_changes)
613
self._commit_sprout_rename_merge(tree1, 'file', expect_fs_hash=True)
633
615
def test_last_modified_revision_after_merge_link_changes(self):
634
616
# merge a link changes the last modified.
635
617
self.requireFeature(features.SymlinkFeature)
636
618
tree1 = self.make_branch_and_tree('t1')
637
619
os.symlink('target', 't1/link')
638
self._commit_sprout_rename_merge(tree1, 'link',
639
mini_commit=self.mini_commit_record_iter_changes)
620
self._commit_sprout_rename_merge(tree1, 'link')
641
def _commit_sprout_rename_merge_converged(self, tree1, name,
622
def _commit_sprout_rename_merge_converged(self, tree1, name):
643
623
# Make a merge which just incorporates a change from a branch:
644
624
# The per-file graph is straight line, and no alteration occurs
645
625
# in the inventory.
651
631
rev2 = self._rename_in_tree(tree2, name)
652
632
tree1.merge_from_branch(tree2.branch)
653
633
def _check_graph(in_tree, changed_in_tree):
654
rev3 = mini_commit(in_tree, name, 'new_' + name, False,
655
delta_against_basis=changed_in_tree)
634
rev3 = self.mini_commit_record_iter_changes(
635
in_tree, name, 'new_' + name, False,
636
delta_against_basis=changed_in_tree)
656
637
tree3, = self._get_revtrees(in_tree, [rev2])
657
638
self.assertEqual(
659
tree3.get_file_revision(tree3.id2path(file_id), file_id))
640
tree3.get_file_revision('new_' + name, file_id))
660
641
expected_graph = {}
661
642
expected_graph[(file_id, rev1)] = ()
662
643
expected_graph[(file_id, rev2)] = ((file_id, rev1),)
679
660
# make and commit on the other side to merge back
681
662
tree2.add(['name'])
682
file_id = tree2.path2id('name')
683
self.assertIsNot(None, file_id)
663
self.assertTrue(tree2.is_versioned('name'))
684
664
rev2 = tree2.commit('')
685
665
tree1.merge_from_branch(tree2.branch)
686
rev3 = mini_commit(tree1, None, 'name', False)
666
rev3 = self.mini_commit_record_iter_changes(tree1, None, 'name', False)
687
667
tree3, = self._get_revtrees(tree1, [rev2])
688
668
# in rev2, name should be only changed in rev2
689
self.assertEqual(rev2, tree3.get_file_revision(tree3.id2path(file_id)))
669
self.assertEqual(rev2, tree3.get_file_revision('name'))
670
file_id = tree2.path2id('name')
690
671
expected_graph = {}
691
672
expected_graph[(file_id, rev2)] = ()
692
673
self.assertFileGraph(expected_graph, tree1, (file_id, rev2))
694
675
def test_last_modified_revision_after_converged_merge_dir_unchanged(self):
695
676
# merge a dir that changed preserves the last modified.
696
677
tree1 = self.make_branch_and_tree('t1')
678
if not tree1.has_versioned_directories():
679
raise tests.TestNotApplicable(
680
'Format does not support versioned directories')
697
681
self.build_tree(['t1/dir/'])
698
self._commit_sprout_rename_merge_converged(tree1, 'dir',
699
mini_commit=self.mini_commit_record_iter_changes)
682
self._commit_sprout_rename_merge_converged(tree1, 'dir')
701
684
def test_last_modified_revision_after_converged_merge_file_unchanged(self):
702
685
# merge a file that changed preserves the last modified.
703
686
tree1 = self.make_branch_and_tree('t1')
704
687
self.build_tree(['t1/file'])
705
self._commit_sprout_rename_merge_converged(tree1, 'file',
706
mini_commit=self.mini_commit_record_iter_changes)
688
self._commit_sprout_rename_merge_converged(tree1, 'file')
708
690
def test_last_modified_revision_after_converged_merge_link_unchanged(self):
709
691
# merge a link that changed preserves the last modified.
710
692
self.requireFeature(features.SymlinkFeature)
711
693
tree1 = self.make_branch_and_tree('t1')
712
694
os.symlink('target', 't1/link')
713
self._commit_sprout_rename_merge_converged(tree1, 'link',
714
mini_commit=self.mini_commit_record_iter_changes)
695
self._commit_sprout_rename_merge_converged(tree1, 'link')
716
697
def test_last_modified_revision_after_merge_new_dir_unchanged(self):
717
698
# merge a new dir does not change the last modified.
718
699
tree1 = self.make_branch_and_tree('t1')
719
self._commit_sprout_make_merge(tree1, self.make_dir,
720
mini_commit=self.mini_commit_record_iter_changes)
700
self._commit_sprout_make_merge(tree1, self.make_dir)
722
702
def test_last_modified_revision_after_merge_new_file_unchanged(self):
723
703
# merge a new file does not change the last modified.
724
704
tree1 = self.make_branch_and_tree('t1')
725
self._commit_sprout_make_merge(tree1, self.make_file,
726
mini_commit=self.mini_commit_record_iter_changes)
705
self._commit_sprout_make_merge(tree1, self.make_file)
728
707
def test_last_modified_revision_after_merge_new_link_unchanged(self):
729
708
# merge a new link does not change the last modified.
730
709
tree1 = self.make_branch_and_tree('t1')
731
self._commit_sprout_make_merge(tree1, self.make_link,
732
mini_commit=self.mini_commit_record_iter_changes)
710
self._commit_sprout_make_merge(tree1, self.make_link)
734
712
def make_dir(self, name):
735
713
self.build_tree([name + '/'])