75
75
def as_revision(self):
76
76
rev = Revision(revision_id=self.revision_id,
77
committer=self.committer,
78
timestamp=float(self.timestamp),
79
timezone=int(self.timezone),
80
inventory_sha1=self.inventory_sha1,
81
message='\n'.join(self.message))
77
committer=self.committer,
78
timestamp=float(self.timestamp),
79
timezone=int(self.timezone),
80
inventory_sha1=self.inventory_sha1,
81
message='\n'.join(self.message))
83
83
if self.parent_ids:
84
84
rev.parent_ids.extend(self.parent_ids)
116
116
"""This contains the meta information. Stuff that allows you to
117
117
recreate the revision or inventory XML.
119
120
def __init__(self, bundle_format=None):
120
121
self.bundle_format = None
121
122
self.committer = None
155
156
if rev.timestamp is None:
156
157
if rev.date is not None:
157
158
rev.timestamp, rev.timezone = \
158
unpack_highres_date(rev.date)
159
unpack_highres_date(rev.date)
160
161
rev.timestamp = self.timestamp
161
162
rev.timezone = self.timezone
210
211
revision_info = self.get_revision_info(revision_id)
211
212
inventory_revision_id = revision_id
212
213
bundle_tree = BundleTree(repository.revision_tree(base),
213
inventory_revision_id)
214
inventory_revision_id)
214
215
self._update_tree(bundle_tree, revision_id)
216
217
inv = bundle_tree.inventory
229
231
def add_sha(d, revision_id, sha1):
230
232
if revision_id is None:
231
233
if sha1 is not None:
232
234
raise BzrError('A Null revision should always'
233
'have a null sha1 hash')
235
'have a null sha1 hash')
235
237
if revision_id in d:
236
238
# This really should have been validated as part
237
239
# of _validate_revisions but lets do it again
238
240
if sha1 != d[revision_id]:
239
241
raise BzrError('** Revision %r referenced with 2 different'
240
' sha hashes %s != %s' % (revision_id,
241
sha1, d[revision_id]))
242
' sha hashes %s != %s' % (revision_id,
243
sha1, d[revision_id]))
243
245
d[revision_id] = sha1
263
265
if sha1 != local_sha1:
264
266
raise BzrError('sha1 mismatch. For revision id {%s}'
265
'local: %s, bundle: %s' % (revision_id, local_sha1, sha1))
267
'local: %s, bundle: %s' % (revision_id, local_sha1, sha1))
268
270
elif revision_id not in checked:
309
311
raise TestamentMismatch(rev.revision_id, rev_info.sha1, sha1)
310
312
if rev.revision_id in rev_to_sha1:
311
313
raise BzrError('Revision {%s} given twice in the list'
313
315
rev_to_sha1[rev.revision_id] = sha1
315
317
def _update_tree(self, bundle_tree, revision_id):
388
390
info = extra.split(' // ')
389
391
if len(info) <= 1:
390
392
raise BzrError('add action lines require the path and file id'
392
394
elif len(info) > 5:
393
395
raise BzrError('add action lines have fewer than 5 entries.'
396
398
if not info[1].startswith('file-id:'):
397
399
raise BzrError('The file-id should follow the path for an add'
399
401
# This will be Unicode because of how the stream is read. Turn it
400
402
# back into a utf8 file_id
401
403
file_id = cache_utf8.encode(info[1][8:])
413
415
info = extra.split(' // ')
414
416
if len(info) < 1:
415
417
raise BzrError('modified action lines have at least'
416
'the path in them: %r' % extra)
418
'the path in them: %r' % extra)
419
421
last_modified, encoding = extra_info(info[1:], path)
422
424
do_patch(path, lines, encoding)
424
426
valid_actions = {
430
432
for action_line, lines in \
431
self.get_revision_info(revision_id).tree_actions:
433
self.get_revision_info(revision_id).tree_actions:
432
434
first = action_line.find(' ')
434
436
raise BzrError('Bogus action line'
435
' (no opening space): %r' % action_line)
436
second = action_line.find(' ', first+1)
437
' (no opening space): %r' % action_line)
438
second = action_line.find(' ', first + 1)
438
440
raise BzrError('Bogus action line'
439
' (missing second space): %r' % action_line)
441
' (missing second space): %r' % action_line)
440
442
action = action_line[:first]
441
kind = action_line[first+1:second]
443
kind = action_line[first + 1:second]
442
444
if kind not in ('file', 'directory', 'symlink'):
443
445
raise BzrError('Bogus action line'
444
' (invalid object kind %r): %r' % (kind, action_line))
445
extra = action_line[second+1:]
446
' (invalid object kind %r): %r' % (kind, action_line))
447
extra = action_line[second + 1:]
447
449
if action not in valid_actions:
448
450
raise BzrError('Bogus action line'
449
' (unrecognized action): %r' % action_line)
451
' (unrecognized action): %r' % action_line)
450
452
valid_actions[action](kind, extra, lines)
452
454
def install_revisions(self, target_repo, stream_input=True):
471
473
def __init__(self, base_tree, revision_id):
472
474
self.base_tree = base_tree
473
self._renamed = {} # Mapping from old_path => new_path
474
self._renamed_r = {} # new_path => old_path
475
self._new_id = {} # new_path => new_id
476
self._new_id_r = {} # new_id => new_path
477
self._kinds = {} # new_path => kind
478
self._last_changed = {} # new_id => revision_id
479
self._executable = {} # new_id => executable value
475
self._renamed = {} # Mapping from old_path => new_path
476
self._renamed_r = {} # new_path => old_path
477
self._new_id = {} # new_path => new_id
478
self._new_id_r = {} # new_id => new_path
479
self._kinds = {} # new_path => kind
480
self._last_changed = {} # new_id => revision_id
481
self._executable = {} # new_id => executable value
480
482
self.patches = {}
481
self._targets = {} # new path => new symlink target
483
self._targets = {} # new path => new symlink target
482
484
self.deleted = []
483
485
self.contents_by_id = True
484
486
self.revision_id = revision_id
506
508
if (file_id in self._last_changed
507
509
and self._last_changed[file_id] != revision_id):
508
510
raise BzrError('Mismatched last-changed revision for file_id {%s}'
509
': %s != %s' % (file_id,
510
self._last_changed[file_id],
511
': %s != %s' % (file_id,
512
self._last_changed[file_id],
512
514
self._last_changed[file_id] = revision_id
514
516
def note_patch(self, new_path, patch):
545
547
old_path = pathjoin(old_dir, basename)
547
549
old_path = new_path
548
#If the new path wasn't in renamed, the old one shouldn't be in
550
# If the new path wasn't in renamed, the old one shouldn't be in
550
552
if old_path in self._renamed_r:
571
573
new_path = pathjoin(new_dir, basename)
573
575
new_path = old_path
574
#If the old path wasn't in renamed, the new one shouldn't be in
576
# If the old path wasn't in renamed, the new one shouldn't be in
576
578
if new_path in self._renamed:
628
630
file_id = self.path2id(path)
629
631
base_id = self.old_contents_id(file_id)
630
632
if (base_id is not None and
631
base_id != self.base_tree.get_root_id()):
633
base_id != self.base_tree.get_root_id()):
632
634
old_path = self.old_path(path)
633
635
patch_original = self.base_tree.get_file(
636
638
patch_original = None
637
639
file_patch = self.patches.get(path)
638
640
if file_patch is None:
639
641
if (patch_original is None and
640
self.kind(path, file_id) == 'directory'):
642
self.kind(path, file_id) == 'directory'):
642
644
if patch_original is None:
643
645
raise AssertionError("None: %s" % file_id)
797
799
# string.splitlines(True) also splits on '\r', but the iter_patched code
798
800
# only expects to iterate over '\n' style lines
799
801
return IterableFile(iter_patched(original,
800
BytesIO(file_patch).readlines()))
802
BytesIO(file_patch).readlines()))