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