23
24
from cElementTree import Element, ElementTree, SubElement
24
25
except ImportError:
25
from elementtree.ElementTree import Element, ElementTree, SubElement
27
from errors import BzrError
30
class RevisionReference:
32
Reference to a stored revision.
34
Includes the revision_id and revision_sha1.
38
def __init__(self, revision_id, revision_sha1):
39
if revision_id == None \
40
or isinstance(revision_id, basestring):
41
self.revision_id = revision_id
43
raise ValueError('bad revision_id %r' % revision_id)
45
if revision_sha1 != None:
46
if isinstance(revision_sha1, basestring) \
47
and len(revision_sha1) == 40:
48
self.revision_sha1 = revision_sha1
50
raise ValueError('bad revision_sha1 %r' % revision_sha1)
26
from elementtree import Element, ElementTree, SubElement
54
29
class Revision(XMLMixin):
58
33
written out. This is not stored because you cannot write the hash
59
34
into the file it describes.
61
After bzr 0.0.5 revisions are allowed to have multiple parents.
62
To support old clients this is written out in a slightly redundant
63
form: the first parent as the predecessor. This will eventually
67
List of parent revisions, each is a RevisionReference.
36
:todo: Perhaps make predecessor be a child element, not an attribute?
77
38
def __init__(self, **args):
39
self.inventory_id = None
40
self.revision_id = None
78
44
self.__dict__.update(args)
81
def _get_precursor(self):
82
from warnings import warn
83
warn("Revision.precursor is deprecated", stacklevel=2)
85
return self.parents[0].revision_id
90
def _get_precursor_sha1(self):
91
from warnings import warn
92
warn("Revision.precursor_sha1 is deprecated", stacklevel=2)
94
return self.parents[0].revision_sha1
100
raise Exception("can't assign to precursor anymore")
103
precursor = property(_get_precursor, _fail, _fail)
104
precursor_sha1 = property(_get_precursor_sha1, _fail, _fail)
108
47
def __repr__(self):
109
return "<Revision id %s>" % self.revision_id
49
return "<Revision id %s>" % self.revision_id
112
52
def to_element(self):
113
root = Element('revision',
53
root = Element('changeset',
114
54
committer = self.committer,
115
55
timestamp = '%.9f' % self.timestamp,
116
56
revision_id = self.revision_id,
117
57
inventory_id = self.inventory_id,
118
inventory_sha1 = self.inventory_sha1,
121
root.set('timezone', str(self.timezone))
58
timezone = str(self.timezone))
60
root.set('precursor', self.precursor)
124
63
msg = SubElement(root, 'message')
125
64
msg.text = self.message
129
# first parent stored as precursor for compatability with 0.0.5 and
132
assert pr.revision_id
133
root.set('precursor', pr.revision_id)
135
root.set('precursor_sha1', pr.revision_sha1)
138
pelts = SubElement(root, 'parents')
139
pelts.tail = pelts.text = '\n'
140
for rr in self.parents:
141
assert isinstance(rr, RevisionReference)
142
p = SubElement(pelts, 'revision_ref')
144
assert rr.revision_id
145
p.set('revision_id', rr.revision_id)
147
p.set('revision_sha1', rr.revision_sha1)
152
def from_element(cls, elt):
153
return unpack_revision(elt)
69
def from_element(cls, root):
70
cs = cls(committer = root.get('committer'),
71
timestamp = float(root.get('timestamp')),
72
precursor = root.get('precursor'),
73
revision_id = root.get('revision_id'),
74
inventory_id = root.get('inventory_id'))
76
v = root.get('timezone')
77
cs.timezone = v and int(v)
79
cs.message = root.findtext('message') # text of <message>
155
82
from_element = classmethod(from_element)
159
def unpack_revision(elt):
160
"""Convert XML element into Revision object."""
161
# <changeset> is deprecated...
162
if elt.tag not in ('revision', 'changeset'):
163
raise BzrError("unexpected tag in revision file: %r" % elt)
165
rev = Revision(committer = elt.get('committer'),
166
timestamp = float(elt.get('timestamp')),
167
revision_id = elt.get('revision_id'),
168
inventory_id = elt.get('inventory_id'),
169
inventory_sha1 = elt.get('inventory_sha1')
172
precursor = elt.get('precursor')
173
precursor_sha1 = elt.get('precursor_sha1')
175
pelts = elt.find('parents')
178
# revisions written prior to 0.0.5 have a single precursor
179
# give as an attribute
180
rev_ref = RevisionReference(precursor, precursor_sha1)
181
rev.parents.append(rev_ref)
184
assert p.tag == 'revision_ref', \
185
"bad parent node tag %r" % p.tag
186
rev_ref = RevisionReference(p.get('revision_id'),
187
p.get('revision_sha1'))
188
rev.parents.append(rev_ref)
190
v = elt.get('timezone')
191
rev.timezone = v and int(v)
193
rev.message = elt.findtext('message') # text of <message>