~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Martin Pool
  • Date: 2005-05-27 02:57:50 UTC
  • Revision ID: mbp@sourcefrog.net-20050527025750-909876bea41d8db6
- new --diff-options to pass options through to external
  diff and turn it on

Show diffs side-by-side

added added

removed removed

Lines of Context:
67
67
 
68
68
 
69
69
 
70
 
def external_diff(old_label, oldlines, new_label, newlines, to_file):
 
70
def external_diff(old_label, oldlines, new_label, newlines, to_file,
 
71
                  diff_opts):
71
72
    """Display a diff by calling out to the external diff program."""
72
73
    import sys
73
74
    
76
77
                                  to_file)
77
78
 
78
79
    from tempfile import NamedTemporaryFile
79
 
    from os import system
 
80
    import os
80
81
 
81
82
    oldtmpf = NamedTemporaryFile()
82
83
    newtmpf = NamedTemporaryFile()
95
96
        oldtmpf.flush()
96
97
        newtmpf.flush()
97
98
 
98
 
        system('diff -u --label %s %s --label %s %s' % (old_label, oldtmpf.name, new_label, newtmpf.name))
 
99
        if not diff_opts:
 
100
            diff_opts = []
 
101
        diffcmd = ['diff',
 
102
                   '--label', old_label,
 
103
                   oldtmpf.name,
 
104
                   '--label', new_label,
 
105
                   newtmpf.name]
 
106
 
 
107
        # diff only allows one style to be specified; they don't override.
 
108
        # note that some of these take optargs, and the optargs can be
 
109
        # directly appended to the options.
 
110
        # this is only an approximate parser; it doesn't properly understand
 
111
        # the grammar.
 
112
        for s in ['-c', '-u', '-C', '-U',
 
113
                  '-e', '--ed',
 
114
                  '-q', '--brief',
 
115
                  '--normal',
 
116
                  '-n', '--rcs',
 
117
                  '-y', '--side-by-side',
 
118
                  '-D', '--ifdef']:
 
119
            for j in diff_opts:
 
120
                if j.startswith(s):
 
121
                    break
 
122
            else:
 
123
                continue
 
124
            break
 
125
        else:
 
126
            diffcmd.append('-u')
 
127
                  
 
128
        if diff_opts:
 
129
            diffcmd.extend(diff_opts)
 
130
 
 
131
        rc = os.spawnvp(os.P_WAIT, 'diff', diffcmd)
 
132
        
 
133
        if rc != 0 and rc != 1:
 
134
            # returns 1 if files differ; that's OK
 
135
            if rc < 0:
 
136
                msg = 'signal %d' % (-rc)
 
137
            else:
 
138
                msg = 'exit code %d' % rc
 
139
                
 
140
            raise BzrError('external diff failed with %s; command: %r' % (rc, diffcmd))
99
141
    finally:
100
142
        oldtmpf.close()                 # and delete
101
143
        newtmpf.close()
102
144
    
103
145
 
104
146
 
105
 
def diff_file(old_label, oldlines, new_label, newlines, to_file):
106
 
    if False:
107
 
        differ = external_diff
108
 
    else:
109
 
        differ = internal_diff
110
 
 
111
 
    differ(old_label, oldlines, new_label, newlines, to_file)
112
 
 
113
 
 
114
 
 
115
 
def show_diff(b, revision, specific_files):
 
147
def show_diff(b, revision, specific_files, external_diff_options=None):
116
148
    import sys
117
149
 
118
150
    if revision == None:
122
154
        
123
155
    new_tree = b.working_tree()
124
156
 
125
 
    show_diff_trees(old_tree, new_tree, sys.stdout, specific_files)
126
 
 
127
 
 
128
 
 
129
 
def show_diff_trees(old_tree, new_tree, to_file, specific_files=None):
 
157
    show_diff_trees(old_tree, new_tree, sys.stdout, specific_files,
 
158
                    external_diff_options)
 
159
 
 
160
 
 
161
 
 
162
def show_diff_trees(old_tree, new_tree, to_file, specific_files=None,
 
163
                    external_diff_options=None):
130
164
    """Show in text form the changes from one tree to another.
131
165
 
132
166
    to_files
133
167
        If set, include only changes to these files.
 
168
 
 
169
    external_diff_options
 
170
        If set, use an external GNU diff and pass these options.
134
171
    """
135
172
 
136
173
    # TODO: Options to control putting on a prefix or suffix, perhaps as a format string
145
182
    # TODO: Generation of pseudo-diffs for added/deleted files could
146
183
    # be usefully made into a much faster special case.
147
184
 
 
185
    if external_diff_options:
 
186
        assert isinstance(external_diff_options, basestring)
 
187
        opts = external_diff_options.split()
 
188
        def diff_file(olab, olines, nlab, nlines, to_file):
 
189
            external_diff(olab, olines, nlab, nlines, to_file, opts)
 
190
    else:
 
191
        diff_file = internal_diff
 
192
    
 
193
 
148
194
    delta = compare_trees(old_tree, new_tree, want_unchanged=False,
149
195
                          specific_files=specific_files)
150
196