23
23
import sys, os.path, types, re
26
27
from cElementTree import Element, ElementTree, SubElement
27
28
except ImportError:
28
29
from elementtree.ElementTree import Element, ElementTree, SubElement
30
from bzrlib.xml import XMLMixin
31
from bzrlib.errors import BzrError, BzrCheckError
31
from xml import XMLMixin
32
from errors import bailout, BzrError, BzrCheckError
34
35
from bzrlib.osutils import uuid, quotefn, splitpath, joinpath, appendpath
68
69
>>> i.add(InventoryEntry('2323', 'bye.c', 'file', '123'))
69
70
Traceback (most recent call last):
71
BzrError: inventory already contains entry with id {2323}
72
BzrError: ('inventory already contains entry with id {2323}', [])
72
73
>>> i.add(InventoryEntry('2324', 'bye.c', 'file', '123'))
73
74
>>> i.add(InventoryEntry('2325', 'wibble', 'directory', '123'))
74
75
>>> i.path2id('src/wibble')
144
145
self.parent_id, text_id=self.text_id)
145
146
other.text_sha1 = self.text_sha1
146
147
other.text_size = self.text_size
147
# note that children are *not* copied; they're pulled across when
211
210
from_element = classmethod(from_element)
213
def __eq__(self, other):
212
def __cmp__(self, other):
214
215
if not isinstance(other, InventoryEntry):
215
216
return NotImplemented
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')
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)
239
233
self.parent_id = None
242
def __eq__(self, other):
236
def __cmp__(self, other):
243
239
if not isinstance(other, RootEntry):
244
240
return NotImplemented
246
return (self.file_id == other.file_id) \
247
and (self.children == other.children)
241
return cmp(self.file_id, other.file_id) \
242
or cmp(self.children, other.children)
329
324
if ie.kind == 'directory':
330
325
for cn, cie in self.iter_entries(from_dir=ie.file_id):
331
326
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.
330
def directories(self):
331
"""Return (path, entry) pairs for all directories.
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))
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():
346
340
if ie.kind == 'directory':
347
descend(ie, child_path)
349
descend(self.root, '')
353
def directories(self):
354
"""Return (path, entry) pairs for all directories, including the root.
357
def descend(parent_ie, parent_path):
358
accum.append((parent_path, parent_ie))
341
dn.append((ie.name, ie))
360
kids = [(ie.name, ie) for ie in parent_ie.children.itervalues() if ie.kind == 'directory']
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
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, '')
348
for name, ie in descend(self.root):
411
393
To add a file to a branch ready to be committed, use Branch.add,
412
394
which calls this."""
413
395
if entry.file_id in self._byid:
414
raise BzrError("inventory already contains entry with id {%s}" % entry.file_id)
396
bailout("inventory already contains entry with id {%s}" % entry.file_id)
417
399
parent = self._byid[entry.parent_id]
419
raise BzrError("parent_id {%s} not in inventory" % entry.parent_id)
401
bailout("parent_id {%s} not in inventory" % entry.parent_id)
421
403
if parent.children.has_key(entry.name):
422
raise BzrError("%s is already versioned" %
404
bailout("%s is already versioned" %
423
405
appendpath(self.id2path(parent.file_id), entry.name))
425
407
self._byid[entry.file_id] = entry
432
414
The immediate parent must already be versioned"""
433
415
parts = bzrlib.osutils.splitpath(relpath)
434
416
if len(parts) == 0:
435
raise BzrError("cannot re-add root of inventory")
417
bailout("cannot re-add root of inventory")
437
419
if file_id == None:
438
420
file_id = bzrlib.branch.gen_file_id(relpath)
515
504
if not isinstance(other, Inventory):
516
505
return NotImplemented
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')
507
if self.id_set() ^ other.id_set():
510
for file_id in self._byid:
511
c = cmp(self[file_id], other[file_id])
534
517
def get_idpath(self, file_id):
605
588
This does not move the working file."""
606
589
if not is_valid_name(new_name):
607
raise BzrError("not an acceptable filename: %r" % new_name)
590
bailout("not an acceptable filename: %r" % new_name)
609
592
new_parent = self._byid[new_parent_id]
610
593
if new_name in new_parent.children:
611
raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
594
bailout("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
613
596
new_parent_idpath = self.get_idpath(new_parent_id)
614
597
if file_id in new_parent_idpath:
615
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
598
bailout("cannot move directory %r into a subdirectory of itself, %r"
616
599
% (self.id2path(file_id), self.id2path(new_parent_id)))
618
601
file_ie = self._byid[file_id]