~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Robert Collins
  • Date: 2005-10-15 11:38:29 UTC
  • mfrom: (1185.16.40)
  • Revision ID: robertc@lifelesslap.robertcollins.net-20051015113829-40226233fb246920
mergeĀ fromĀ martin

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /usr/bin/env python
2
1
# -*- coding: UTF-8 -*-
3
2
 
4
3
# This program is free software; you can redistribute it and/or modify
45
44
    ud = difflib.unified_diff(oldlines, newlines,
46
45
                              fromfile=old_label, tofile=new_label)
47
46
 
 
47
    ud = list(ud)
48
48
    # work-around for difflib being too smart for its own good
49
49
    # if /dev/null is "1,0", patch won't recognize it as /dev/null
50
50
    if not oldlines:
51
 
        ud = list(ud)
52
51
        ud[2] = ud[2].replace('-1,0', '-0,0')
53
52
    elif not newlines:
54
 
        ud = list(ud)
55
53
        ud[2] = ud[2].replace('+1,0', '+0,0')
 
54
    # work around for difflib emitting random spaces after the label
 
55
    ud[0] = ud[0][:-2] + '\n'
 
56
    ud[1] = ud[1][:-2] + '\n'
56
57
 
57
58
    for line in ud:
58
59
        to_file.write(line)
61
62
    print >>to_file
62
63
 
63
64
 
64
 
 
65
 
 
66
65
def external_diff(old_label, oldlines, new_label, newlines, to_file,
67
66
                  diff_opts):
68
67
    """Display a diff by calling out to the external diff program."""
140
139
    finally:
141
140
        oldtmpf.close()                 # and delete
142
141
        newtmpf.close()
143
 
    
144
 
 
145
 
 
146
 
def show_diff(b, revision, specific_files, external_diff_options=None):
 
142
 
 
143
def show_diff(b, from_spec, specific_files, external_diff_options=None,
 
144
              revision2=None, output=None):
147
145
    """Shortcut for showing the diff to the working tree.
148
146
 
149
147
    b
150
148
        Branch.
151
149
 
152
150
    revision
153
 
        None for each, or otherwise the old revision to compare against.
 
151
        None for 'basis tree', or otherwise the old revision to compare against.
154
152
    
155
153
    The more general form is show_diff_trees(), where the caller
156
154
    supplies any two trees.
157
155
    """
158
 
    import sys
 
156
    if output is None:
 
157
        import sys
 
158
        output = sys.stdout
159
159
 
160
 
    if revision == None:
 
160
    if from_spec is None:
161
161
        old_tree = b.basis_tree()
162
162
    else:
163
 
        old_tree = b.revision_tree(b.lookup_revision(revision))
164
 
        
165
 
    new_tree = b.working_tree()
166
 
 
167
 
    show_diff_trees(old_tree, new_tree, sys.stdout, specific_files,
 
163
        old_tree = b.revision_tree(from_spec.in_history(b).rev_id)
 
164
 
 
165
    if revision2 is None:
 
166
        new_tree = b.working_tree()
 
167
    else:
 
168
        new_tree = b.revision_tree(revision2.in_history(b).rev_id)
 
169
 
 
170
    show_diff_trees(old_tree, new_tree, output, specific_files,
168
171
                    external_diff_options)
169
172
 
170
173
 
205
208
                          specific_files=specific_files)
206
209
 
207
210
    for path, file_id, kind in delta.removed:
208
 
        print >>to_file, '*** removed %s %r' % (kind, path)
209
 
        if kind == 'file':
210
 
            diff_file(old_label + path,
211
 
                      old_tree.get_file(file_id).readlines(),
212
 
                      DEVNULL, 
213
 
                      [],
214
 
                      to_file)
215
 
 
 
211
        print >>to_file, '=== removed %s %r' % (kind, path)
 
212
        old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
 
213
                                         DEVNULL, None, None, to_file)
216
214
    for path, file_id, kind in delta.added:
217
 
        print >>to_file, '*** added %s %r' % (kind, path)
218
 
        if kind == 'file':
219
 
            diff_file(DEVNULL,
220
 
                      [],
221
 
                      new_label + path,
222
 
                      new_tree.get_file(file_id).readlines(),
223
 
                      to_file)
224
 
 
225
 
    for old_path, new_path, file_id, kind, text_modified in delta.renamed:
226
 
        print >>to_file, '*** renamed %s %r => %r' % (kind, old_path, new_path)
 
215
        print >>to_file, '=== added %s %r' % (kind, path)
 
216
        new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
 
217
                                         DEVNULL, None, None, to_file, 
 
218
                                         reverse=True)
 
219
    for (old_path, new_path, file_id, kind,
 
220
         text_modified, meta_modified) in delta.renamed:
 
221
        prop_str = get_prop_change(meta_modified)
 
222
        print >>to_file, '=== renamed %s %r => %r%s' % (
 
223
                          kind, old_path, new_path, prop_str)
 
224
        _maybe_diff_file_or_symlink(old_label, old_path, old_tree, file_id,
 
225
                                    new_label, new_path, new_tree,
 
226
                                    text_modified, kind, to_file, diff_file)
 
227
    for path, file_id, kind, text_modified, meta_modified in delta.modified:
 
228
        prop_str = get_prop_change(meta_modified)
 
229
        print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
227
230
        if text_modified:
228
 
            diff_file(old_label + old_path,
229
 
                      old_tree.get_file(file_id).readlines(),
230
 
                      new_label + new_path,
231
 
                      new_tree.get_file(file_id).readlines(),
232
 
                      to_file)
233
 
 
234
 
    for path, file_id, kind in delta.modified:
235
 
        print >>to_file, '*** modified %s %r' % (kind, path)
236
 
        if kind == 'file':
237
 
            diff_file(old_label + path,
238
 
                      old_tree.get_file(file_id).readlines(),
239
 
                      new_label + path,
240
 
                      new_tree.get_file(file_id).readlines(),
241
 
                      to_file)
242
 
 
243
 
 
244
 
 
245
 
 
246
 
 
 
231
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
 
232
                                        new_label, path, new_tree,
 
233
                                        True, kind, to_file, diff_file)
 
234
    
 
235
 
 
236
def get_prop_change(meta_modified):
 
237
    if meta_modified:
 
238
        return " (properties changed)"
 
239
    else:
 
240
        return  ""
 
241
 
 
242
 
 
243
def _maybe_diff_file_or_symlink(old_label, old_path, old_tree, file_id,
 
244
                                new_label, new_path, new_tree, text_modified,
 
245
                                kind, to_file, diff_file):
 
246
    if text_modified:
 
247
        new_entry = new_tree.inventory[file_id]
 
248
        old_tree.inventory[file_id].diff(diff_file,
 
249
                                         old_label + old_path, old_tree,
 
250
                                         new_label + new_path, new_entry, 
 
251
                                         new_tree, to_file)