1
# (C) 2005 Canonical Development Ltd
1
# Copyright (C) 2005, 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
28
# New bundles should try to use this header format
29
29
BUNDLE_HEADER = '# Bazaar revision bundle v'
30
BUNDLE_HEADER_RE = re.compile(r'^# Bazaar revision bundle v(?P<version>\d+[\w.]*)\n$')
31
CHANGESET_OLD_HEADER_RE = re.compile(r'^# Bazaar-NG changeset v(?P<version>\d+[\w.]*)\n$')
30
BUNDLE_HEADER_RE = re.compile(
31
r'^# Bazaar revision bundle v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
32
CHANGESET_OLD_HEADER_RE = re.compile(
33
r'^# Bazaar-NG changeset v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
37
39
def _get_filename(f):
38
if hasattr(f, 'name'):
40
return getattr(f, 'name', '<unknown>')
44
44
"""Read in a bundle from a filelike object.
46
46
:param f: A file-like object
51
51
m = BUNDLE_HEADER_RE.match(line)
53
if m.group('lineending') != '':
54
raise errors.UnsupportedEOLMarker()
53
55
version = m.group('version')
57
elif line.startswith(BUNDLE_HEADER):
58
raise errors.MalformedHeader(
59
'Extra characters after version number')
55
60
m = CHANGESET_OLD_HEADER_RE.match(line)
57
62
version = m.group('version')
58
raise errors.BundleNotSupported(version, 'old format bundles not supported')
63
raise errors.BundleNotSupported(version,
64
'old format bundles not supported')
60
66
if version is None:
61
raise errors.NoBundleFound(_get_filename(f))
67
raise errors.NotABundle('Did not find an opening header')
63
69
# Now we have a version, to figure out how to read the bundle
64
if not _serializers.has_key(version):
65
raise errors.BundleNotSupported(version, 'version not listed in known versions')
70
if version not in _serializers:
71
raise errors.BundleNotSupported(version,
72
'version not listed in known versions')
67
74
serializer = _serializers[version](version)
78
85
:param version: [optional] target serialization version
81
if not _serializers.has_key(version):
88
if version not in _serializers:
82
89
raise errors.BundleNotSupported(version, 'unknown bundle format')
84
91
serializer = _serializers[version](version)
85
return serializer.write(source, revision_ids, forced_bases, f)
88
def write_bundle(repository, revision_id, base_revision_id, out):
94
return serializer.write(source, revision_ids, forced_bases, f)
99
def write_bundle(repository, revision_id, base_revision_id, out, format=None):
101
repository.lock_read()
103
return _write_bundle(repository, revision_id, base_revision_id, out,
109
def _write_bundle(repository, revision_id, base_revision_id, out, format):
110
"""Write a bundle of revisions.
112
:param repository: Repository containing revisions to serialize.
113
:param revision_id: Head revision_id of the bundle.
114
:param base_revision_id: Revision assumed to be present in repositories
116
:param out: Output file.
90
118
if base_revision_id is NULL_REVISION:
91
119
base_revision_id = None
92
120
base_ancestry = set(repository.get_ancestry(base_revision_id))
93
121
revision_ids = [r for r in repository.get_ancestry(revision_id) if r
94
122
not in base_ancestry]
95
123
revision_ids = list(reversed(revision_ids))
96
write(repository, revision_ids, out,
124
write(repository, revision_ids, out, format,
97
125
forced_bases = {revision_id:base_revision_id})
98
126
return revision_ids
122
150
'Thu 2005-06-30 12:38:52.350850105 -0500'
123
151
>>> format_highres_date(1120153132.350850105, 7200)
124
152
'Thu 2005-06-30 19:38:52.350850105 +0200'
153
>>> format_highres_date(1152428738.867522, 19800)
154
'Sun 2006-07-09 12:35:38.867522001 +0530'
127
157
assert isinstance(t, float)
129
159
# This has to be formatted for "original" date, so that the
130
160
# revision XML entry will be reproduced faithfully.
133
163
tt = time.gmtime(t + offset)
153
183
(1120153132.3508501, 0)
154
184
>>> unpack_highres_date('Thu 2005-06-30 19:38:52.350850105 +0200')
155
185
(1120153132.3508501, 7200)
186
>>> unpack_highres_date('Sun 2006-07-09 12:35:38.867522001 +0530')
187
(1152428738.867522, 19800)
156
188
>>> from bzrlib.osutils import local_time_offset
157
189
>>> t = time.time()
158
190
>>> o = local_time_offset()
180
212
dot_loc = date.find('.')
181
213
if dot_loc == -1:
182
raise ValueError('Date string does not contain high-precision seconds: %r' % date)
215
'Date string does not contain high-precision seconds: %r' % date)
183
216
base_time = time.strptime(date[:dot_loc], "%a %Y-%m-%d %H:%M:%S")
184
217
fract_seconds, offset = date[dot_loc:].split()
185
218
fract_seconds = float(fract_seconds)
186
220
offset = int(offset)
187
offset = int(offset / 100) * 3600 + offset % 100
222
hours = int(offset / 100)
223
minutes = (offset % 100)
224
seconds_offset = (hours * 3600) + (minutes * 60)
189
226
# time.mktime returns localtime, but calendar.timegm returns UTC time
190
227
timestamp = calendar.timegm(base_time)
228
timestamp -= seconds_offset
192
229
# Add back in the fractional seconds
193
230
timestamp += fract_seconds
194
return (timestamp, offset)
231
return (timestamp, seconds_offset)
197
234
class BundleSerializer(object):
259
296
base64.encode(temp, to_file)
260
297
to_file.write('\n')
262
register_lazy('0.7', 'bzrlib.bundle.serializer.v07', 'BundleSerializerV07')
263
register_lazy(None, 'bzrlib.bundle.serializer.v07', 'BundleSerializerV07')
299
register_lazy('0.8', 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
300
register_lazy('0.9', 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
301
register_lazy(None, 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')