14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from __future__ import absolute_import
17
19
# TODO: Some kind of command-line display of revision properties:
18
20
# perhaps show them in log -v and allow them as options to the commit command.
21
from .lazy_import import lazy_import
23
from bzrlib.lazy_import import lazy_import
22
24
lazy_import(globals(), """
23
from breezy import bugtracker
25
from bzrlib import bugtracker
31
from bzrlib.osutils import contains_whitespace
30
NULL_REVISION = b"null:"
31
CURRENT_REVISION = b"current:"
34
CURRENT_REVISION="current:"
34
37
class Revision(object):
69
72
if not isinstance(other, Revision):
72
self.inventory_sha1 == other.inventory_sha1
73
and self.revision_id == other.revision_id
74
and self.timestamp == other.timestamp
75
and self.message == other.message
76
and self.timezone == other.timezone
77
and self.committer == other.committer
78
and self.properties == other.properties
79
and self.parent_ids == other.parent_ids)
75
self.inventory_sha1 == other.inventory_sha1
76
and self.revision_id == other.revision_id
77
and self.timestamp == other.timestamp
78
and self.message == other.message
79
and self.timezone == other.timezone
80
and self.committer == other.committer
81
and self.properties == other.properties
82
and self.parent_ids == other.parent_ids)
81
84
def __ne__(self, other):
82
85
return not self.__eq__(other)
84
87
def _check_properties(self):
85
88
"""Verify that all revision properties are OK."""
86
for name, value in self.properties.items():
87
# GZ 2017-06-10: What sort of string are properties exactly?
88
not_text = not isinstance(name, str)
89
if not_text or osutils.contains_whitespace(name):
89
for name, value in self.properties.iteritems():
90
if not isinstance(name, basestring) or contains_whitespace(name):
90
91
raise ValueError("invalid property name %r" % name)
91
if not isinstance(value, (str, bytes)):
92
if not isinstance(value, basestring):
92
93
raise ValueError("invalid property value %r for %r" %
102
103
reversed_result = []
103
104
while current_revision is not None:
104
105
reversed_result.append(current_revision.revision_id)
105
if not len(current_revision.parent_ids):
106
if not len (current_revision.parent_ids):
106
107
reversed_result.append(None)
107
108
current_revision = None
142
143
"""Iterate over the bugs associated with this revision."""
143
144
bug_property = self.properties.get('bugs', None)
144
145
if bug_property is None:
146
return bugtracker.decode_bug_urls(bug_property)
147
for line in bug_property.splitlines():
149
url, status = line.split(None, 2)
151
raise errors.InvalidLineInBugsProperty(line)
152
if status not in bugtracker.ALLOWED_BUG_STATUSES:
153
raise errors.InvalidBugStatus(status)
149
157
def iter_ancestors(revision_id, revision_source, only_present=False):
156
164
yield ancestor, distance
158
166
revision = revision_source.get_revision(ancestor)
159
except errors.NoSuchRevision as e:
167
except errors.NoSuchRevision, e:
160
168
if e.revision == revision_id:
178
186
found_ancestors = {}
179
187
anc_iter = enumerate(iter_ancestors(revision_id, revision_source,
181
189
for anc_order, (anc_id, anc_distance) in anc_iter:
182
190
if anc_id not in found_ancestors:
183
191
found_ancestors[anc_id] = (anc_order, anc_distance)
199
207
:return: True if the revision is reserved, False otherwise
201
return isinstance(revision_id, bytes) and revision_id.endswith(b':')
209
return isinstance(revision_id, basestring) and revision_id.endswith(':')
204
212
def check_not_reserved_id(revision_id):
210
218
def ensure_null(revision_id):
211
219
"""Ensure only NULL_REVISION is used to represent the null revision"""
212
220
if revision_id is None:
214
'NULL_REVISION should be used for the null'
215
' revision instead of None.')
221
symbol_versioning.warn('NULL_REVISION should be used for the null'
222
' revision instead of None, as of bzr 0.91.',
223
DeprecationWarning, stacklevel=2)
219
229
def is_null(revision_id):
220
230
if revision_id is None:
221
raise ValueError('NULL_REVISION should be used for the null'
222
' revision instead of None.')
223
return (revision_id == NULL_REVISION)
231
symbol_versioning.warn('NULL_REVISION should be used for the null'
232
' revision instead of None, as of bzr 0.90.',
233
DeprecationWarning, stacklevel=2)
234
return revision_id in (None, NULL_REVISION)