/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: Ian Clatworthy
  • Date: 2007-12-04 05:49:37 UTC
  • mto: (3118.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 3119.
  • Revision ID: ian.clatworthy@internode.on.net-20071204054937-6v169ypv0lclbyuj
Improved diff based on feedback from abentley

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import time
28
28
 
29
29
from bzrlib import (
 
30
    bzrdir,
30
31
    errors,
31
32
    osutils,
32
33
    patiencediff,
37
38
 
38
39
from bzrlib.symbol_versioning import (
39
40
        deprecated_function,
 
41
        zero_ninetythree,
40
42
        )
41
43
from bzrlib.trace import mutter, warning
42
44
 
268
270
                        new_abspath, e)
269
271
 
270
272
 
 
273
@deprecated_function(zero_ninetythree)
271
274
def diff_cmd_helper(tree, specific_files, external_diff_options, 
272
275
                    old_revision_spec=None, new_revision_spec=None,
273
276
                    revision_specs=None,
344
347
                           extra_trees=extra_trees)
345
348
 
346
349
 
 
350
def _get_trees_to_diff(path_list, revision_specs, old_url, new_url):
 
351
    """Get the trees and specific files to diff given a list of paths.
 
352
 
 
353
    This method works out the trees to be diff'ed and the files of
 
354
    interest within those trees.
 
355
 
 
356
    :param path_list:
 
357
        the list of arguments passed to the diff command
 
358
    :param revision_specs:
 
359
        Zero, one or two RevisionSpecs from the diff command line,
 
360
        saying what revisions to compare.
 
361
    :param old_url:
 
362
        The url of the old branch or tree. If None, the tree to use is
 
363
        taken from the first path, if any, or the current working tree.
 
364
    :param new_url:
 
365
        The url of the new branch or tree. If None, the tree to use is
 
366
        taken from the first path, if any, or the current working tree.
 
367
    :returns:
 
368
        a tuple of (old_tree, new_tree, specific_files, extra_trees) where
 
369
        extra_trees is a sequence of additional trees to search in for
 
370
        file-ids.
 
371
    """
 
372
    # Get the old and new revision specs
 
373
    old_revision_spec = None
 
374
    new_revision_spec = None
 
375
    if revision_specs is not None:
 
376
        if len(revision_specs) > 0:
 
377
            old_revision_spec = revision_specs[0]
 
378
        if len(revision_specs) > 1:
 
379
            new_revision_spec = revision_specs[1]
 
380
        # If both revision specs include a branch, we can diff them
 
381
        # without needing to look further for the details
 
382
        if (old_revision_spec is not None and
 
383
            new_revision_spec is not None and
 
384
            not old_revision_spec.needs_branch() and
 
385
            not new_revision_spec.needs_branch()):
 
386
            old_tree = _get_tree_to_diff(old_revision_spec)
 
387
            new_tree = _get_tree_to_diff(new_revision_spec)
 
388
            specific_files = path_list or None
 
389
            return old_tree, new_tree, specific_files, None
 
390
 
 
391
    # If no path is given, assume the current directory
 
392
    if path_list is None or len(path_list) == 0:
 
393
        default_location = u'.'
 
394
        other_paths = []
 
395
        check_paths = True
 
396
    elif old_url is not None and new_url is not None:
 
397
        default_location = None  # don't care - not required
 
398
        other_paths = path_list
 
399
        check_paths = False
 
400
    else:
 
401
        default_location = path_list[0]
 
402
        other_paths = path_list[1:]
 
403
        check_paths = True
 
404
 
 
405
    # Get the old location
 
406
    if old_url is None:
 
407
        old_url = default_location
 
408
    working_tree, branch, relpath = \
 
409
        bzrdir.BzrDir.open_containing_tree_or_branch(old_url)
 
410
    old_tree = _get_tree_to_diff(old_revision_spec, working_tree, branch)
 
411
 
 
412
    # Get the new location
 
413
    if new_url is None:
 
414
        new_url = default_location
 
415
    if new_url != old_url:
 
416
        working_tree, branch, relpath = \
 
417
            bzrdir.BzrDir.open_containing_tree_or_branch(new_url)
 
418
    new_tree = _get_tree_to_diff(new_revision_spec, working_tree, branch,
 
419
        basis_is_default=working_tree is None)
 
420
 
 
421
    # Get the specific files and extra trees
 
422
    specific_files = _relative_files_for_diff(working_tree, relpath,
 
423
        other_paths, check_paths)
 
424
    extra_trees = None
 
425
    if new_tree != working_tree and working_tree is not None:
 
426
        extra_trees = (working_tree,)
 
427
    return old_tree, new_tree, specific_files, extra_trees
 
428
 
 
429
 
 
430
def _get_tree_to_diff(spec, tree=None, branch=None, basis_is_default=True):
 
431
    if branch is None and tree is not None:
 
432
        branch = tree.branch
 
433
    if spec is None or spec.spec is None:
 
434
        if basis_is_default:
 
435
            return branch.basis_tree()
 
436
        else:
 
437
            return tree
 
438
    revision = spec.in_store(branch)
 
439
    revision_id = revision.rev_id
 
440
    rev_branch = revision.branch
 
441
    return rev_branch.repository.revision_tree(revision_id)
 
442
 
 
443
 
 
444
def _relative_files_for_diff(tree, first_relpath, other_paths, check_paths):
 
445
    """Get the specific files for diff.
 
446
 
 
447
    This method converts path arguments to relative paths in a tree.
 
448
    If the tree is None or check_paths is False, other_paths are assumed
 
449
    to be relative already. Otherwise, all arguments must be paths in
 
450
    the working tree.
 
451
    """
 
452
    specific_files = []
 
453
    if first_relpath != '':
 
454
        specific_files.append(first_relpath)
 
455
    if not check_paths or tree is None:
 
456
        specific_files.extend(other_paths)
 
457
    else:
 
458
        for filename in other_paths:
 
459
            try:
 
460
                specific_files.append(tree.relpath(osutils.dereference_path(
 
461
                    filename)))
 
462
            except errors.PathNotChild:
 
463
                raise errors.BzrCommandError("Files are in different branches")
 
464
    if len(specific_files) == 0:
 
465
        specific_files = None
 
466
    return specific_files
 
467
 
 
468
 
347
469
def show_diff_trees(old_tree, new_tree, to_file, specific_files=None,
348
470
                    external_diff_options=None,
349
471
                    old_label='a/', new_label='b/',
351
473
                    path_encoding='utf8'):
352
474
    """Show in text form the changes from one tree to another.
353
475
 
354
 
    to_files
355
 
        If set, include only changes to these files.
 
476
    to_file
 
477
        The output stream.
 
478
 
 
479
    specific_files
 
480
        Include only changes to these files - None for all changes.
356
481
 
357
482
    external_diff_options
358
483
        If set, use an external GNU diff and pass these options.