1505
1505
# TODO: check new id is unique
1506
1506
entry = self._get_entry(0, path_utf8=path)
1507
1507
# mark the old path absent, and insert a new root path
1508
present_parents = len(entry[1]) - 1
1509
1508
self._make_absent(entry)
1510
1509
id_index = self._get_id_index()
1511
self.update_minimal(('', '', new_id), 'directory', present_parents,
1510
self.update_minimal(('', '', new_id), 'd',
1512
1511
path_utf8='', id_index=id_index, packed_stat=entry[1][0][4])
1513
1512
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
1664
1663
# generate a byid index of the dirstate
1665
1664
id_index = self._get_id_index()
1667
num_present_parents = len(self._parents) - len(self._ghosts)
1668
1666
# incremental algorithm:
1669
1667
# two iterators: current data and new data, both in dirblock order.
1670
1668
new_iterator = new_inv.iter_entries_by_dir()
1692
1690
new_dirname, new_basename = os.path.split(new_path_utf8)
1693
1691
new_id = current_new[1].file_id
1694
1692
new_entry_key = (new_dirname, new_basename, new_id)
1693
current_new_minikind = \
1694
DirState._kind_to_minikind[current_new[1].kind]
1696
1696
# for safety disable variables
1697
1697
new_path_utf8 = new_dirname = new_basename = new_id = new_entry_key = None
1699
1699
# we make both end conditions explicit
1700
1700
if not current_old:
1701
1701
# old is finished: insert current_new into the state.
1702
self.update_minimal(new_entry_key, current_new[1].kind,
1703
num_present_parents, executable=current_new[1].executable,
1702
self.update_minimal(new_entry_key, current_new_minikind,
1703
executable=current_new[1].executable,
1704
1704
id_index=id_index, path_utf8=new_path_utf8)
1705
1705
current_new = advance(new_iterator)
1706
1706
elif not current_new:
1712
1712
# TODO: update the record if anything significant has changed.
1713
1713
# the minimal required trigger is if the execute bit or cached
1714
1714
# kind has changed.
1715
kind = DirState._minikind_to_kind[current_old[1][0][0]]
1716
1715
if (current_old[1][0][3] != current_new[1].executable or
1717
kind != current_new[1].kind):
1718
self.update_minimal(current_old[0], current_new[1].kind,
1719
num_present_parents,
1716
current_old[1][0][0] != current_new_minikind):
1717
self.update_minimal(current_old[0], current_new_minikind,
1720
1718
executable=current_new[1].executable,
1721
1719
id_index=id_index, path_utf8=new_path_utf8)
1722
1720
# both sides are dealt with, move on
1725
1723
elif new_entry_key < current_old[0]:
1726
1724
# new comes before:
1727
1725
# add a entry for this and advance new
1728
self.update_minimal(new_entry_key, current_new[1].kind,
1729
num_present_parents, executable=current_new[1].executable,
1726
self.update_minimal(new_entry_key, current_new_minikind,
1727
executable=current_new[1].executable,
1730
1728
id_index=id_index, path_utf8=new_path_utf8)
1731
1729
current_new = advance(new_iterator)
1785
1783
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
1786
1784
return last_reference
1788
def update_minimal(self, key, kind, num_present_parents, executable=False,
1789
fingerprint='', packed_stat=None, size=0, id_index=None,
1791
"""Update an entry to the state in tree 0."""
1786
def update_minimal(self, key, minikind, executable=False, fingerprint='',
1787
packed_stat=None, size=0, id_index=None, path_utf8=None):
1788
"""Update an entry to the state in tree 0.
1790
This will either create a new entry at 'key' or update an existing one.
1791
It also makes sure that any other records which might mention this are
1794
:param key: (dir, name, file_id) for the new entry
1795
:param minikind: The type for the entry ('f' == 'file', 'd' ==
1797
:param executable: Should the executable bit be set?
1798
:param fingerprint: Simple fingerprint for new entry.
1799
:param packed_stat: packed stat value for new entry.
1800
:param size: Size information for new entry
1801
:param id_index: A mapping from file_id => key, as returned by
1803
:param path_utf8: key[0] + '/' + key[1], just passed in to avoid doing
1792
1806
block = self._find_block(key)[1]
1793
1807
if packed_stat is None:
1794
1808
packed_stat = DirState.NULLSTAT
1795
1809
entry_index, present = self._find_entry_index(key, block)
1796
minikind = DirState._kind_to_minikind[kind]
1797
1810
new_details = (minikind, fingerprint, size, executable, packed_stat)
1798
1811
assert id_index is not None, 'need an id index to do updates for now !'
1799
1812
if not present:
1821
1834
self._dirblocks[other_block_index][1][other_entry_index][1][0] = \
1822
1835
('r', path_utf8, 0, False, '')
1837
num_present_parents = self._num_present_parents()
1824
1838
for lookup_index in xrange(1, num_present_parents + 1):
1825
1839
# grab any one entry, use it to find the right path.
1826
1840
# TODO: optimise this to reduce memory use in highly