/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Michael Ellerman
  • Date: 2006-05-31 08:44:29 UTC
  • mto: (1711.2.63 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1792.
  • Revision ID: michael@ellerman.id.au-20060531084429-35e5429abda9f560
Add optional location to ancestry and fix behaviour for checkouts.

This adds an optional location parameter to the ancestry command. It also
changes the behaviour of ancestry on checkouts such that if they have
been created with a subset of the branch history, only the subset is
shown by 'bzr ancestry'. Tests for all of that as well.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
from bzrlib.delta import compare_trees
18
18
from bzrlib.errors import BzrError
19
19
import bzrlib.errors as errors
 
20
from bzrlib.patiencediff import unified_diff
 
21
import bzrlib.patiencediff
20
22
from bzrlib.symbol_versioning import *
 
23
from bzrlib.textfile import check_text_lines
21
24
from bzrlib.trace import mutter
22
25
 
 
26
 
23
27
# TODO: Rather than building a changeset object, we should probably
24
28
# invoke callbacks on an object.  That object can either accumulate a
25
29
# list, write them out directly, etc etc.
26
30
 
27
 
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file):
28
 
    import difflib
29
 
    
 
31
def internal_diff(old_filename, oldlines, new_filename, newlines, to_file,
 
32
                  allow_binary=False, sequence_matcher=None):
30
33
    # FIXME: difflib is wrong if there is no trailing newline.
31
34
    # The syntax used by patch seems to be "\ No newline at
32
35
    # end of file" following the last diff line from that
42
45
    # both sequences are empty.
43
46
    if not oldlines and not newlines:
44
47
        return
 
48
    
 
49
    if allow_binary is False:
 
50
        check_text_lines(oldlines)
 
51
        check_text_lines(newlines)
45
52
 
46
 
    ud = difflib.unified_diff(oldlines, newlines,
47
 
                              fromfile=old_filename+'\t', 
48
 
                              tofile=new_filename+'\t')
 
53
    if sequence_matcher is None:
 
54
        sequence_matcher = bzrlib.patiencediff.PatienceSequenceMatcher
 
55
    ud = unified_diff(oldlines, newlines,
 
56
                      fromfile=old_filename+'\t', 
 
57
                      tofile=new_filename+'\t',
 
58
                      sequencematcher=sequence_matcher)
49
59
 
50
60
    ud = list(ud)
51
61
    # work-around for difflib being too smart for its own good
184
194
 
185
195
 
186
196
def diff_cmd_helper(tree, specific_files, external_diff_options, 
187
 
                    old_revision_spec=None, new_revision_spec=None):
 
197
                    old_revision_spec=None, new_revision_spec=None,
 
198
                    old_label='a/', new_label='b/'):
188
199
    """Helper for cmd_diff.
189
200
 
190
201
   tree 
223
234
        new_tree = spec_tree(new_revision_spec)
224
235
 
225
236
    return show_diff_trees(old_tree, new_tree, sys.stdout, specific_files,
226
 
                           external_diff_options)
 
237
                           external_diff_options,
 
238
                           old_label=old_label, new_label=new_label)
227
239
 
228
240
 
229
241
def show_diff_trees(old_tree, new_tree, to_file, specific_files=None,
230
 
                    external_diff_options=None):
 
242
                    external_diff_options=None,
 
243
                    old_label='a/', new_label='b/'):
231
244
    """Show in text form the changes from one tree to another.
232
245
 
233
246
    to_files
241
254
        new_tree.lock_read()
242
255
        try:
243
256
            return _show_diff_trees(old_tree, new_tree, to_file,
244
 
                                    specific_files, external_diff_options)
 
257
                                    specific_files, external_diff_options,
 
258
                                    old_label=old_label, new_label=new_label)
245
259
        finally:
246
260
            new_tree.unlock()
247
261
    finally:
249
263
 
250
264
 
251
265
def _show_diff_trees(old_tree, new_tree, to_file,
252
 
                     specific_files, external_diff_options):
253
 
 
254
 
    # TODO: Options to control putting on a prefix or suffix, perhaps
255
 
    # as a format string?
256
 
    old_label = 'a/'
257
 
    new_label = 'b/'
 
266
                     specific_files, external_diff_options, 
 
267
                     old_label='a/', new_label='b/' ):
258
268
 
259
269
    DEVNULL = '/dev/null'
260
270
    # Windows users, don't panic about this filename -- it is a
280
290
    has_changes = 0
281
291
    for path, file_id, kind in delta.removed:
282
292
        has_changes = 1
283
 
        print >>to_file, '=== removed %s %r' % (kind, old_label + path)
 
293
        print >>to_file, '=== removed %s %r' % (kind, path)
284
294
        old_tree.inventory[file_id].diff(diff_file, old_label + path, old_tree,
285
295
                                         DEVNULL, None, None, to_file)
286
296
    for path, file_id, kind in delta.added:
287
297
        has_changes = 1
288
 
        print >>to_file, '=== added %s %r' % (kind, new_label + path)
 
298
        print >>to_file, '=== added %s %r' % (kind, path)
289
299
        new_tree.inventory[file_id].diff(diff_file, new_label + path, new_tree,
290
300
                                         DEVNULL, None, None, to_file, 
291
301
                                         reverse=True)
294
304
        has_changes = 1
295
305
        prop_str = get_prop_change(meta_modified)
296
306
        print >>to_file, '=== renamed %s %r => %r%s' % (
297
 
                    kind, old_label + old_path, new_label + new_path, prop_str)
 
307
                    kind, old_path, new_path, prop_str)
298
308
        _maybe_diff_file_or_symlink(old_label, old_path, old_tree, file_id,
299
309
                                    new_label, new_path, new_tree,
300
310
                                    text_modified, kind, to_file, diff_file)
301
311
    for path, file_id, kind, text_modified, meta_modified in delta.modified:
302
312
        has_changes = 1
303
313
        prop_str = get_prop_change(meta_modified)
304
 
        print >>to_file, '=== modified %s %r%s' % (kind, old_label + path,
305
 
                    prop_str)
 
314
        print >>to_file, '=== modified %s %r%s' % (kind, path, prop_str)
306
315
        if text_modified:
307
316
            _maybe_diff_file_or_symlink(old_label, path, old_tree, file_id,
308
317
                                        new_label, path, new_tree,
322
331
        raise errors.PathsNotVersionedError(sorted(unversioned))
323
332
    
324
333
 
 
334
def _raise_if_nonexistent(paths, old_tree, new_tree):
 
335
    """Complain if paths are not in either inventory or tree.
 
336
 
 
337
    It's OK with the files exist in either tree's inventory, or 
 
338
    if they exist in the tree but are not versioned.
 
339
    
 
340
    This can be used by operations such as bzr status that can accept
 
341
    unknown or ignored files.
 
342
    """
 
343
    mutter("check paths: %r", paths)
 
344
    if not paths:
 
345
        return
 
346
    s = old_tree.filter_unversioned_files(paths)
 
347
    s = new_tree.filter_unversioned_files(s)
 
348
    s = [path for path in s if not new_tree.has_filename(path)]
 
349
    if s:
 
350
        raise errors.PathsDoNotExist(sorted(s))
 
351
 
 
352
 
325
353
def get_prop_change(meta_modified):
326
354
    if meta_modified:
327
355
        return " (properties changed)"