~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Robert Collins
  • Date: 2010-04-10 09:22:04 UTC
  • mto: This revision was merged to the branch mainline in revision 5142.
  • Revision ID: robertc@robertcollins.net-20100410092204-jrdwwf7vtfr0t41k
``bzrlib.mutabletree.MutableTree.commit`` will now support a passed in
config as in previous versions of bzrlib. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import difflib
18
18
import os
19
19
import re
 
20
import shutil
20
21
import string
21
22
import sys
22
23
 
31
32
    branch as _mod_branch,
32
33
    bzrdir,
33
34
    cmdline,
34
 
    cleanup,
35
35
    errors,
36
36
    osutils,
37
37
    patiencediff,
48
48
    )
49
49
from bzrlib.symbol_versioning import (
50
50
    deprecated_function,
51
 
    deprecated_in,
52
51
    )
53
52
from bzrlib.trace import mutter, note, warning
54
53
 
99
98
    if sequence_matcher is None:
100
99
        sequence_matcher = patiencediff.PatienceSequenceMatcher
101
100
    ud = patiencediff.unified_diff(oldlines, newlines,
102
 
                      fromfile=old_filename.encode(path_encoding, 'replace'),
103
 
                      tofile=new_filename.encode(path_encoding, 'replace'),
 
101
                      fromfile=old_filename.encode(path_encoding),
 
102
                      tofile=new_filename.encode(path_encoding),
104
103
                      sequencematcher=sequence_matcher)
105
104
 
106
105
    ud = list(ud)
290
289
                        new_abspath, e)
291
290
 
292
291
 
293
 
@deprecated_function(deprecated_in((2, 2, 0)))
294
292
def get_trees_and_branches_to_diff(path_list, revision_specs, old_url, new_url,
295
293
                                   apply_view=True):
296
294
    """Get the trees and specific files to diff given a list of paths.
315
313
    :returns:
316
314
        a tuple of (old_tree, new_tree, old_branch, new_branch,
317
315
        specific_files, extra_trees) where extra_trees is a sequence of
318
 
        additional trees to search in for file-ids.  The trees and branches
319
 
        are not locked.
320
 
    """
321
 
    op = cleanup.OperationWithCleanups(get_trees_and_branches_to_diff_locked)
322
 
    return op.run_simple(path_list, revision_specs, old_url, new_url,
323
 
            op.add_cleanup, apply_view=apply_view)
324
 
    
325
 
 
326
 
def get_trees_and_branches_to_diff_locked(
327
 
    path_list, revision_specs, old_url, new_url, add_cleanup, apply_view=True):
328
 
    """Get the trees and specific files to diff given a list of paths.
329
 
 
330
 
    This method works out the trees to be diff'ed and the files of
331
 
    interest within those trees.
332
 
 
333
 
    :param path_list:
334
 
        the list of arguments passed to the diff command
335
 
    :param revision_specs:
336
 
        Zero, one or two RevisionSpecs from the diff command line,
337
 
        saying what revisions to compare.
338
 
    :param old_url:
339
 
        The url of the old branch or tree. If None, the tree to use is
340
 
        taken from the first path, if any, or the current working tree.
341
 
    :param new_url:
342
 
        The url of the new branch or tree. If None, the tree to use is
343
 
        taken from the first path, if any, or the current working tree.
344
 
    :param add_cleanup:
345
 
        a callable like Command.add_cleanup.  get_trees_and_branches_to_diff
346
 
        will register cleanups that must be run to unlock the trees, etc.
347
 
    :param apply_view:
348
 
        if True and a view is set, apply the view or check that the paths
349
 
        are within it
350
 
    :returns:
351
 
        a tuple of (old_tree, new_tree, old_branch, new_branch,
352
 
        specific_files, extra_trees) where extra_trees is a sequence of
353
 
        additional trees to search in for file-ids.  The trees and branches
354
 
        will be read-locked until the cleanups registered via the add_cleanup
355
 
        param are run.
 
316
        additional trees to search in for file-ids.
356
317
    """
357
318
    # Get the old and new revision specs
358
319
    old_revision_spec = None
381
342
        default_location = path_list[0]
382
343
        other_paths = path_list[1:]
383
344
 
384
 
    def lock_tree_or_branch(wt, br):
385
 
        if wt is not None:
386
 
            wt.lock_read()
387
 
            add_cleanup(wt.unlock)
388
 
        elif br is not None:
389
 
            br.lock_read()
390
 
            add_cleanup(br.unlock)
391
 
 
392
345
    # Get the old location
393
346
    specific_files = []
394
347
    if old_url is None:
395
348
        old_url = default_location
396
349
    working_tree, branch, relpath = \
397
350
        bzrdir.BzrDir.open_containing_tree_or_branch(old_url)
398
 
    lock_tree_or_branch(working_tree, branch)
399
351
    if consider_relpath and relpath != '':
400
352
        if working_tree is not None and apply_view:
401
353
            views.check_path_in_view(working_tree, relpath)
409
361
    if new_url != old_url:
410
362
        working_tree, branch, relpath = \
411
363
            bzrdir.BzrDir.open_containing_tree_or_branch(new_url)
412
 
        lock_tree_or_branch(working_tree, branch)
413
364
        if consider_relpath and relpath != '':
414
365
            if working_tree is not None and apply_view:
415
366
                views.check_path_in_view(working_tree, relpath)
420
371
 
421
372
    # Get the specific files (all files is None, no files is [])
422
373
    if make_paths_wt_relative and working_tree is not None:
423
 
        other_paths = working_tree.safe_relpath_files(
424
 
            other_paths,
 
374
        try:
 
375
            from bzrlib.builtins import safe_relpath_files
 
376
            other_paths = safe_relpath_files(working_tree, other_paths,
425
377
            apply_view=apply_view)
 
378
        except errors.FileInWrongBranch:
 
379
            raise errors.BzrCommandError("Files are in different branches")
426
380
    specific_files.extend(other_paths)
427
381
    if len(specific_files) == 0:
428
382
        specific_files = None
703
657
        """
704
658
        def _get_text(tree, file_id, path):
705
659
            if file_id is not None:
706
 
                return tree.get_file_lines(file_id, path)
 
660
                return tree.get_file(file_id, path).readlines()
707
661
            else:
708
662
                return []
709
663
        try:
710
664
            from_text = _get_text(self.old_tree, from_file_id, from_path)
711
665
            to_text = _get_text(self.new_tree, to_file_id, to_path)
712
666
            self.text_differ(from_label, from_text, to_label, to_text,
713
 
                             self.to_file, path_encoding=self.path_encoding)
 
667
                             self.to_file)
714
668
        except errors.BinaryFile:
715
669
            self.to_file.write(
716
670
                  ("Binary files %s and %s differ\n" %
717
 
                  (from_label, to_label)).encode(self.path_encoding,'replace'))
 
671
                  (from_label, to_label)).encode(self.path_encoding))
718
672
        return self.CHANGED
719
673
 
720
674
 
736
690
                     path_encoding)
737
691
 
738
692
    @classmethod
739
 
    def make_from_diff_tree(klass, command_string, external_diff_options=None):
 
693
    def make_from_diff_tree(klass, command_string):
740
694
        def from_diff_tree(diff_tree):
741
 
            full_command_string = [command_string]
742
 
            if external_diff_options is not None:
743
 
                full_command_string += ' ' + external_diff_options
744
 
            return klass.from_string(full_command_string, diff_tree.old_tree,
 
695
            return klass.from_string(command_string, diff_tree.old_tree,
745
696
                                     diff_tree.new_tree, diff_tree.to_file)
746
697
        return from_diff_tree
747
698
 
797
748
                target.close()
798
749
        finally:
799
750
            source.close()
 
751
        if not allow_write:
 
752
            osutils.make_readonly(full_path)
800
753
        try:
801
754
            mtime = tree.get_file_mtime(file_id)
802
755
        except errors.FileTimestampUnavailable:
803
 
            pass
804
 
        else:
805
 
            os.utime(full_path, (mtime, mtime))
806
 
        if not allow_write:
807
 
            osutils.make_readonly(full_path)
 
756
            mtime = 0
 
757
        os.utime(full_path, (mtime, mtime))
808
758
        return full_path
809
759
 
810
760
    def _prepare_files(self, file_id, old_path, new_path, force_temp=False,
915
865
        :param using: Commandline to use to invoke an external diff tool
916
866
        """
917
867
        if using is not None:
918
 
            extra_factories = [DiffFromTool.make_from_diff_tree(using, external_diff_options)]
 
868
            extra_factories = [DiffFromTool.make_from_diff_tree(using)]
919
869
        else:
920
870
            extra_factories = []
921
871
        if external_diff_options:
922
872
            opts = external_diff_options.split()
923
 
            def diff_file(olab, olines, nlab, nlines, to_file, path_encoding=None):
924
 
                """:param path_encoding: not used but required
925
 
                        to match the signature of internal_diff.
926
 
                """
 
873
            def diff_file(olab, olines, nlab, nlines, to_file):
927
874
                external_diff(olab, olines, nlab, nlines, to_file, opts)
928
875
        else:
929
876
            diff_file = internal_diff