~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/revision.py

  • Committer: Martin Pool
  • Date: 2005-05-17 06:56:16 UTC
  • Revision ID: mbp@sourcefrog.net-20050517065616-6f23381d6184a8aa
- add space for un-merged patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
 
19
19
 
20
 
class RevisionReference(object):
21
 
    """
22
 
    Reference to a stored revision.
23
 
 
24
 
    Includes the revision_id and revision_sha1.
25
 
    """
26
 
    revision_id = None
27
 
    revision_sha1 = None
28
 
    def __init__(self, revision_id, revision_sha1):
29
 
        if revision_id == None \
30
 
           or isinstance(revision_id, basestring):
31
 
            self.revision_id = revision_id
32
 
        else:
33
 
            raise ValueError('bad revision_id %r' % revision_id)
34
 
 
35
 
        if revision_sha1 != None:
36
 
            if isinstance(revision_sha1, basestring) \
37
 
               and len(revision_sha1) == 40:
38
 
                self.revision_sha1 = revision_sha1
39
 
            else:
40
 
                raise ValueError('bad revision_sha1 %r' % revision_sha1)
41
 
                
42
 
 
43
 
 
44
 
class Revision(object):
 
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 Revision(XMLMixin):
45
31
    """Single revision on a branch.
46
32
 
47
33
    Revisions may know their revision_hash, but only once they've been
48
34
    written out.  This is not stored because you cannot write the hash
49
35
    into the file it describes.
50
36
 
51
 
    After bzr 0.0.5 revisions are allowed to have multiple parents.
52
 
    To support old clients this is written out in a slightly redundant
53
 
    form: the first parent as the predecessor.  This will eventually
54
 
    be dropped.
55
 
 
56
 
    parents
57
 
        List of parent revisions, each is a RevisionReference.
 
37
    TODO: Perhaps make predecessor be a child element, not an attribute?
58
38
    """
59
 
    inventory_id = None
60
 
    inventory_sha1 = None
61
 
    revision_id = None
62
 
    timestamp = None
63
 
    message = None
64
 
    timezone = None
65
 
    committer = None
66
 
    
67
39
    def __init__(self, **args):
 
40
        self.inventory_id = None
 
41
        self.revision_id = None
 
42
        self.timestamp = None
 
43
        self.message = None
 
44
        self.timezone = None
 
45
        self.committer = None
 
46
        self.precursor = None
68
47
        self.__dict__.update(args)
69
 
        self.parents = []
70
 
 
71
 
    def _get_precursor(self):
72
 
        from warnings import warn
73
 
        warn("Revision.precursor is deprecated", stacklevel=2)
74
 
        if self.parents:
75
 
            return self.parents[0].revision_id
76
 
        else:
77
 
            return None
78
 
 
79
 
 
80
 
    def _get_precursor_sha1(self):
81
 
        from warnings import warn
82
 
        warn("Revision.precursor_sha1 is deprecated", stacklevel=2)
83
 
        if self.parents:
84
 
            return self.parents[0].revision_sha1
85
 
        else:
86
 
            return None    
87
 
 
88
 
 
89
 
    def _fail(self):
90
 
        raise Exception("can't assign to precursor anymore")
91
 
 
92
 
 
93
 
    precursor = property(_get_precursor, _fail, _fail)
94
 
    precursor_sha1 = property(_get_precursor_sha1, _fail, _fail)
95
 
 
96
48
 
97
49
 
98
50
    def __repr__(self):
100
52
 
101
53
        
102
54
    def to_element(self):
103
 
        from bzrlib.xml import Element, SubElement
104
 
        
105
55
        root = Element('revision',
106
56
                       committer = self.committer,
107
57
                       timestamp = '%.9f' % self.timestamp,
108
58
                       revision_id = self.revision_id,
109
59
                       inventory_id = self.inventory_id,
110
 
                       inventory_sha1 = self.inventory_sha1,
111
 
                       )
112
 
        if self.timezone:
113
 
            root.set('timezone', str(self.timezone))
 
60
                       timezone = str(self.timezone))
 
61
        if self.precursor:
 
62
            root.set('precursor', self.precursor)
114
63
        root.text = '\n'
115
64
        
116
65
        msg = SubElement(root, 'message')
117
66
        msg.text = self.message
118
67
        msg.tail = '\n'
119
68
 
120
 
        if self.parents:
121
 
            # first parent stored as precursor for compatability with 0.0.5 and
122
 
            # earlier
123
 
            pr = self.parents[0]
124
 
            assert pr.revision_id
125
 
            root.set('precursor', pr.revision_id)
126
 
            if pr.revision_sha1:
127
 
                root.set('precursor_sha1', pr.revision_sha1)
128
 
                
129
 
        if self.parents:
130
 
            pelts = SubElement(root, 'parents')
131
 
            pelts.tail = pelts.text = '\n'
132
 
            for rr in self.parents:
133
 
                assert isinstance(rr, RevisionReference)
134
 
                p = SubElement(pelts, 'revision_ref')
135
 
                p.tail = '\n'
136
 
                assert rr.revision_id
137
 
                p.set('revision_id', rr.revision_id)
138
 
                if rr.revision_sha1:
139
 
                    p.set('revision_sha1', rr.revision_sha1)
140
 
 
141
69
        return root
142
70
 
143
71
 
144
72
    def from_element(cls, elt):
145
 
        return unpack_revision(elt)
 
73
        # <changeset> is deprecated...
 
74
        if elt.tag not in ('revision', 'changeset'):
 
75
            raise BzrError("unexpected tag in revision file: %r" % elt)
 
76
 
 
77
        cs = cls(committer = elt.get('committer'),
 
78
                 timestamp = float(elt.get('timestamp')),
 
79
                 precursor = elt.get('precursor'),
 
80
                 revision_id = elt.get('revision_id'),
 
81
                 inventory_id = elt.get('inventory_id'))
 
82
 
 
83
        v = elt.get('timezone')
 
84
        cs.timezone = v and int(v)
 
85
 
 
86
        cs.message = elt.findtext('message') # text of <message>
 
87
        return cs
146
88
 
147
89
    from_element = classmethod(from_element)
148
90
 
149
 
 
150
 
 
151
 
def unpack_revision(elt):
152
 
    """Convert XML element into Revision object."""
153
 
    # <changeset> is deprecated...
154
 
    from bzrlib.errors import BzrError
155
 
    
156
 
    if elt.tag not in ('revision', 'changeset'):
157
 
        raise BzrError("unexpected tag in revision file: %r" % elt)
158
 
 
159
 
    rev = Revision(committer = elt.get('committer'),
160
 
                   timestamp = float(elt.get('timestamp')),
161
 
                   revision_id = elt.get('revision_id'),
162
 
                   inventory_id = elt.get('inventory_id'),
163
 
                   inventory_sha1 = elt.get('inventory_sha1')
164
 
                   )
165
 
 
166
 
    precursor = elt.get('precursor')
167
 
    precursor_sha1 = elt.get('precursor_sha1')
168
 
 
169
 
    pelts = elt.find('parents')
170
 
 
171
 
    if precursor:
172
 
        # revisions written prior to 0.0.5 have a single precursor
173
 
        # give as an attribute
174
 
        rev_ref = RevisionReference(precursor, precursor_sha1)
175
 
        rev.parents.append(rev_ref)
176
 
    elif pelts:
177
 
        for p in pelts:
178
 
            assert p.tag == 'revision_ref', \
179
 
                   "bad parent node tag %r" % p.tag
180
 
            rev_ref = RevisionReference(p.get('revision_id'),
181
 
                                        p.get('revision_sha1'))
182
 
            rev.parents.append(rev_ref)
183
 
 
184
 
    v = elt.get('timezone')
185
 
    rev.timezone = v and int(v)
186
 
 
187
 
    rev.message = elt.findtext('message') # text of <message>
188
 
    return rev