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, '')
380
398
raise BzrError("file_id {%s} not in inventory" % file_id)
401
def get_file_kind(self, file_id):
402
return self._byid[file_id].kind
383
404
def get_child(self, parent_id, filename):
384
405
return self[parent_id].children.get(filename)
390
411
To add a file to a branch ready to be committed, use Branch.add,
391
412
which calls this."""
392
413
if entry.file_id in self._byid:
393
bailout("inventory already contains entry with id {%s}" % entry.file_id)
414
raise BzrError("inventory already contains entry with id {%s}" % entry.file_id)
396
417
parent = self._byid[entry.parent_id]
398
bailout("parent_id {%s} not in inventory" % entry.parent_id)
419
raise BzrError("parent_id {%s} not in inventory" % entry.parent_id)
400
421
if parent.children.has_key(entry.name):
401
bailout("%s is already versioned" %
422
raise BzrError("%s is already versioned" %
402
423
appendpath(self.id2path(parent.file_id), entry.name))
404
425
self._byid[entry.file_id] = entry
409
430
"""Add entry from a path.
411
432
The immediate parent must already be versioned"""
433
from bzrlib.errors import NotVersionedError
412
435
parts = bzrlib.osutils.splitpath(relpath)
413
436
if len(parts) == 0:
414
bailout("cannot re-add root of inventory")
437
raise BzrError("cannot re-add root of inventory")
416
439
if file_id == None:
417
440
file_id = bzrlib.branch.gen_file_id(relpath)
419
parent_id = self.path2id(parts[:-1])
420
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)
421
447
ie = InventoryEntry(file_id, parts[-1],
422
448
kind=kind, parent_id=parent_id)
423
449
return self.add(ie)
501
520
if not isinstance(other, Inventory):
502
521
return NotImplemented
504
if self.id_set() ^ other.id_set():
507
for file_id in self._byid:
508
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')
514
539
def get_idpath(self, file_id):
585
610
This does not move the working file."""
586
611
if not is_valid_name(new_name):
587
bailout("not an acceptable filename: %r" % new_name)
612
raise BzrError("not an acceptable filename: %r" % new_name)
589
614
new_parent = self._byid[new_parent_id]
590
615
if new_name in new_parent.children:
591
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)))
593
618
new_parent_idpath = self.get_idpath(new_parent_id)
594
619
if file_id in new_parent_idpath:
595
bailout("cannot move directory %r into a subdirectory of itself, %r"
620
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
596
621
% (self.id2path(file_id), self.id2path(new_parent_id)))
598
623
file_ie = self._byid[file_id]