~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Martin Pool
  • Date: 2006-01-13 08:12:22 UTC
  • mfrom: (1185.63.5 bzr.patches)
  • Revision ID: mbp@sourcefrog.net-20060113081222-6b572004a2ade0cc
[merge] test_hashcache_raise from Denys

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
# invoke callbacks on an object.  That object can either accumulate a
23
23
# list, write them out directly, etc etc.
24
24
 
25
 
def internal_diff(old_label, oldlines, new_label, newlines, to_file):
 
25
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file):
26
26
    import difflib
27
27
    
28
28
    # FIXME: difflib is wrong if there is no trailing newline.
42
42
        return
43
43
 
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')
46
47
 
47
48
    ud = list(ud)
48
49
    # work-around for difflib being too smart for its own good
62
63
    print >>to_file
63
64
 
64
65
 
65
 
def external_diff(old_label, oldlines, new_label, newlines, to_file,
 
66
def external_diff(old_filename, oldlines, new_filename, newlines, to_file,
66
67
                  diff_opts):
67
68
    """Display a diff by calling out to the external diff program."""
68
69
    import sys
97
98
        if not diff_opts:
98
99
            diff_opts = []
99
100
        diffcmd = ['diff',
100
 
                   '--label', old_label,
 
101
                   '--label', old_filename+'\t',
101
102
                   oldtmpf.name,
102
 
                   '--label', new_label,
 
103
                   '--label', new_filename+'\t',
103
104
                   newtmpf.name]
104
105
 
105
106
        # diff only allows one style to be specified; they don't override.
141
142
        newtmpf.close()
142
143
 
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.
146
147
 
147
148
    b
158
159
        output = sys.stdout
159
160
 
160
161
    if from_spec is None:
161
 
        old_tree = b.basis_tree()
 
162
        if b2 is None:
 
163
            old_tree = b.basis_tree()
 
164
        else:
 
165
            old_tree = b.working_tree()
162
166
    else:
163
167
        old_tree = b.revision_tree(from_spec.in_history(b).rev_id)
164
168
 
165
169
    if revision2 is None:
166
 
        new_tree = b.working_tree()
 
170
        if b2 is None:
 
171
            new_tree = b.working_tree()
 
172
        else:
 
173
            new_tree = b2.working_tree()
167
174
    else:
168
175
        new_tree = b.revision_tree(revision2.in_history(b).rev_id)
169
176
 
170
 
    show_diff_trees(old_tree, new_tree, output, specific_files,
171
 
                    external_diff_options)
 
177
    return show_diff_trees(old_tree, new_tree, output, specific_files,
 
178
                           external_diff_options)
172
179
 
173
180
 
174
181
 
183
190
        If set, use an external GNU diff and pass these options.
184
191
    """
185
192
 
 
193
    old_tree.lock_read()
 
194
    try:
 
195
        new_tree.lock_read()
 
196
        try:
 
197
            return _show_diff_trees(old_tree, new_tree, to_file,
 
198
                                    specific_files, external_diff_options)
 
199
        finally:
 
200
            new_tree.unlock()
 
201
    finally:
 
202
        old_tree.unlock()
 
203
 
 
204
 
 
205
def _show_diff_trees(old_tree, new_tree, to_file,
 
206
                     specific_files, external_diff_options):
 
207
 
186
208
    # TODO: Options to control putting on a prefix or suffix, perhaps as a format string
187
209
    old_label = ''
188
210
    new_label = ''
207
229
    delta = compare_trees(old_tree, new_tree, want_unchanged=False,
208
230
                          specific_files=specific_files)
209
231
 
 
232
    has_changes = 0
210
233
    for path, file_id, kind in delta.removed:
 
234
        has_changes = 1
211
235
        print >>to_file, '=== removed %s %r' % (kind, path)
212
236
        old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
213
237
                                         DEVNULL, None, None, to_file)
214
238
    for path, file_id, kind in delta.added:
 
239
        has_changes = 1
215
240
        print >>to_file, '=== added %s %r' % (kind, path)
216
241
        new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
217
242
                                         DEVNULL, None, None, to_file, 
218
243
                                         reverse=True)
219
244
    for (old_path, new_path, file_id, kind,
220
245
         text_modified, meta_modified) in delta.renamed:
 
246
        has_changes = 1
221
247
        prop_str = get_prop_change(meta_modified)
222
248
        print >>to_file, '=== renamed %s %r => %r%s' % (
223
249
                          kind, old_path, new_path, prop_str)
225
251
                                    new_label, new_path, new_tree,
226
252
                                    text_modified, kind, to_file, diff_file)
227
253
    for path, file_id, kind, text_modified, meta_modified in delta.modified:
 
254
        has_changes = 1
228
255
        prop_str = get_prop_change(meta_modified)
229
256
        print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
230
257
        if text_modified:
231
258
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
232
259
                                        new_label, path, new_tree,
233
260
                                        True, kind, to_file, diff_file)
 
261
    return has_changes
234
262
    
235
263
 
236
264
def get_prop_change(meta_modified):