133
def _diff_one(oldlines, newlines, to_file, **kw):
136
# FIXME: difflib is wrong if there is no trailing newline.
137
# The syntax used by patch seems to be "\ No newline at
138
# end of file" following the last diff line from that
139
# file. This is not trivial to insert into the
140
# unified_diff output and it might be better to just fix
141
# or replace that function.
143
# In the meantime we at least make sure the patch isn't
147
# Special workaround for Python2.3, where difflib fails if
148
# both sequences are empty.
149
if not oldlines and not newlines:
154
if oldlines and (oldlines[-1][-1] != '\n'):
157
if newlines and (newlines[-1][-1] != '\n'):
161
ud = difflib.unified_diff(oldlines, newlines, **kw)
163
# work-around for difflib being too smart for its own good
164
# if /dev/null is "1,0", patch won't recognize it as /dev/null
167
ud[2] = ud[2].replace('-1,0', '-0,0')
170
ud[2] = ud[2].replace('+1,0', '+0,0')
172
to_file.writelines(ud)
174
print >>to_file, "\\ No newline at end of file"
133
178
def show_diff(b, revision, file_list):
134
import difflib, sys, types
182
raise NotImplementedError('diff on restricted files broken at the moment')
136
184
if revision == None:
137
185
old_tree = b.basis_tree()
152
200
# TODO: Generation of pseudo-diffs for added/deleted files could
153
201
# be usefully made into a much faster special case.
155
# TODO: Better to return them in sorted order I think.
158
file_list = [b.relpath(f) for f in file_list]
160
# FIXME: If given a file list, compare only those files rather
161
# than comparing everything and then throwing stuff away.
163
for file_state, fid, old_name, new_name, kind in diff_trees(old_tree, new_tree):
165
if file_list and (new_name not in file_list):
168
# Don't show this by default; maybe do it if an option is passed
169
# idlabel = ' {%s}' % fid
172
def diffit(oldlines, newlines, **kw):
174
# FIXME: difflib is wrong if there is no trailing newline.
175
# The syntax used by patch seems to be "\ No newline at
176
# end of file" following the last diff line from that
177
# file. This is not trivial to insert into the
178
# unified_diff output and it might be better to just fix
179
# or replace that function.
181
# In the meantime we at least make sure the patch isn't
185
# Special workaround for Python2.3, where difflib fails if
186
# both sequences are empty.
187
if not oldlines and not newlines:
192
if oldlines and (oldlines[-1][-1] != '\n'):
195
if newlines and (newlines[-1][-1] != '\n'):
199
ud = difflib.unified_diff(oldlines, newlines, **kw)
201
# work-around for difflib being too smart for its own good
202
# if /dev/null is "1,0", patch won't recognize it as /dev/null
205
ud[2] = ud[2].replace('-1,0', '-0,0')
208
ud[2] = ud[2].replace('+1,0', '+0,0')
210
sys.stdout.writelines(ud)
212
print "\\ No newline at end of file"
213
sys.stdout.write('\n')
215
if file_state in ['.', '?', 'I']:
217
elif file_state == 'A':
218
print '*** added %s %r' % (kind, new_name)
221
new_tree.get_file(fid).readlines(),
223
tofile=new_label + new_name + idlabel)
224
elif file_state == 'D':
225
assert isinstance(old_name, types.StringTypes)
226
print '*** deleted %s %r' % (kind, old_name)
228
diffit(old_tree.get_file(fid).readlines(), [],
229
fromfile=old_label + old_name + idlabel,
231
elif file_state in ['M', 'R']:
232
if file_state == 'M':
233
assert kind == 'file'
234
assert old_name == new_name
235
print '*** modified %s %r' % (kind, new_name)
236
elif file_state == 'R':
237
print '*** renamed %s %r => %r' % (kind, old_name, new_name)
240
diffit(old_tree.get_file(fid).readlines(),
241
new_tree.get_file(fid).readlines(),
242
fromfile=old_label + old_name + idlabel,
243
tofile=new_label + new_name)
245
raise BzrError("can't represent state %s {%s}" % (file_state, fid))
203
delta = compare_trees(old_tree, new_tree, want_unchanged=False)
205
for path, file_id, kind in delta.removed:
206
print '*** removed %s %r' % (kind, path)
208
_diff_one(old_tree.get_file(file_id).readlines(),
211
fromfile=old_label + path,
214
for path, file_id, kind in delta.added:
215
print '*** added %s %r' % (kind, path)
218
new_tree.get_file(file_id).readlines(),
221
tofile=new_label + path)
223
for old_path, new_path, file_id, kind, text_modified in delta.renamed:
224
print '*** renamed %s %r => %r' % (kind, old_path, new_path)
226
_diff_one(old_tree.get_file(file_id).readlines(),
227
new_tree.get_file(file_id).readlines(),
229
fromfile=old_label + old_path,
230
tofile=new_label + new_path)
232
for path, file_id, kind in delta.modified:
233
print '*** modified %s %r' % (kind, path)
235
_diff_one(old_tree.get_file(file_id).readlines(),
236
new_tree.get_file(file_id).readlines(),
238
fromfile=old_label + path,
239
tofile=new_label + path)
279
273
def show(self, to_file, show_ids=False, show_unchanged=False):
280
274
def show_list(files):
281
for path, fid in files:
275
for path, fid, kind in files:
276
if kind == 'directory':
278
elif kind == 'symlink':
283
282
print >>to_file, ' %-30s %s' % (path, fid)
285
284
print >>to_file, ' ', path
288
print >>to_file, 'removed files:'
287
print >>to_file, 'removed:'
289
288
show_list(self.removed)
292
print >>to_file, 'added files:'
291
print >>to_file, 'added:'
293
292
show_list(self.added)
296
print >>to_file, 'renamed files:'
297
for oldpath, newpath, fid, text_modified in self.renamed:
295
print >>to_file, 'renamed:'
296
for oldpath, newpath, fid, kind, text_modified in self.renamed:
299
298
print >>to_file, ' %s => %s %s' % (oldpath, newpath, fid)
301
300
print >>to_file, ' %s => %s' % (oldpath, newpath)
303
302
if self.modified:
304
print >>to_file, 'modified files:'
303
print >>to_file, 'modified:'
305
304
show_list(self.modified)
307
306
if show_unchanged and self.unchanged:
308
print >>to_file, 'unchanged files:'
307
print >>to_file, 'unchanged:'
309
308
show_list(self.unchanged)
336
338
# May not be worthwhile.
338
340
if old_path != new_path:
339
delta.renamed.append((old_path, new_path, file_id, text_modified))
341
delta.renamed.append((old_path, new_path, file_id, kind,
340
343
elif text_modified:
341
delta.modified.append((new_path, file_id))
344
delta.modified.append((new_path, file_id, kind))
342
345
elif want_unchanged:
343
delta.unchanged.append((new_path, file_id))
346
delta.unchanged.append((new_path, file_id, kind))
345
delta.removed.append((old_inv.id2path(file_id), file_id))
348
delta.removed.append((old_inv.id2path(file_id), file_id, kind))
350
mutter('start looking for new files')
346
351
for file_id in new_inv:
347
352
if file_id in old_inv:
349
delta.added.append((new_inv.id2path(file_id), file_id))
354
kind = new_inv.get_file_kind(file_id)
355
delta.added.append((new_inv.id2path(file_id), file_id, kind))
351
357
delta.removed.sort()
352
358
delta.added.sort()