14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
from bzrlib.delta import compare_trees
18
from bzrlib.errors import BzrError
17
19
from bzrlib.trace import mutter
18
from bzrlib.errors import BzrError
19
from bzrlib.delta import compare_trees
21
21
# TODO: Rather than building a changeset object, we should probably
22
22
# invoke callbacks on an object. That object can either accumulate a
23
23
# list, write them out directly, etc etc.
25
def internal_diff(old_label, oldlines, new_label, newlines, to_file):
25
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file):
28
28
# FIXME: difflib is wrong if there is no trailing newline.
44
44
ud = difflib.unified_diff(oldlines, newlines,
45
fromfile=old_label, tofile=new_label)
45
fromfile=old_filename+'\t',
46
tofile=new_filename+'\t')
48
49
# work-around for difflib being too smart for its own good
65
def external_diff(old_label, oldlines, new_label, newlines, to_file,
66
def external_diff(old_filename, oldlines, new_filename, newlines, to_file,
67
68
"""Display a diff by calling out to the external diff program."""
99
100
diffcmd = ['diff',
100
'--label', old_label,
101
'--label', old_filename+'\t',
102
'--label', new_label,
103
'--label', new_filename+'\t',
105
106
# diff only allows one style to be specified; they don't override.
143
144
def show_diff(b, from_spec, specific_files, external_diff_options=None,
144
revision2=None, output=None):
145
revision2=None, output=None, b2=None):
145
146
"""Shortcut for showing the diff to the working tree.
158
159
output = sys.stdout
160
161
if from_spec is None:
161
old_tree = b.basis_tree()
162
old_tree = b.bzrdir.open_workingtree()
164
old_tree = old_tree = old_tree.basis_tree()
163
old_tree = b.revision_tree(from_spec.in_history(b).rev_id)
166
old_tree = b.repository.revision_tree(from_spec.in_history(b).rev_id)
165
168
if revision2 is None:
166
new_tree = b.working_tree()
170
new_tree = b.bzrdir.open_workingtree()
172
new_tree = b2.bzrdir.open_workingtree()
168
new_tree = b.revision_tree(revision2.in_history(b).rev_id)
174
new_tree = b.repository.revision_tree(revision2.in_history(b).rev_id)
170
show_diff_trees(old_tree, new_tree, output, specific_files,
171
external_diff_options)
176
return show_diff_trees(old_tree, new_tree, output, specific_files,
177
external_diff_options)
183
189
If set, use an external GNU diff and pass these options.
196
return _show_diff_trees(old_tree, new_tree, to_file,
197
specific_files, external_diff_options)
204
def _show_diff_trees(old_tree, new_tree, to_file,
205
specific_files, external_diff_options):
186
207
# TODO: Options to control putting on a prefix or suffix, perhaps as a format string
207
228
delta = compare_trees(old_tree, new_tree, want_unchanged=False,
208
229
specific_files=specific_files)
210
232
for path, file_id, kind in delta.removed:
211
234
print >>to_file, '=== removed %s %r' % (kind, path)
212
235
old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
213
236
DEVNULL, None, None, to_file)
214
237
for path, file_id, kind in delta.added:
215
239
print >>to_file, '=== added %s %r' % (kind, path)
216
240
new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
217
241
DEVNULL, None, None, to_file,
219
243
for (old_path, new_path, file_id, kind,
220
244
text_modified, meta_modified) in delta.renamed:
221
246
prop_str = get_prop_change(meta_modified)
222
247
print >>to_file, '=== renamed %s %r => %r%s' % (
223
248
kind, old_path, new_path, prop_str)
225
250
new_label, new_path, new_tree,
226
251
text_modified, kind, to_file, diff_file)
227
252
for path, file_id, kind, text_modified, meta_modified in delta.modified:
228
254
prop_str = get_prop_change(meta_modified)
229
255
print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
230
256
if text_modified:
231
257
_maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
232
258
new_label, path, new_tree,
233
259
True, kind, to_file, diff_file)
236
263
def get_prop_change(meta_modified):