1
# Copyright (C) 2005, 2006 Canonical Ltd
1
# Copyright (C) 2005, 2006 by 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
22
22
from bzrlib import errors
23
23
from bzrlib.bundle.serializer import (BundleSerializer,
26
28
from bzrlib.bundle.serializer import binary_diff
27
29
from bzrlib.bundle.bundle_data import (RevisionInfo, BundleInfo, BundleTree)
29
31
from bzrlib.osutils import pathjoin
30
32
from bzrlib.progress import DummyProgress
31
33
from bzrlib.revision import NULL_REVISION
34
from bzrlib.rio import RioWriter, read_stanzas
33
36
from bzrlib.testament import StrictTestament
34
from bzrlib.timestamp import (
38
37
from bzrlib.textfile import text_file
39
38
from bzrlib.trace import mutter
56
55
self.properties = properties
58
def add_utf8_property(self, name, value):
59
"""Add a property whose value is currently utf8 to the action."""
60
self.properties.append((name, value.decode('utf8')))
62
57
def add_property(self, name, value):
63
58
"""Add a property to the action"""
64
59
self.properties.append((name, value))
102
97
def check_compatible(self):
103
98
if self.source.supports_rich_root():
104
raise errors.IncompatibleBundleFormat('0.8', repr(self.source))
99
raise errors.IncompatibleFormat('0.8', repr(self.source))
106
101
def write(self, source, revision_ids, forced_bases, f):
107
102
"""Write the bundless to the supplied files.
131
def write_bundle(self, repository, target, base, fileobj):
132
return self._write_bundle(repository, target, base, fileobj)
134
126
def _write_main_header(self):
135
127
"""Write the header for the changes"""
137
f.write(_get_bundle_header('0.8'))
129
f.write(BUNDLE_HEADER)
140
def _write(self, key, value, indent=1, trailing_space_when_empty=False):
141
"""Write out meta information, with proper indenting, etc.
143
:param trailing_space_when_empty: To work around a bug in earlier
144
bundle readers, when writing an empty property, we use "prop: \n"
145
rather than writing "prop:\n".
146
If this parameter is True, and value is the empty string, we will
147
write an extra space.
133
def _write(self, key, value, indent=1):
134
"""Write out meta information, with proper indenting, etc"""
149
135
assert indent > 0, 'indentation must be greater than 0'
151
137
f.write('#' + (' ' * indent))
152
138
f.write(key.encode('utf-8'))
154
if trailing_space_when_empty and value == '':
158
elif isinstance(value, str):
162
elif isinstance(value, unicode):
141
elif isinstance(value, basestring):
164
143
f.write(value.encode('utf-8'))
168
147
for entry in value:
169
148
f.write('#' + (' ' * (indent+2)))
170
if isinstance(entry, str):
173
f.write(entry.encode('utf-8'))
149
f.write(entry.encode('utf-8'))
176
152
def _write_revisions(self, pb):
180
156
last_rev_id = None
181
157
last_rev_tree = None
183
i_max = len(self.revision_ids)
159
i_max = len(self.revision_ids)
184
160
for i, rev_id in enumerate(self.revision_ids):
185
161
pb.update("Generating revsion data", i, i_max)
186
162
rev = self.source.get_revision(rev_id)
237
213
w('base id', base_rev)
238
214
if rev.properties:
239
215
self._write('properties', None, indent=1)
240
for name, value in sorted(rev.properties.items()):
241
self._write(name, value, indent=3,
242
trailing_space_when_empty=True)
216
for name, value in rev.properties.items():
217
self._write(name, value, indent=3)
244
219
# Add an extra blank space at the end
245
220
self.to_file.write('\n')
290
265
old_path, new_path):
291
266
entry = new_tree.inventory[file_id]
292
267
if entry.revision != default_revision_id:
293
action.add_utf8_property('last-changed', entry.revision)
268
action.add_property('last-changed', entry.revision)
294
269
if meta_modified:
295
270
action.add_bool_property('executable', entry.executable)
296
271
if text_modified and kind == "symlink":
333
308
if new_rev != old_rev:
334
309
action = Action('modified', [ie.kind,
335
310
new_tree.id2path(ie.file_id)])
336
action.add_utf8_property('last-changed', ie.revision)
311
action.add_property('last-changed', ie.revision)
337
312
action.write(self.to_file)
450
425
revision_info = self.info.revisions[-1]
451
426
if key in revision_info.__dict__:
452
427
if getattr(revision_info, key) is None:
453
if key in ('file_id', 'revision_id', 'base_id'):
454
value = value.encode('utf8')
455
elif key in ('parent_ids'):
456
value = [v.encode('utf8') for v in value]
457
428
setattr(revision_info, key, value)
459
430
raise errors.MalformedHeader('Duplicated Key: %s' % key)