93
92
long_header = 'bazaar-ng testament version 1\n'
94
93
short_header = 'bazaar-ng testament short form 1\n'
98
96
def from_revision(cls, repository, revision_id):
99
"""Produce a new testament from a historical revision."""
97
"""Produce a new testament from a historical revision"""
100
98
rev = repository.get_revision(revision_id)
101
tree = repository.revision_tree(revision_id)
102
return cls(rev, tree)
105
def from_revision_tree(cls, tree):
106
"""Produce a new testament from a revision tree."""
107
rev = tree._repository.get_revision(tree.get_revision_id())
108
return cls(rev, tree)
110
def __init__(self, rev, tree):
111
"""Create a new testament for rev using tree."""
99
inventory = repository.get_inventory(revision_id)
100
return cls(rev, inventory)
102
def __init__(self, rev, inventory):
103
"""Create a new testament for rev using inventory."""
112
104
self.revision_id = rev.revision_id
113
105
self.committer = rev.committer
114
106
self.timezone = rev.timezone or 0
115
107
self.timestamp = rev.timestamp
116
108
self.message = rev.message
117
109
self.parent_ids = rev.parent_ids[:]
118
if not isinstance(tree, Tree):
119
raise TypeError("As of bzr 2.4 Testament.__init__() takes a "
120
"Revision and a Tree.")
110
self.inventory = inventory
122
111
self.revprops = copy(rev.properties)
123
112
if contains_whitespace(self.revision_id):
124
113
raise ValueError(self.revision_id)
136
125
a(self.long_header)
137
a('revision-id: %s\n' % self.revision_id.decode('utf-8'))
126
a('revision-id: %s\n' % self.revision_id)
138
127
a('committer: %s\n' % self.committer)
139
128
a('timestamp: %d\n' % self.timestamp)
140
129
a('timezone: %d\n' % self.timezone)
143
132
for parent_id in sorted(self.parent_ids):
144
133
if contains_whitespace(parent_id):
145
134
raise ValueError(parent_id)
146
a(' %s\n' % parent_id.decode('utf-8'))
135
a(' %s\n' % parent_id)
148
137
for l in self.message.splitlines():
154
143
return [line.encode('utf-8') for line in r]
156
145
def _get_entries(self):
157
return ((path, ie) for (path, file_class, kind, ie) in
158
self.tree.list_files(include_root=self.include_root))
146
entries = self.inventory.iter_entries()
160
150
def _escape_path(self, path):
161
151
if contains_linebreaks(path):
162
152
raise ValueError(path)
163
if not isinstance(path, str):
164
# TODO(jelmer): Clean this up for pad.lv/1696545
165
path = path.decode('ascii')
166
return path.replace(u'\\', u'/').replace(u' ', u'\\ ')
153
return unicode(path.replace('\\', '/').replace(' ', '\ '))
168
155
def _entry_to_line(self, path, ie):
169
156
"""Turn an inventory entry into a testament line"""
170
157
if contains_whitespace(ie.file_id):
171
158
raise ValueError(ie.file_id)
174
161
if ie.kind == 'file':
175
162
# TODO: avoid switching on kind
176
163
if not ie.text_sha1:
177
164
raise AssertionError()
178
content = ie.text_sha1.decode('ascii')
165
content = ie.text_sha1
179
166
content_spacer = ' '
180
167
elif ie.kind == 'symlink':
181
168
if not ie.symlink_target:
191
178
def as_text(self):
192
return b''.join(self.as_text_lines())
179
return ''.join(self.as_text_lines())
194
181
def as_short_text(self):
195
182
"""Return short digest-based testament."""
196
return (self.short_header.encode('ascii') +
183
return (self.short_header +
199
186
% (self.revision_id, self.as_sha1()))
201
188
def _revprops_to_lines(self):
221
210
long_header = 'bazaar-ng testament version 2.1\n'
222
211
short_header = 'bazaar-ng testament short form 2.1\n'
225
212
def _entry_to_line(self, path, ie):
226
213
l = Testament._entry_to_line(self, path, ie)[:-1]
227
l += ' ' + ie.revision.decode('utf-8')
214
l += ' ' + ie.revision
228
215
l += {True: ' yes\n', False: ' no\n'}[ie.executable]
238
225
long_header = 'bazaar testament version 3 strict\n'
239
226
short_header = 'bazaar testament short form 3 strict\n'
227
def _get_entries(self):
228
return self.inventory.iter_entries()
242
230
def _escape_path(self, path):
243
231
if contains_linebreaks(path):
244
232
raise ValueError(path)
245
if not isinstance(path, str):
246
# TODO(jelmer): Clean this up for pad.lv/1696545
247
path = path.decode('ascii')
250
return path.replace(u'\\', u'/').replace(u' ', u'\\ ')
235
return unicode(path.replace('\\', '/').replace(' ', '\ '))