688
691
# This will unlock it
689
692
self.check_state_with_reopen(expected_result, state)
694
def test_set_state_from_inventory_mixed_paths(self):
695
tree1 = self.make_branch_and_tree('tree1')
696
self.build_tree(['tree1/a/', 'tree1/a/b/', 'tree1/a-b/',
697
'tree1/a/b/foo', 'tree1/a-b/bar'])
700
tree1.add(['a', 'a/b', 'a-b', 'a/b/foo', 'a-b/bar'],
701
['a-id', 'b-id', 'a-b-id', 'foo-id', 'bar-id'])
702
tree1.commit('rev1', rev_id='rev1')
703
root_id = tree1.get_root_id()
704
inv = tree1.inventory
707
expected_result1 = [('', '', root_id, 'd'),
708
('', 'a', 'a-id', 'd'),
709
('', 'a-b', 'a-b-id', 'd'),
710
('a', 'b', 'b-id', 'd'),
711
('a/b', 'foo', 'foo-id', 'f'),
712
('a-b', 'bar', 'bar-id', 'f'),
714
expected_result2 = [('', '', root_id, 'd'),
715
('', 'a', 'a-id', 'd'),
716
('', 'a-b', 'a-b-id', 'd'),
717
('a-b', 'bar', 'bar-id', 'f'),
719
state = dirstate.DirState.initialize('dirstate')
721
state.set_state_from_inventory(inv)
723
for entry in state._iter_entries():
724
values.append(entry[0] + entry[1][0][:1])
725
self.assertEqual(expected_result1, values)
727
state.set_state_from_inventory(inv)
729
for entry in state._iter_entries():
730
values.append(entry[0] + entry[1][0][:1])
731
self.assertEqual(expected_result2, values)
691
735
def test_set_path_id_no_parents(self):
692
736
"""The id of a path can be changed trivally with no parents."""
693
737
state = dirstate.DirState.initialize('dirstate')
1448
1492
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1449
1493
state._dirblock_state)
1494
self.assertEqual([('f', '', 14, False, dirstate.DirState.NULLSTAT)],
1452
1498
# However, if we move the clock forward so the file is considered
1453
# "stable", it should just returned the cached value.
1454
state.adjust_time(20)
1499
# "stable", it should just cache the value.
1500
state.adjust_time(+20)
1455
1501
link_or_sha1 = state.update_entry(entry, abspath='a',
1456
1502
stat_value=stat_value)
1457
1503
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1459
1505
self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1460
1506
('sha1', 'a'), ('is_exec', mode, False),
1507
('sha1', 'a'), ('is_exec', mode, False),
1509
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1463
def test_update_entry_no_stat_value(self):
1464
"""Passing the stat_value is optional."""
1465
state, entry = self.get_state_with_a()
1466
state.adjust_time(-10) # Make sure the file looks new
1467
self.build_tree(['a'])
1468
# Add one where we don't provide the stat or sha already
1469
link_or_sha1 = state.update_entry(entry, abspath='a')
1512
# Subsequent calls will just return the cached value
1513
link_or_sha1 = state.update_entry(entry, abspath='a',
1514
stat_value=stat_value)
1470
1515
self.assertEqual('b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6',
1472
stat_value = os.lstat('a')
1473
self.assertEqual([('lstat', 'a'), ('sha1', 'a'),
1474
('is_exec', stat_value.st_mode, False),
1517
self.assertEqual([('sha1', 'a'), ('is_exec', mode, False),
1518
('sha1', 'a'), ('is_exec', mode, False),
1519
('sha1', 'a'), ('is_exec', mode, False),
1521
self.assertEqual([('f', link_or_sha1, 14, False, packed_stat)],
1477
1524
def test_update_entry_symlink(self):
1478
1525
"""Update entry should read symlinks."""
1492
1539
stat_value=stat_value)
1493
1540
self.assertEqual('target', link_or_sha1)
1494
1541
self.assertEqual([('read_link', 'a', '')], state._log)
1495
# Dirblock is updated
1496
self.assertEqual([('l', link_or_sha1, 6, False, packed_stat)],
1542
# Dirblock is not updated (the link is too new)
1543
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1498
1545
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1499
1546
state._dirblock_state)
1503
1550
stat_value=stat_value)
1504
1551
self.assertEqual('target', link_or_sha1)
1505
1552
self.assertEqual([('read_link', 'a', ''),
1506
('read_link', 'a', 'target'),
1553
('read_link', 'a', ''),
1555
self.assertEqual([('l', '', 6, False, dirstate.DirState.NULLSTAT)],
1508
1557
state.adjust_time(+20) # Skip into the future, all files look old
1509
1558
link_or_sha1 = state.update_entry(entry, abspath='a',
1510
1559
stat_value=stat_value)
1511
1560
self.assertEqual('target', link_or_sha1)
1512
# There should not be a new read_link call.
1513
# (this is a weak assertion, because read_link is fairly inexpensive,
1514
# versus the number of symlinks that we would have)
1515
self.assertEqual([('read_link', 'a', ''),
1516
('read_link', 'a', 'target'),
1561
# We need to re-read the link because only now can we cache it
1562
self.assertEqual([('read_link', 'a', ''),
1563
('read_link', 'a', ''),
1564
('read_link', 'a', ''),
1566
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1569
# Another call won't re-read the link
1570
self.assertEqual([('read_link', 'a', ''),
1571
('read_link', 'a', ''),
1572
('read_link', 'a', ''),
1574
link_or_sha1 = state.update_entry(entry, abspath='a',
1575
stat_value=stat_value)
1576
self.assertEqual('target', link_or_sha1)
1577
self.assertEqual([('l', 'target', 6, False, packed_stat)],
1580
def do_update_entry(self, state, entry, abspath):
1581
stat_value = os.lstat(abspath)
1582
return state.update_entry(entry, abspath, stat_value)
1519
1584
def test_update_entry_dir(self):
1520
1585
state, entry = self.get_state_with_a()
1521
1586
self.build_tree(['a/'])
1522
self.assertIs(None, state.update_entry(entry, 'a'))
1587
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1589
def test_update_entry_dir_unchanged(self):
1590
state, entry = self.get_state_with_a()
1591
self.build_tree(['a/'])
1592
state.adjust_time(+20)
1593
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1594
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1595
state._dirblock_state)
1597
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1598
state._dirblock_state)
1599
self.assertIs(None, self.do_update_entry(state, entry, 'a'))
1600
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1601
state._dirblock_state)
1603
def test_update_entry_file_unchanged(self):
1604
state, entry = self.get_state_with_a()
1605
self.build_tree(['a'])
1606
sha1sum = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1607
state.adjust_time(+20)
1608
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1609
self.assertEqual(dirstate.DirState.IN_MEMORY_MODIFIED,
1610
state._dirblock_state)
1612
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1613
state._dirblock_state)
1614
self.assertEqual(sha1sum, self.do_update_entry(state, entry, 'a'))
1615
self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
1616
state._dirblock_state)
1524
1618
def create_and_test_file(self, state, entry):
1525
1619
"""Create a file at 'a' and verify the state finds it.
1569
1663
stat_value = os.lstat('a')
1570
1664
packed_stat = dirstate.pack_stat(stat_value)
1572
link_or_sha1 = state.update_entry(entry, abspath='a')
1666
link_or_sha1 = self.do_update_entry(state, entry, abspath='a')
1573
1667
self.assertEqual('path/to/foo', link_or_sha1)
1574
1668
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1576
1670
return packed_stat
1578
def test_update_missing_file(self):
1579
state, entry = self.get_state_with_a()
1580
packed_stat = self.create_and_test_file(state, entry)
1581
# Now if we delete the file, update_entry should recover and
1584
self.assertIs(None, state.update_entry(entry, abspath='a'))
1585
# And the record shouldn't be changed.
1586
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1587
self.assertEqual([('f', digest, 14, False, packed_stat)],
1590
def test_update_missing_dir(self):
1591
state, entry = self.get_state_with_a()
1592
packed_stat = self.create_and_test_dir(state, entry)
1593
# Now if we delete the directory, update_entry should recover and
1596
self.assertIs(None, state.update_entry(entry, abspath='a'))
1597
self.assertEqual([('d', '', 0, False, packed_stat)], entry[1])
1599
def test_update_missing_symlink(self):
1600
if not osutils.has_symlinks():
1601
# PlatformDeficiency / TestSkipped
1602
raise TestSkipped("No symlink support")
1603
state, entry = self.get_state_with_a()
1604
packed_stat = self.create_and_test_symlink(state, entry)
1606
self.assertIs(None, state.update_entry(entry, abspath='a'))
1607
# And the record shouldn't be changed.
1608
self.assertEqual([('l', 'path/to/foo', 11, False, packed_stat)],
1611
1672
def test_update_file_to_dir(self):
1612
1673
"""If a file changes to a directory we return None for the sha.
1613
1674
We also update the inventory record.
1615
1676
state, entry = self.get_state_with_a()
1677
# The file sha1 won't be cached unless the file is old
1678
state.adjust_time(+10)
1616
1679
self.create_and_test_file(state, entry)
1618
1681
self.create_and_test_dir(state, entry)
1677
1750
packed_stat = dirstate.pack_stat(stat_value)
1679
1752
state.adjust_time(-10) # Make sure everything is new
1680
# Make sure it wants to kkkkkkkk
1681
1753
state.update_entry(entry, abspath='a', stat_value=stat_value)
1683
1755
# The row is updated, but the executable bit stays set.
1756
self.assertEqual([('f', '', 14, True, dirstate.DirState.NULLSTAT)],
1759
# Make the disk object look old enough to cache
1760
state.adjust_time(+20)
1684
1761
digest = 'b50e5406bb5e153ebbeb20268fcf37c87e1ecfb6'
1762
state.update_entry(entry, abspath='a', stat_value=stat_value)
1685
1763
self.assertEqual([('f', digest, 14, True, packed_stat)], entry[1])