3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
from xml import XMLMixin
23
from cElementTree import Element, ElementTree, SubElement
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)
54
class Revision(XMLMixin):
55
"""Single revision on a branch.
57
Revisions may know their revision_hash, but only once they've been
58
written out. This is not stored because you cannot write the hash
59
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.
77
def __init__(self, **args):
78
self.__dict__.update(args)
81
def _get_precursor(self):
82
##from warnings import warn
83
##warn("Revision.precursor is deprecated")
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")
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)
109
return "<Revision id %s>" % self.revision_id
112
def to_element(self):
113
root = Element('revision',
114
committer = self.committer,
115
timestamp = '%.9f' % self.timestamp,
116
revision_id = self.revision_id,
117
inventory_id = self.inventory_id,
118
inventory_sha1 = self.inventory_sha1,
121
root.set('timezone', str(self.timezone))
123
root.set('precursor', self.precursor)
124
if self.precursor_sha1:
125
root.set('precursor_sha1', self.precursor_sha1)
128
msg = SubElement(root, 'message')
129
msg.text = self.message
133
pelts = SubElement(root, 'parents')
134
for rr in self.parents:
135
assert isinstance(rr, RevisionReference)
136
p = SubElement(pelts, 'revision_ref')
137
p.set('revision_id', rr.revision_id)
139
p.set('revision_sha1', rr.revision_sha1)
144
def from_element(cls, elt):
145
return unpack_revision(elt)
147
from_element = classmethod(from_element)
151
def unpack_revision(elt):
152
"""Convert XML element into Revision object."""
153
# <changeset> is deprecated...
154
if elt.tag not in ('revision', 'changeset'):
155
raise BzrError("unexpected tag in revision file: %r" % elt)
157
rev = Revision(committer = elt.get('committer'),
158
timestamp = float(elt.get('timestamp')),
159
revision_id = elt.get('revision_id'),
160
inventory_id = elt.get('inventory_id'),
161
inventory_sha1 = elt.get('inventory_sha1')
164
precursor = elt.get('precursor')
165
precursor_sha1 = elt.get('precursor_sha1')
167
pelts = elt.find('parents')
170
# revisions written prior to 0.0.5 have a single precursor
171
# give as an attribute
172
rev_ref = RevisionReference(precursor, precursor_sha1)
173
rev.parents.append(rev_ref)
176
assert p.tag == 'revision_ref', \
177
"bad parent node tag %r" % p.tag
178
rev_ref = RevisionReference(p.get('revision_id'),
179
p.get('revision_sha1'))
180
rev.parents.append(rev_ref)
182
v = elt.get('timezone')
183
rev.timezone = v and int(v)
185
rev.message = elt.findtext('message') # text of <message>