60
60
def __init__(self, branch, revisions, delta,
61
61
full_remove=True, full_rename=False,
62
external_diff_options = None,
63
62
new_tree=None, old_tree=None,
64
63
old_label = '', new_label = ''):
72
71
self.full_remove=full_remove
73
72
self.full_rename=full_rename
74
self.external_diff_options = external_diff_options
75
73
self.old_label = old_label
76
74
self.new_label = new_label
77
75
self.old_tree = old_tree
78
76
self.new_tree = new_tree
79
77
self.to_file = None
81
self.precursor_revno = None
79
#self.parent_revno = None
81
# These are entries in the header.
82
# They will be repeated in the footer,
83
# only if they have changed
83
88
self._get_revision_list(revisions)
111
116
for rev_id in rh[old_revno+1:new_revno+1]:
112
117
self.revision_list.append(self.branch.get_revision(rev_id))
113
self.precursor_revno = old_revno+1
114
self.revno = new_revno+1
118
#self.parent_revno = old_revno+1
119
#self.revno = new_revno+1
116
121
def _write(self, txt, key=None):
134
139
def _write_header(self):
135
140
"""Write the stuff that comes before the patches."""
136
from bzrlib.osutils import username, format_date
141
from bzrlib.osutils import username
142
from common import format_highres_date
137
143
write = self._write
139
145
for line in common.get_header():
142
148
# Print out the basic information about the 'target' revision
143
149
rev = self.revision_list[-1]
144
150
write(rev.committer, key='committer')
145
write(format_date(rev.timestamp, offset=rev.timezone), key='date')
151
self.committer = rev.committer
152
self.date = format_highres_date(rev.timestamp, offset=rev.timezone)
153
write(self.date, key='date')
147
155
self.to_file.write('# message:\n')
148
156
for line in rev.message.split('\n'):
149
157
self.to_file.write('# %s\n' % line)
158
self.message = rev.message
152
161
self.to_file.write('\n')
160
169
write = self._write
162
write('BEGIN BZR FOOTER')
164
171
# Base revision is the revision this changeset is against
172
# We probably should write some sort of
174
# for base revisions of EmptyTree, rather than
175
# just looking like we left it off.
176
# Besides, we might leave it off in the trivial case
177
# that the base is the first parent of the target revision.
178
# In which case having it missing doesn't mean that we
179
# should use the empty tree.
165
180
if self.base_revision:
166
181
rev_id = self.base_revision.revision_id
167
182
write(rev_id, key='base')
170
185
self._write_revisions()
172
187
#self._write_ids()
174
write('END BZR FOOTER')
188
self._write_text_ids()
176
190
def _write_revisions(self):
177
191
"""Not used. Used for writing multiple revisions."""
192
from common import format_highres_date
178
194
for rev in self.revision_list:
179
195
rev_id = rev.revision_id
180
196
self.to_file.write('# revision: %s\n' % rev_id)
181
197
self.to_file.write('# sha1: %s\n' %
182
198
self.branch.get_revision_sha1(rev_id))
183
self.to_file.write('# committer: %s\n' % rev.committer)
184
self.to_file.write('# timestamp: %.9f\n' % rev.timestamp)
185
self.to_file.write('# timezone: %s\n' % rev.timezone)
186
self.to_file.write('# inventory id: %s\n' % rev.inventory_id)
199
if rev.committer != self.committer:
200
self.to_file.write('# committer: %s\n' % rev.committer)
201
date = format_highres_date(rev.timestamp, rev.timezone)
202
if date != self.date:
203
self.to_file.write('# date: %s\n' % date)
204
if rev.inventory_id != rev_id:
205
self.to_file.write('# inventory id: %s\n' % rev.inventory_id)
187
206
self.to_file.write('# inventory sha1: %s\n' % rev.inventory_sha1)
188
207
self.to_file.write('# parents:\n')
189
208
for parent in rev.parents:
190
209
self.to_file.write('# %s\t%s\n' % (
191
210
parent.revision_id,
192
211
parent.revision_sha1))
193
self.to_file.write('# message:\n')
194
for line in rev.message.split('\n'):
195
self.to_file.write('# %s\n' % line)
212
if rev.message and rev.message != self.message:
213
self.to_file.write('# message:\n')
214
for line in rev.message.split('\n'):
215
self.to_file.write('# %s\n' % line)
198
218
def _write_ids(self):
241
261
def _write_diffs(self):
242
262
"""Write out the specific diffs"""
243
263
from bzrlib.diff import internal_diff, external_diff
264
from common import encode
244
265
DEVNULL = '/dev/null'
246
if self.external_diff_options:
247
assert isinstance(self.external_diff_options, basestring)
248
opts = self.external_diff_options.split()
249
def diff_file(olab, olines, nlab, nlines, to_file):
250
external_diff(olab, olines, nlab, nlines, to_file, opts)
252
diff_file = internal_diff
267
diff_file = internal_diff
268
# Get the target tree so that we can check for
269
# Appropriate text ids.
270
rev_id = self.revision_list[-1].revision_id
271
tree = self.branch.revision_tree(rev_id)
274
def get_text_id_str(file_id, modified=True):
275
"""This returns an empty string if guess_text_id == real_text_id.
276
Otherwise it returns a string suitable for printing, indicating
279
guess_id = common.guess_text_id(tree, file_id, rev_id,
281
real_id = tree.inventory[file_id].text_id
282
if guess_id != real_id:
283
return '\ttext-id:' + encode(real_id)
254
288
for path, file_id, kind in self.delta.removed:
255
print >>self.to_file, '*** removed %s %r' % (kind, path)
289
# We don't care about text ids for removed files
290
print >>self.to_file, '*** removed %s %s' % (kind,
256
292
if kind == 'file' and self.full_remove:
257
293
diff_file(self.old_label + path,
258
294
self.old_tree.get_file(file_id).readlines(),
263
299
for path, file_id, kind in self.delta.added:
264
print >>self.to_file, '*** added %s %r id:%s' % (kind, path, file_id)
300
print >>self.to_file, '*** added %s %s\tfile-id:%s%s' % (kind,
303
get_text_id_str(file_id))
265
304
if kind == 'file':
266
305
diff_file(DEVNULL,
272
311
for old_path, new_path, file_id, kind, text_modified in self.delta.renamed:
273
print >>self.to_file, '*** renamed %s %r => %r' % (kind, old_path, new_path)
312
print >>self.to_file, '*** renamed %s %s\t=> %s%s' % (kind,
313
encode(old_path), encode(new_path),
314
get_text_id_str(file_id, text_modified))
274
315
if self.full_rename and kind == 'file':
275
316
diff_file(self.old_label + old_path,
276
317
self.old_tree.get_file(file_id).readlines(),
292
333
for path, file_id, kind in self.delta.modified:
293
print >>self.to_file, '*** modified %s %r' % (kind, path)
334
print >>self.to_file, '*** modified %s %s%s' % (kind,
335
encode(path), get_text_id_str(file_id))
294
336
if kind == 'file':
295
337
diff_file(self.old_label + path,
296
338
self.old_tree.get_file(file_id).readlines(),