23
23
import sys, os.path, types, re
27
26
from cElementTree import Element, ElementTree, SubElement
28
27
except ImportError:
29
28
from elementtree.ElementTree import Element, ElementTree, SubElement
31
from xml import XMLMixin
32
from errors import bailout, BzrError, BzrCheckError
30
from bzrlib.xml import XMLMixin
31
from bzrlib.errors import BzrError, BzrCheckError
35
34
from bzrlib.osutils import uuid, quotefn, splitpath, joinpath, appendpath
69
68
>>> i.add(InventoryEntry('2323', 'bye.c', 'file', '123'))
70
69
Traceback (most recent call last):
72
BzrError: ('inventory already contains entry with id {2323}', [])
71
BzrError: inventory already contains entry with id {2323}
73
72
>>> i.add(InventoryEntry('2324', 'bye.c', 'file', '123'))
74
73
>>> i.add(InventoryEntry('2325', 'wibble', 'directory', '123'))
75
74
>>> i.path2id('src/wibble')
145
144
self.parent_id, text_id=self.text_id)
146
145
other.text_sha1 = self.text_sha1
147
146
other.text_size = self.text_size
147
# note that children are *not* copied; they're pulled across when
210
211
from_element = classmethod(from_element)
212
def __cmp__(self, other):
213
def __eq__(self, other):
215
214
if not isinstance(other, InventoryEntry):
216
215
return NotImplemented
218
return cmp(self.file_id, other.file_id) \
219
or cmp(self.name, other.name) \
220
or cmp(self.text_sha1, other.text_sha1) \
221
or cmp(self.text_size, other.text_size) \
222
or cmp(self.text_id, other.text_id) \
223
or cmp(self.parent_id, other.parent_id) \
224
or cmp(self.kind, other.kind)
217
return (self.file_id == other.file_id) \
218
and (self.name == other.name) \
219
and (self.text_sha1 == other.text_sha1) \
220
and (self.text_size == other.text_size) \
221
and (self.text_id == other.text_id) \
222
and (self.parent_id == other.parent_id) \
223
and (self.kind == other.kind)
226
def __ne__(self, other):
227
return not (self == other)
230
raise ValueError('not hashable')
233
239
self.parent_id = None
236
def __cmp__(self, other):
242
def __eq__(self, other):
239
243
if not isinstance(other, RootEntry):
240
244
return NotImplemented
241
return cmp(self.file_id, other.file_id) \
242
or cmp(self.children, other.children)
246
return (self.file_id == other.file_id) \
247
and (self.children == other.children)
324
329
if ie.kind == 'directory':
325
330
for cn, cie in self.iter_entries(from_dir=ie.file_id):
326
331
yield os.path.join(name, cn), cie
335
"""Return list of (path, ie) for all entries except the root.
337
This may be faster than iter_entries.
340
def descend(dir_ie, dir_path):
341
kids = dir_ie.children.items()
343
for name, ie in kids:
344
child_path = os.path.join(dir_path, name)
345
accum.append((child_path, ie))
346
if ie.kind == 'directory':
347
descend(ie, child_path)
349
descend(self.root, '')
330
353
def directories(self):
331
"""Return (path, entry) pairs for all directories.
354
"""Return (path, entry) pairs for all directories, including the root.
333
def descend(parent_ie):
334
parent_name = parent_ie.name
335
yield parent_name, parent_ie
337
# directory children in sorted order
339
for ie in parent_ie.children.itervalues():
340
if ie.kind == 'directory':
341
dn.append((ie.name, ie))
357
def descend(parent_ie, parent_path):
358
accum.append((parent_path, parent_ie))
344
for name, child_ie in dn:
345
for sub_name, sub_ie in descend(child_ie):
346
yield appendpath(parent_name, sub_name), sub_ie
360
kids = [(ie.name, ie) for ie in parent_ie.children.itervalues() if ie.kind == 'directory']
348
for name, ie in descend(self.root):
363
for name, child_ie in kids:
364
child_path = os.path.join(parent_path, name)
365
descend(child_ie, child_path)
366
descend(self.root, '')
393
411
To add a file to a branch ready to be committed, use Branch.add,
394
412
which calls this."""
395
413
if entry.file_id in self._byid:
396
bailout("inventory already contains entry with id {%s}" % entry.file_id)
414
raise BzrError("inventory already contains entry with id {%s}" % entry.file_id)
399
417
parent = self._byid[entry.parent_id]
401
bailout("parent_id {%s} not in inventory" % entry.parent_id)
419
raise BzrError("parent_id {%s} not in inventory" % entry.parent_id)
403
421
if parent.children.has_key(entry.name):
404
bailout("%s is already versioned" %
422
raise BzrError("%s is already versioned" %
405
423
appendpath(self.id2path(parent.file_id), entry.name))
407
425
self._byid[entry.file_id] = entry
412
430
"""Add entry from a path.
414
432
The immediate parent must already be versioned"""
433
from bzrlib.errors import NotVersionedError
415
435
parts = bzrlib.osutils.splitpath(relpath)
416
436
if len(parts) == 0:
417
bailout("cannot re-add root of inventory")
437
raise BzrError("cannot re-add root of inventory")
419
439
if file_id == None:
420
440
file_id = bzrlib.branch.gen_file_id(relpath)
422
parent_id = self.path2id(parts[:-1])
423
assert parent_id != None
442
parent_path = parts[:-1]
443
parent_id = self.path2id(parent_path)
444
if parent_id == None:
445
raise NotVersionedError(parent_path)
424
447
ie = InventoryEntry(file_id, parts[-1],
425
448
kind=kind, parent_id=parent_id)
426
449
return self.add(ie)
504
520
if not isinstance(other, Inventory):
505
521
return NotImplemented
507
if self.id_set() ^ other.id_set():
510
for file_id in self._byid:
511
c = cmp(self[file_id], other[file_id])
523
if len(self._byid) != len(other._byid):
524
# shortcut: obviously not the same
527
return self._byid == other._byid
530
def __ne__(self, other):
531
return not (self == other)
535
raise ValueError('not hashable')
517
539
def get_idpath(self, file_id):
588
610
This does not move the working file."""
589
611
if not is_valid_name(new_name):
590
bailout("not an acceptable filename: %r" % new_name)
612
raise BzrError("not an acceptable filename: %r" % new_name)
592
614
new_parent = self._byid[new_parent_id]
593
615
if new_name in new_parent.children:
594
bailout("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
616
raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
596
618
new_parent_idpath = self.get_idpath(new_parent_id)
597
619
if file_id in new_parent_idpath:
598
bailout("cannot move directory %r into a subdirectory of itself, %r"
620
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
599
621
% (self.id2path(file_id), self.id2path(new_parent_id)))
601
623
file_ie = self._byid[file_id]