~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd.
 
1
# Copyright (C) 2005-2014 Canonical Ltd.
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
119
119
 
120
120
 
121
121
def _spawn_external_diff(diffcmd, capture_errors=True):
122
 
    """Spawn the externall diff process, and return the child handle.
 
122
    """Spawn the external diff process, and return the child handle.
123
123
 
124
124
    :param diffcmd: The command list to spawn
125
125
    :param capture_errors: Capture stderr as well as setting LANG=C
154
154
 
155
155
    return pipe
156
156
 
 
157
# diff style options as of GNU diff v3.2
 
158
style_option_list = ['-c', '-C', '--context',
 
159
                     '-e', '--ed',
 
160
                     '-f', '--forward-ed',
 
161
                     '-q', '--brief',
 
162
                     '--normal',
 
163
                     '-n', '--rcs',
 
164
                     '-u', '-U', '--unified',
 
165
                     '-y', '--side-by-side',
 
166
                     '-D', '--ifdef']
 
167
 
 
168
def default_style_unified(diff_opts):
 
169
    """Default to unified diff style if alternative not specified in diff_opts.
 
170
 
 
171
        diff only allows one style to be specified; they don't override.
 
172
        Note that some of these take optargs, and the optargs can be
 
173
        directly appended to the options.
 
174
        This is only an approximate parser; it doesn't properly understand
 
175
        the grammar.
 
176
 
 
177
    :param diff_opts: List of options for external (GNU) diff.
 
178
    :return: List of options with default style=='unified'.
 
179
    """
 
180
    for s in style_option_list:
 
181
        for j in diff_opts:
 
182
            if j.startswith(s):
 
183
                break
 
184
        else:
 
185
            continue
 
186
        break
 
187
    else:
 
188
        diff_opts.append('-u')
 
189
    return diff_opts
 
190
 
157
191
 
158
192
def external_diff(old_filename, oldlines, new_filename, newlines, to_file,
159
193
                  diff_opts):
195
229
                   '--binary',
196
230
                  ]
197
231
 
198
 
        # diff only allows one style to be specified; they don't override.
199
 
        # note that some of these take optargs, and the optargs can be
200
 
        # directly appended to the options.
201
 
        # this is only an approximate parser; it doesn't properly understand
202
 
        # the grammar.
203
 
        for s in ['-c', '-u', '-C', '-U',
204
 
                  '-e', '--ed',
205
 
                  '-q', '--brief',
206
 
                  '--normal',
207
 
                  '-n', '--rcs',
208
 
                  '-y', '--side-by-side',
209
 
                  '-D', '--ifdef']:
210
 
            for j in diff_opts:
211
 
                if j.startswith(s):
212
 
                    break
213
 
            else:
214
 
                continue
215
 
            break
216
 
        else:
217
 
            diffcmd.append('-u')
 
232
        diff_opts = default_style_unified(diff_opts)
218
233
 
219
234
        if diff_opts:
220
235
            diffcmd.extend(diff_opts)
265
280
                msg = 'exit code %d' % rc
266
281
 
267
282
            raise errors.BzrError('external diff failed with %s; command: %r'
268
 
                                  % (rc, diffcmd))
 
283
                                  % (msg, diffcmd))
269
284
 
270
285
 
271
286
    finally:
272
287
        oldtmpf.close()                 # and delete
273
288
        newtmpf.close()
274
 
        # Clean up. Warn in case the files couldn't be deleted
275
 
        # (in case windows still holds the file open, but not
276
 
        # if the files have already been deleted)
277
 
        try:
278
 
            os.remove(old_abspath)
279
 
        except OSError, e:
280
 
            if e.errno not in (errno.ENOENT,):
281
 
                warning('Failed to delete temporary file: %s %s',
282
 
                        old_abspath, e)
283
 
        try:
284
 
            os.remove(new_abspath)
285
 
        except OSError:
286
 
            if e.errno not in (errno.ENOENT,):
287
 
                warning('Failed to delete temporary file: %s %s',
288
 
                        new_abspath, e)
 
289
 
 
290
        def cleanup(path):
 
291
            # Warn in case the file couldn't be deleted (in case windows still
 
292
            # holds the file open, but not if the files have already been
 
293
            # deleted)
 
294
            try:
 
295
                os.remove(path)
 
296
            except OSError, e:
 
297
                if e.errno not in (errno.ENOENT,):
 
298
                    warning('Failed to delete temporary file: %s %s', path, e)
 
299
 
 
300
        cleanup(old_abspath)
 
301
        cleanup(new_abspath)
289
302
 
290
303
 
291
304
def get_trees_and_branches_to_diff_locked(