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
414
432
The immediate parent must already be versioned"""
415
433
parts = bzrlib.osutils.splitpath(relpath)
416
434
if len(parts) == 0:
417
bailout("cannot re-add root of inventory")
435
raise BzrError("cannot re-add root of inventory")
419
437
if file_id == None:
420
438
file_id = bzrlib.branch.gen_file_id(relpath)
504
515
if not isinstance(other, Inventory):
505
516
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])
518
if len(self._byid) != len(other._byid):
519
# shortcut: obviously not the same
522
return self._byid == other._byid
525
def __ne__(self, other):
526
return not (self == other)
530
raise ValueError('not hashable')
517
534
def get_idpath(self, file_id):
588
605
This does not move the working file."""
589
606
if not is_valid_name(new_name):
590
bailout("not an acceptable filename: %r" % new_name)
607
raise BzrError("not an acceptable filename: %r" % new_name)
592
609
new_parent = self._byid[new_parent_id]
593
610
if new_name in new_parent.children:
594
bailout("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
611
raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
596
613
new_parent_idpath = self.get_idpath(new_parent_id)
597
614
if file_id in new_parent_idpath:
598
bailout("cannot move directory %r into a subdirectory of itself, %r"
615
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
599
616
% (self.id2path(file_id), self.id2path(new_parent_id)))
601
618
file_ie = self._byid[file_id]