577
578
self.assertEqual([], changes)
578
579
self.assertEqual(['', 'versioned', 'versioned2'], returned)
581
class TestCorruptDirstate(TestCaseWithTransport):
582
"""Tests for how we handle when the dirstate has been corrupted."""
584
def create_wt4(self):
585
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
586
control.create_repository()
587
control.create_branch()
588
tree = workingtree_4.WorkingTreeFormat4().initialize(control)
581
def get_tree_with_cachable_file_foo(self):
582
tree = self.make_branch_and_tree('.')
583
self.build_tree(['foo'])
584
tree.add(['foo'], ['foo-id'])
585
# a 4 second old timestamp is always hashable - sucks to delay
586
# the test suite, but not testing this is worse.
591
def test_invalid_rename(self):
592
tree = self.create_wt4()
593
# Create a corrupted dirstate
590
def test_commit_updates_hash_cache(self):
591
tree = self.get_tree_with_cachable_file_foo()
592
revid = tree.commit('a commit')
593
# tree's dirstate should now have a valid stat entry for foo.
595
entry = tree._get_entry(path='foo')
596
expected_sha1 = osutils.sha_file_by_name('foo')
597
self.assertEqual(expected_sha1, entry[1][0][1])
599
def test_observed_sha1_cachable(self):
600
tree = self.get_tree_with_cachable_file_foo()
601
expected_sha1 = osutils.sha_file_by_name('foo')
594
602
tree.lock_write()
596
tree.commit('init') # We need a parent, or we always compare with NULL
597
state = tree.current_dirstate()
598
state._read_dirblocks_if_needed()
599
# Now add in an invalid entry, a rename with a dangling pointer
600
state._dirblocks[1][1].append((('', 'foo', 'foo-id'),
601
[('f', '', 0, False, ''),
602
('r', 'bar', 0 , False, '')]))
603
self.assertListRaises(errors.CorruptDirstate,
604
tree.iter_changes, tree.basis_tree())
604
tree._observed_sha1("foo-id", "foo", expected_sha1)
605
self.assertEqual(expected_sha1,
606
tree._get_entry(path="foo")[1][0][1])
608
def get_simple_dirblocks(self, state):
609
"""Extract the simple information from the DirState.
611
This returns the dirblocks, only with the sha1sum and stat details
615
for block in state._dirblocks:
616
simple_block = (block[0], [])
617
for entry in block[1]:
618
# Include the key for each entry, and for each parent include
619
# just the minikind, so we know if it was
620
# present/absent/renamed/etc
621
simple_block[1].append((entry[0], [i[0] for i in entry[1]]))
622
simple_blocks.append(simple_block)
625
def test_update_basis_with_invalid_delta(self):
626
"""When given an invalid delta, it should abort, and not be saved."""
627
self.build_tree(['dir/', 'dir/file'])
628
tree = self.create_wt4()
609
tree = tree.bzrdir.open_workingtree()
630
611
self.addCleanup(tree.unlock)
631
tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
632
first_revision_id = tree.commit('init')
634
root_id = tree.path2id('')
635
state = tree.current_dirstate()
636
state._read_dirblocks_if_needed()
638
('', [(('', '', root_id), ['d', 'd'])]),
639
('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
640
('dir', [(('dir', 'file', 'file-id'), ['f', 'f'])]),
641
], self.get_simple_dirblocks(state))
643
tree.remove(['dir/file'])
645
('', [(('', '', root_id), ['d', 'd'])]),
646
('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
647
('dir', [(('dir', 'file', 'file-id'), ['a', 'f'])]),
648
], self.get_simple_dirblocks(state))
649
# Make sure the removal is written to disk
652
# self.assertRaises(Exception, tree.update_basis_by_delta,
653
new_dir = inventory.InventoryDirectory('dir-id', 'new-dir', root_id)
654
new_dir.revision = 'new-revision-id'
655
new_file = inventory.InventoryFile('file-id', 'new-file', root_id)
656
new_file.revision = 'new-revision-id'
657
self.assertRaises(errors.InconsistentDelta,
658
tree.update_basis_by_delta, 'new-revision-id',
659
[('dir', 'new-dir', 'dir-id', new_dir),
660
('dir/file', 'new-dir/new-file', 'file-id', new_file),
664
# Now when we re-read the file it should not have been modified
612
self.assertEqual(expected_sha1, tree._get_entry(path="foo")[1][0][1])
614
def test_observed_sha1_new_file(self):
615
tree = self.make_branch_and_tree('.')
616
self.build_tree(['foo'])
617
tree.add(['foo'], ['foo-id'])
667
self.assertEqual(first_revision_id, tree.last_revision())
668
state = tree.current_dirstate()
669
state._read_dirblocks_if_needed()
671
('', [(('', '', root_id), ['d', 'd'])]),
672
('', [(('', 'dir', 'dir-id'), ['d', 'd'])]),
673
('dir', [(('dir', 'file', 'file-id'), ['a', 'f'])]),
674
], self.get_simple_dirblocks(state))
620
current_sha1 = tree._get_entry(path="foo")[1][0][1]
625
tree._observed_sha1("foo-id", "foo",
626
osutils.sha_file_by_name('foo'))
627
# Must not have changed
628
self.assertEqual(current_sha1,
629
tree._get_entry(path="foo")[1][0][1])