/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/revision.py

More work on roundtrip push support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# (C) 2005 Canonical
2
 
 
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.
7
 
 
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.
12
 
 
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
16
 
 
17
 
 
18
 
 
19
 
 
20
 
from xml import XMLMixin
21
 
 
22
 
try:
23
 
    from cElementTree import Element, ElementTree, SubElement
24
 
except ImportError:
25
 
    from elementtree.ElementTree import Element, ElementTree, SubElement
26
 
 
27
 
from errors import BzrError
28
 
 
29
 
 
30
 
class RevisionReference:
31
 
    """
32
 
    Reference to a stored revision.
33
 
 
34
 
    Includes the revision_id and revision_sha1.
35
 
    """
36
 
    revision_id = None
37
 
    revision_sha1 = None
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
42
 
        else:
43
 
            raise ValueError('bad revision_id %r' % revision_id)
44
 
 
45
 
        if revision_sha1 != None:
46
 
            if isinstance(revision_sha1, basestring) \
47
 
               and len(revision_sha1) == 40:
48
 
                self.revision_sha1 = revision_sha1
49
 
            else:
50
 
                raise ValueError('bad revision_sha1 %r' % revision_sha1)
51
 
                
52
 
 
53
 
 
54
 
class Revision(XMLMixin):
55
 
    """Single revision on a branch.
56
 
 
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.
60
 
 
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
64
 
    be dropped.
65
 
 
66
 
    parents
67
 
        List of parent revisions, each is a RevisionReference.
68
 
    """
69
 
    inventory_id = None
70
 
    inventory_sha1 = None
71
 
    revision_id = None
72
 
    timestamp = None
73
 
    message = None
74
 
    timezone = None
75
 
    committer = None
76
 
    
77
 
    def __init__(self, **args):
78
 
        self.__dict__.update(args)
79
 
        self.parents = []
80
 
 
81
 
    def _get_precursor(self):
82
 
        from warnings import warn
83
 
        warn("Revision.precursor is deprecated", stacklevel=2)
84
 
        if self.parents:
85
 
            return self.parents[0].revision_id
86
 
        else:
87
 
            return None
88
 
 
89
 
 
90
 
    def _get_precursor_sha1(self):
91
 
        from warnings import warn
92
 
        warn("Revision.precursor_sha1 is deprecated", stacklevel=2)
93
 
        if self.parents:
94
 
            return self.parents[0].revision_sha1
95
 
        else:
96
 
            return None    
97
 
 
98
 
 
99
 
    def _fail(self):
100
 
        raise Exception("can't assign to precursor anymore")
101
 
 
102
 
 
103
 
    precursor = property(_get_precursor, _fail, _fail)
104
 
    precursor_sha1 = property(_get_precursor_sha1, _fail, _fail)
105
 
 
106
 
 
107
 
 
108
 
    def __repr__(self):
109
 
        return "<Revision id %s>" % self.revision_id
110
 
 
111
 
        
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,
119
 
                       )
120
 
        if self.timezone:
121
 
            root.set('timezone', str(self.timezone))
122
 
        root.text = '\n'
123
 
        
124
 
        msg = SubElement(root, 'message')
125
 
        msg.text = self.message
126
 
        msg.tail = '\n'
127
 
 
128
 
        if self.parents:
129
 
            # first parent stored as precursor for compatability with 0.0.5 and
130
 
            # earlier
131
 
            pr = self.parents[0]
132
 
            root.set('precursor', pr.revision_id)
133
 
            if pr.revision_sha1:
134
 
                root.set('precursor_sha1', pr.revision_sha1)
135
 
                
136
 
        if self.parents:
137
 
            pelts = SubElement(root, 'parents')
138
 
            pelts.tail = pelts.text = '\n'
139
 
            for rr in self.parents:
140
 
                assert isinstance(rr, RevisionReference)
141
 
                p = SubElement(pelts, 'revision_ref')
142
 
                p.tail = '\n'
143
 
                p.set('revision_id', rr.revision_id)
144
 
                if rr.revision_sha1:
145
 
                    p.set('revision_sha1', rr.revision_sha1)
146
 
 
147
 
        return root
148
 
 
149
 
 
150
 
    def from_element(cls, elt):
151
 
        return unpack_revision(elt)
152
 
 
153
 
    from_element = classmethod(from_element)
154
 
 
155
 
 
156
 
 
157
 
def unpack_revision(elt):
158
 
    """Convert XML element into Revision object."""
159
 
    # <changeset> is deprecated...
160
 
    if elt.tag not in ('revision', 'changeset'):
161
 
        raise BzrError("unexpected tag in revision file: %r" % elt)
162
 
 
163
 
    rev = Revision(committer = elt.get('committer'),
164
 
                   timestamp = float(elt.get('timestamp')),
165
 
                   revision_id = elt.get('revision_id'),
166
 
                   inventory_id = elt.get('inventory_id'),
167
 
                   inventory_sha1 = elt.get('inventory_sha1')
168
 
                   )
169
 
 
170
 
    precursor = elt.get('precursor')
171
 
    precursor_sha1 = elt.get('precursor_sha1')
172
 
 
173
 
    pelts = elt.find('parents')
174
 
 
175
 
    if precursor:
176
 
        # revisions written prior to 0.0.5 have a single precursor
177
 
        # give as an attribute
178
 
        rev_ref = RevisionReference(precursor, precursor_sha1)
179
 
        rev.parents.append(rev_ref)
180
 
    elif pelts:
181
 
        for p in pelts:
182
 
            assert p.tag == 'revision_ref', \
183
 
                   "bad parent node tag %r" % p.tag
184
 
            rev_ref = RevisionReference(p.get('revision_id'),
185
 
                                        p.get('revision_sha1'))
186
 
            rev.parents.append(rev_ref)
187
 
 
188
 
    v = elt.get('timezone')
189
 
    rev.timezone = v and int(v)
190
 
 
191
 
    rev.message = elt.findtext('message') # text of <message>
192
 
    return rev