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))
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.
150
raise ValueError('indentation must be greater than 0')
133
def _write(self, key, value, indent=1):
134
"""Write out meta information, with proper indenting, etc"""
135
assert indent > 0, 'indentation must be greater than 0'
152
137
f.write('#' + (' ' * indent))
153
138
f.write(key.encode('utf-8'))
155
if trailing_space_when_empty and value == '':
159
elif isinstance(value, str):
163
elif isinstance(value, unicode):
141
elif isinstance(value, basestring):
165
143
f.write(value.encode('utf-8'))
169
147
for entry in value:
170
148
f.write('#' + (' ' * (indent+2)))
171
if isinstance(entry, str):
174
f.write(entry.encode('utf-8'))
149
f.write(entry.encode('utf-8'))
177
152
def _write_revisions(self, pb):
181
156
last_rev_id = None
182
157
last_rev_tree = None
184
i_max = len(self.revision_ids)
159
i_max = len(self.revision_ids)
185
160
for i, rev_id in enumerate(self.revision_ids):
186
161
pb.update("Generating revsion data", i, i_max)
187
162
rev = self.source.get_revision(rev_id)
238
213
w('base id', base_rev)
239
214
if rev.properties:
240
215
self._write('properties', None, indent=1)
241
for name, value in sorted(rev.properties.items()):
242
self._write(name, value, indent=3,
243
trailing_space_when_empty=True)
216
for name, value in rev.properties.items():
217
self._write(name, value, indent=3)
245
219
# Add an extra blank space at the end
246
220
self.to_file.write('\n')
291
265
old_path, new_path):
292
266
entry = new_tree.inventory[file_id]
293
267
if entry.revision != default_revision_id:
294
action.add_utf8_property('last-changed', entry.revision)
268
action.add_property('last-changed', entry.revision)
295
269
if meta_modified:
296
270
action.add_bool_property('executable', entry.executable)
297
271
if text_modified and kind == "symlink":
334
308
if new_rev != old_rev:
335
309
action = Action('modified', [ie.kind,
336
310
new_tree.id2path(ie.file_id)])
337
action.add_utf8_property('last-changed', ie.revision)
311
action.add_property('last-changed', ie.revision)
338
312
action.write(self.to_file)
451
425
revision_info = self.info.revisions[-1]
452
426
if key in revision_info.__dict__:
453
427
if getattr(revision_info, key) is None:
454
if key in ('file_id', 'revision_id', 'base_id'):
455
value = value.encode('utf8')
456
elif key in ('parent_ids'):
457
value = [v.encode('utf8') for v in value]
458
428
setattr(revision_info, key, value)
460
430
raise errors.MalformedHeader('Duplicated Key: %s' % key)
524
494
action, lines, do_continue = self._read_one_patch()
525
495
if action is not None:
526
496
revision_actions.append((action, lines))
527
if self.info.revisions[-1].tree_actions is not None:
528
raise AssertionError()
497
assert self.info.revisions[-1].tree_actions is None
529
498
self.info.revisions[-1].tree_actions = revision_actions
531
500
def _read_footer(self):