6
7
def write(self, repository, revision_ids, forced_bases, fileobj):
7
8
container = _PseudoContainer(fileobj)
8
9
transaction = repository.get_transaction()
9
for file_id, file_revision_ids in \
10
repository.fileids_altered_by_revision_ids(revision_ids).iteritems():
10
altered = repository.fileids_altered_by_revision_ids(revision_ids)
11
for file_id, file_revision_ids in altered.iteritems():
11
12
vf = repository.weave_store.get_weave(file_id, transaction)
12
13
file_revision_ids = [r for r in revision_ids if r in
14
15
for file_revision_id in file_revision_ids:
15
16
text = ''.join(vf.make_mpdiff(file_revision_id).to_patch())
16
container.add_record('M', len(text), ['file:%s/%s' %
17
(file_id, file_revision_id)], text)
17
container_name = self.encode_name('file', file_revision_id,
19
container.add_record('M', len(text), [container_name], text)
23
container = _RecordReader(file, self)
27
def encode_name(name_kind, revision_id, file_id=None):
28
assert name_kind in ('revision', 'file')
29
if name_kind in ('revision',):
30
assert file_id is None
32
assert file_id is not None
33
if file_id is not None:
34
file_tail = '/' + file_id
37
return name_kind + ':' + revision_id + file_tail
40
def decode_name(name):
41
kind, revisionfile_id = name.split(':', 1)
42
revisionfile_id = revisionfile_id.split('/')
43
if len(revisionfile_id) == 1:
44
revision_id = revisionfile_id[0]
47
revision_id, file_id = revisionfile_id
48
return kind, revision_id, file_id
23
51
class _PseudoContainer(object):
33
61
self._fileobj.write(bencode.bencode([list(e) for e in self._records]))
64
class _RecordReader(object):
66
def __init__(self, fileobj, serializer):
67
self._records = [tuple(e) for e in bencode.bdecode(fileobj.read())]
68
self._record_iter = iter(self._records)
69
self._current_text = None
70
self._serializer = serializer
72
def iter_records(self):
73
for type, size, names, text in self._records:
74
self._current_text = text
75
yield type, size, names
78
def read_record(self):
79
return self._current_text
81
def install(self, repository):
83
current_versionedfile = None
84
pending_file_records = []
85
for type_, size, names in self.iter_records():
87
self._install_file_records(current_versionedfile,
91
kind, revision_id, file_id = self._serializer.decode_name(name)
93
self._install_file_records(current_versionedfile,
96
if file_id != current_file:
97
self._install_file_records(current_versionedfile,
99
current_file = file_id
100
current_versionedfile = \
101
repository.weave_store.get_weave_or_empty(file_id,
102
repository.get_transaction())
103
pending_file_records = []
104
if revision_id in current_versionedfile:
106
pending_file_records.append((type_, revision_id, [],
110
def _install_file_records(self, current_versionedfile,
111
pending_file_records):
112
for type_, revision, parents, text in pending_file_records:
114
mpdiff = multiparent.MultiParent.from_lines(text)
115
current_versionedfile.add_mpdiff(revision, parents, mpdiff)