1169
def update_by_delta(self, delta):
1170
"""Apply an inventory delta to the dirstate for tree 0
1172
:param delta: An inventory delta. See Inventory.apply_delta for
1175
self._read_dirblocks_if_needed()
1178
for old_path, new_path, file_id, inv_entry in sorted(delta,
1180
assert file_id not in insertions
1181
assert file_id not in removals
1182
if old_path is not None:
1183
old_path = old_path.encode('utf-8')
1184
removals[file_id] = old_path
1185
if new_path is not None:
1186
new_path = new_path.encode('utf-8')
1187
dirname, basename = osutils.split(new_path)
1188
key = (dirname, basename, file_id)
1189
minikind = DirState._kind_to_minikind[inv_entry.kind]
1191
fingerprint = inv_entry.reference_revision
1194
insertions[file_id] = (key, minikind, inv_entry.executable,
1195
fingerprint, new_path)
1196
if None not in (old_path, new_path):
1197
for child in self._iter_child_entries(0, old_path):
1198
if child[0][2] in insertions or child[0][2] in removals:
1200
child_dirname = child[0][0]
1201
child_basename = child[0][1]
1202
minikind = child[1][0][0]
1203
fingerprint = child[1][0][4]
1204
executable = child[1][0][3]
1205
old_child_path = osutils.pathjoin(child[0][0],
1207
removals[child[0][2]] = old_child_path
1208
child_suffix = child_dirname[len(old_path):]
1209
new_child_dirname = (new_path + child_suffix)
1210
key = (new_child_dirname, child_basename, child[0][2])
1211
new_child_path = os.path.join(new_child_dirname,
1213
insertions[child[0][2]] = (key, minikind, executable,
1214
fingerprint, new_child_path)
1215
self._apply_removals(removals.values())
1216
self._apply_insertions(insertions.values())
1218
def _apply_removals(self, removals):
1219
for path in sorted(removals, reverse=True):
1220
dirname, basename = osutils.split(path)
1221
block_i, entry_i, d_present, f_present = \
1222
self._get_block_entry_index(dirname, basename, 0)
1223
entry = self._dirblocks[block_i][1][entry_i]
1224
self._make_absent(entry)
1226
def _apply_insertions(self, adds):
1227
for key, minikind, executable, fingerprint, path_utf8 in sorted(adds):
1228
self.update_minimal(key, minikind, executable, fingerprint,
1229
path_utf8=path_utf8)
1231
1166
def update_basis_by_delta(self, delta, new_revid):
1232
1167
"""Update the parents of this tree after a commit.
1312
1247
source_path = entry[0][0] + '/' + entry[0][1]
1314
1249
source_path = entry[0][1]
1316
target_path = new_path_utf8 + source_path[len(old_path):]
1318
assert len(old_path) > 0, ("cannot rename directory to"
1320
target_path = source_path[len(old_path) + 1:]
1250
target_path = new_path_utf8 + source_path[len(old_path):]
1321
1251
adds.append((None, target_path, entry[0][2], entry[1][1], False))
1322
1252
deletes.append(
1323
1253
(source_path, target_path, entry[0][2], None, False))
1362
1292
assert old_path is None
1363
1293
# the entry for this file_id must be in tree 0.
1364
1294
entry = self._get_entry(0, file_id, new_path)
1365
if entry[0] is None or entry[0][2] != file_id:
1366
self._changes_aborted = True
1367
raise errors.InconsistentDelta(new_path, file_id,
1368
'working tree does not contain new entry')
1295
if entry[0][2] != file_id:
1296
raise errors.BzrError('dirstate: cannot apply delta, working'
1297
' tree does not contain new entry %r %r' %
1298
(new_path, file_id))
1369
1299
if real_add and entry[1][1][0] not in absent:
1370
self._changes_aborted = True
1371
raise errors.InconsistentDelta(new_path, file_id,
1372
'The entry was considered to be a genuinely new record,'
1373
' but there was already an old record for it.')
1300
raise errors.BzrError('dirstate: inconsistent delta, with '
1301
'tree 0. %r %r' % (new_path, file_id))
1374
1302
# We don't need to update the target of an 'r' because the handling
1375
1303
# of renames turns all 'r' situations into a delete at the original
1387
1315
assert old_path == new_path
1388
1316
# the entry for this file_id must be in tree 0.
1389
1317
entry = self._get_entry(0, file_id, new_path)
1390
if entry[0] is None or entry[0][2] != file_id:
1391
self._changes_aborted = True
1392
raise errors.InconsistentDelta(new_path, file_id,
1393
'working tree does not contain new entry')
1318
if entry[0][2] != file_id:
1319
raise errors.BzrError('dirstate: cannot apply delta, working'
1320
' tree does not contain new entry %r %r' %
1321
(new_path, file_id))
1394
1322
if (entry[1][0][0] in absent or
1395
1323
entry[1][1][0] in absent):
1396
self._changes_aborted = True
1397
raise errors.InconsistentDelta(new_path, file_id,
1398
'changed considered absent')
1324
raise errors.BzrError('dirstate: inconsistent delta, with '
1325
'tree 0. %r %r' % (new_path, file_id))
1399
1326
entry[1][1] = new_details
1401
1328
def _update_basis_apply_deletes(self, deletes):
1421
1348
block_index, entry_index, dir_present, file_present = \
1422
1349
self._get_block_entry_index(dirname, basename, 1)
1423
1350
if not file_present:
1424
self._changes_aborted = True
1425
raise errors.InconsistentDelta(old_path, file_id,
1426
'basis tree does not contain removed entry')
1351
raise errors.BzrError('dirstate: cannot apply delta, basis'
1352
' tree does not contain new entry %r %r' %
1353
(old_path, file_id))
1427
1354
entry = self._dirblocks[block_index][1][entry_index]
1428
1355
if entry[0][2] != file_id:
1429
self._changes_aborted = True
1430
raise errors.InconsistentDelta(old_path, file_id,
1431
'mismatched file_id in tree 1')
1356
raise errors.BzrError('mismatched file_id in tree 1 %r %r' %
1357
(old_path, file_id))
1432
1358
if real_delete:
1433
1359
if entry[1][0][0] != 'a':
1434
self._changes_aborted = True
1435
raise errors.InconsistentDelta(old_path, file_id,
1436
'This was marked as a real delete, but the WT state'
1437
' claims that it still exists and is versioned.')
1360
raise errors.BzrError('dirstate: inconsistent delta, with '
1361
'tree 0. %r %r' % (old_path, file_id))
1438
1362
del self._dirblocks[block_index][1][entry_index]
1440
1364
if entry[1][0][0] == 'a':
1441
self._changes_aborted = True
1442
raise errors.InconsistentDelta(old_path, file_id,
1443
'The entry was considered a rename, but the source path'
1444
' is marked as absent.')
1445
# For whatever reason, we were asked to rename an entry
1446
# that was originally marked as deleted. This could be
1447
# because we are renaming the parent directory, and the WT
1448
# current state has the file marked as deleted.
1365
raise errors.BzrError('dirstate: inconsistent delta, with '
1366
'tree 0. %r %r' % (old_path, file_id))
1449
1367
elif entry[1][0][0] == 'r':
1450
1368
# implement the rename
1451
1369
del self._dirblocks[block_index][1][entry_index]
2037
1954
start over, to allow for fine grained read lock duration, so 'status'
2038
1955
wont block 'commit' - for example.
2040
if self._changes_aborted:
2041
# Should this be a warning? For now, I'm expecting that places that
2042
# mark it inconsistent will warn, making a warning here redundant.
2043
trace.mutter('Not saving DirState because '
2044
'_changes_aborted is set.')
2046
1957
if (self._header_state == DirState.IN_MEMORY_MODIFIED or
2047
1958
self._dirblock_state == DirState.IN_MEMORY_MODIFIED):