/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 breezy/workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2018-05-06 11:48:54 UTC
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@jelmer.uk-20180506114854-h4qd9ojaqy8wxjsd
Move .mailmap to root.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
import errno
33
33
import os
 
34
import re
 
35
import shutil
34
36
import sys
35
37
 
36
38
import breezy
37
39
 
38
40
from .lazy_import import lazy_import
39
41
lazy_import(globals(), """
40
 
import shutil
41
42
import stat
42
43
 
43
44
from breezy import (
44
 
    cleanup,
 
45
    branch,
45
46
    conflicts as _mod_conflicts,
 
47
    controldir,
 
48
    errors,
46
49
    filters as _mod_filters,
 
50
    generate_ids,
47
51
    merge,
48
52
    revision as _mod_revision,
49
53
    transform,
50
54
    transport,
 
55
    ui,
51
56
    views,
52
57
    )
53
 
from breezy.bzr import (
54
 
    generate_ids,
55
 
    )
56
58
""")
57
59
 
58
60
from . import (
59
 
    errors,
60
 
    )
61
 
from .controldir import (
62
 
    ControlComponent,
63
 
    ControlComponentFormatRegistry,
64
 
    ControlComponentFormat,
65
 
    ControlDir,
66
 
    ControlDirFormat,
67
 
    )
68
 
from . import (
69
61
    osutils,
70
62
    )
71
63
from .i18n import gettext
72
64
from . import mutabletree
73
 
from .symbol_versioning import deprecated_method, deprecated_in
 
65
from .sixish import (
 
66
    text_type,
 
67
    )
74
68
from .trace import mutter, note
75
69
 
76
70
 
 
71
ERROR_PATH_NOT_FOUND = 3    # WindowsError errno code, equivalent to ENOENT
 
72
 
 
73
 
77
74
class SettingFileIdUnsupported(errors.BzrError):
78
75
 
79
76
    _fmt = "This format does not support setting file ids."
84
81
    _fmt = "This format does not support shelving changes."
85
82
 
86
83
 
87
 
class WorkingTree(mutabletree.MutableTree, ControlComponent):
 
84
class WorkingTree(mutabletree.MutableTree,
 
85
    controldir.ControlComponent):
88
86
    """Working copy tree.
89
87
 
90
88
    :ivar basedir: The root of the tree on disk. This is a unicode path object
109
107
        self.controldir = _controldir
110
108
        if not _internal:
111
109
            raise errors.BzrError("Please use controldir.open_workingtree or "
112
 
                                  "WorkingTree.open() to obtain a WorkingTree.")
 
110
                "WorkingTree.open() to obtain a WorkingTree.")
113
111
        basedir = osutils.safe_unicode(basedir)
114
112
        mutter("opening working tree %r", basedir)
115
113
        if branch is not None:
129
127
    def control_transport(self):
130
128
        return self._transport
131
129
 
132
 
    def supports_symlinks(self):
133
 
        return osutils.supports_symlinks(self.basedir)
134
 
 
135
130
    def is_control_filename(self, filename):
136
131
        """True if filename is the name of a control file in this tree.
137
132
 
162
157
        return self._format.supports_merge_modified
163
158
 
164
159
    def _supports_executable(self):
165
 
        return osutils.supports_executable(self.basedir)
 
160
        if sys.platform == 'win32':
 
161
            return False
 
162
        # FIXME: Ideally this should check the file system
 
163
        return True
166
164
 
167
165
    def break_lock(self):
168
166
        """Break a lock if one is present from another instance.
204
202
        """
205
203
        if path is None:
206
204
            path = osutils.getcwd()
207
 
        control = ControlDir.open(path, _unsupported=_unsupported)
 
205
        control = controldir.ControlDir.open(path, _unsupported=_unsupported)
208
206
        return control.open_workingtree(unsupported=_unsupported)
209
207
 
210
208
    @staticmethod
222
220
        """
223
221
        if path is None:
224
222
            path = osutils.getcwd()
225
 
        control, relpath = ControlDir.open_containing(path)
 
223
        control, relpath = controldir.ControlDir.open_containing(path)
226
224
        return control.open_workingtree(), relpath
227
225
 
228
226
    @staticmethod
281
279
        # self.relpath exists as a "thunk" to osutils, but canonical_relpath
282
280
        # doesn't - fix that up here before we enter the loop.
283
281
        if canonicalize:
284
 
            def fixer(p):
285
 
                return osutils.canonical_relpath(self.basedir, p)
 
282
            fixer = lambda p: osutils.canonical_relpath(self.basedir, p)
286
283
        else:
287
284
            fixer = self.relpath
288
285
        for filename in file_list:
300
297
        """
301
298
        return WorkingTree.open(path, _unsupported=True)
302
299
 
 
300
    @staticmethod
 
301
    def find_trees(location):
 
302
        def list_current(transport):
 
303
            return [d for d in transport.list_dir('')
 
304
                    if not controldir.is_control_filename(d)]
 
305
        def evaluate(controldir):
 
306
            try:
 
307
                tree = controldir.open_workingtree()
 
308
            except errors.NoWorkingTree:
 
309
                return True, None
 
310
            else:
 
311
                return True, tree
 
312
        t = transport.get_transport(location)
 
313
        iterator = controldir.ControlDir.find_controldirs(t, evaluate=evaluate,
 
314
                                              list_current=list_current)
 
315
        return [tr for tr in iterator if tr is not None]
 
316
 
303
317
    def __repr__(self):
304
318
        return "<%s of %s>" % (self.__class__.__name__,
305
319
                               getattr(self, 'basedir', None))
321
335
            # in the future this should return the tree for
322
336
            # 'empty:' - the implicit root empty tree.
323
337
            return self.branch.repository.revision_tree(
324
 
                _mod_revision.NULL_REVISION)
 
338
                       _mod_revision.NULL_REVISION)
325
339
        try:
326
340
            return self.revision_tree(revision_id)
327
341
        except errors.NoSuchRevision:
339
353
                raise
340
354
            # the basis tree is a ghost so return an empty tree.
341
355
            return self.branch.repository.revision_tree(
342
 
                _mod_revision.NULL_REVISION)
 
356
                       _mod_revision.NULL_REVISION)
343
357
 
344
358
    def relpath(self, path):
345
359
        """Return the local path portion from a given path.
352
366
    def has_filename(self, filename):
353
367
        return osutils.lexists(self.abspath(filename))
354
368
 
355
 
    def get_file(self, path, filtered=True):
356
 
        return self.get_file_with_stat(path, filtered=filtered)[0]
 
369
    def get_file(self, path, file_id=None, filtered=True):
 
370
        return self.get_file_with_stat(path, file_id, filtered=filtered)[0]
357
371
 
358
 
    def get_file_with_stat(self, path, filtered=True,
 
372
    def get_file_with_stat(self, path, file_id=None, filtered=True,
359
373
                           _fstat=osutils.fstat):
360
374
        """See Tree.get_file_with_stat."""
361
375
        abspath = self.abspath(path)
368
382
        stat_value = _fstat(file_obj.fileno())
369
383
        if filtered and self.supports_content_filtering():
370
384
            filters = self._content_filter_stack(path)
371
 
            if filters:
372
 
                file_obj, size = _mod_filters.filtered_input_file(
373
 
                    file_obj, filters)
374
 
                stat_value = _mod_filters.FilteredStat(
375
 
                    stat_value, st_size=size)
 
385
            file_obj = _mod_filters.filtered_input_file(file_obj, filters)
376
386
        return (file_obj, stat_value)
377
387
 
378
 
    def get_file_text(self, path, filtered=True):
379
 
        with self.get_file(path, filtered=filtered) as my_file:
 
388
    def get_file_text(self, path, file_id=None, filtered=True):
 
389
        with self.get_file(path, file_id, filtered=filtered) as my_file:
380
390
            return my_file.read()
381
391
 
382
 
    def get_file_lines(self, path, filtered=True):
 
392
    def get_file_lines(self, path, file_id=None, filtered=True):
383
393
        """See Tree.get_file_lines()"""
384
 
        with self.get_file(path, filtered=filtered) as file:
 
394
        with self.get_file(path, file_id, filtered=filtered) as file:
385
395
            return file.readlines()
386
396
 
387
397
    def get_parent_ids(self):
401
411
            pass
402
412
        else:
403
413
            for l in osutils.split_lines(merges_bytes):
404
 
                revision_id = l.rstrip(b'\n')
 
414
                revision_id = l.rstrip('\n')
405
415
                parents.append(revision_id)
406
416
        return parents
407
417
 
 
418
    def get_root_id(self):
 
419
        """Return the id of this trees root"""
 
420
        raise NotImplementedError(self.get_root_id)
 
421
 
408
422
    def clone(self, to_controldir, revision_id=None):
409
423
        """Duplicate this working tree into to_bzr, including all state.
410
424
 
427
441
    def copy_content_into(self, tree, revision_id=None):
428
442
        """Copy the current content and user files of this tree into tree."""
429
443
        with self.lock_read():
430
 
            tree.set_root_id(self.path2id(''))
 
444
            tree.set_root_id(self.get_root_id())
431
445
            if revision_id is None:
432
446
                merge.transform_tree(tree, self)
433
447
            else:
437
451
                    other_tree = self.revision_tree(revision_id)
438
452
                except errors.NoSuchRevision:
439
453
                    other_tree = self.branch.repository.revision_tree(
440
 
                        revision_id)
 
454
                            revision_id)
441
455
 
442
456
                merge.transform_tree(tree, other_tree)
443
457
                if revision_id == _mod_revision.NULL_REVISION:
446
460
                    new_parents = [revision_id]
447
461
                tree.set_parent_ids(new_parents)
448
462
 
449
 
    def get_file_size(self, path):
 
463
    def get_file_size(self, path, file_id=None):
450
464
        """See Tree.get_file_size"""
451
465
        # XXX: this returns the on-disk size; it should probably return the
452
466
        # canonical size
484
498
        with self.lock_write():
485
499
            parents = self.get_parent_ids() + [revision_id]
486
500
            self.set_parent_ids(parents, allow_leftmost_as_ghost=len(parents) > 1
487
 
                                or allow_leftmost_as_ghost)
 
501
                or allow_leftmost_as_ghost)
488
502
 
489
503
    def add_parent_tree(self, parent_tuple, allow_leftmost_as_ghost=False):
490
504
        """Add revision_id, tree tuple as a parent.
506
520
                # was.
507
521
                allow_leftmost_as_ghost = True
508
522
            self.set_parent_ids(parent_ids,
509
 
                                allow_leftmost_as_ghost=allow_leftmost_as_ghost)
 
523
                allow_leftmost_as_ghost=allow_leftmost_as_ghost)
510
524
 
511
525
    def add_pending_merge(self, *revision_ids):
512
526
        with self.lock_tree_write():
523
537
                self.set_parent_ids(parents, allow_leftmost_as_ghost=True)
524
538
 
525
539
    def path_content_summary(self, path, _lstat=os.lstat,
526
 
                             _mapper=osutils.file_kind_from_stat_mode):
 
540
        _mapper=osutils.file_kind_from_stat_mode):
527
541
        """See Tree.path_content_summary."""
528
542
        abspath = self.abspath(path)
529
543
        try:
565
579
        if len(revision_ids) > 0:
566
580
            leftmost_id = revision_ids[0]
567
581
            if (not allow_leftmost_as_ghost and not
568
 
                    self.branch.repository.has_revision(leftmost_id)):
 
582
                self.branch.repository.has_revision(leftmost_id)):
569
583
                raise errors.GhostRevisionUnusableHere(leftmost_id)
570
584
 
571
585
    def _set_merges_from_parent_ids(self, parent_ids):
572
586
        merges = parent_ids[1:]
573
587
        self._transport.put_bytes('pending-merges', b'\n'.join(merges),
574
 
                                  mode=self.controldir._get_file_mode())
 
588
            mode=self.controldir._get_file_mode())
575
589
 
576
590
    def _filter_parent_ids_by_ancestry(self, revision_ids):
577
591
        """Check that all merged revisions are proper 'heads'.
589
603
                new_revision_ids.append(revision_id)
590
604
        if new_revision_ids != revision_ids:
591
605
            mutter('requested to set revision_ids = %s,'
592
 
                   ' but filtered to %s', revision_ids, new_revision_ids)
 
606
                         ' but filtered to %s', revision_ids, new_revision_ids)
593
607
        return new_revision_ids
594
608
 
595
609
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
606
620
        """
607
621
        with self.lock_tree_write():
608
622
            self._check_parents_for_ghosts(revision_ids,
609
 
                                           allow_leftmost_as_ghost=allow_leftmost_as_ghost)
 
623
                allow_leftmost_as_ghost=allow_leftmost_as_ghost)
610
624
            for revision_id in revision_ids:
611
625
                _mod_revision.check_not_reserved_id(revision_id)
612
626
 
661
675
            merger.other_rev_id = to_revision
662
676
            if _mod_revision.is_null(merger.other_rev_id):
663
677
                raise errors.NoCommits(branch)
664
 
            self.branch.fetch(branch, stop_revision=merger.other_rev_id)
 
678
            self.branch.fetch(branch, last_revision=merger.other_rev_id)
665
679
            merger.other_basis = merger.other_rev_id
666
680
            merger.other_tree = self.branch.repository.revision_tree(
667
681
                merger.other_rev_id)
709
723
            self.add(path, file_id, 'directory')
710
724
            return file_id
711
725
 
712
 
    def get_symlink_target(self, path):
 
726
    def get_symlink_target(self, path, file_id=None):
713
727
        abspath = self.abspath(path)
714
728
        target = osutils.readlink(abspath)
715
729
        return target
717
731
    def subsume(self, other_tree):
718
732
        raise NotImplementedError(self.subsume)
719
733
 
720
 
    def _directory_is_tree_reference(self, relpath):
721
 
        raise NotImplementedError(self._directory_is_tree_reference)
722
 
 
723
 
    def extract(self, path, format=None):
 
734
    def _setup_directory_is_tree_reference(self):
 
735
        if self._branch.repository._format.supports_tree_reference:
 
736
            self._directory_is_tree_reference = \
 
737
                self._directory_may_be_tree_reference
 
738
        else:
 
739
            self._directory_is_tree_reference = \
 
740
                self._directory_is_never_tree_reference
 
741
 
 
742
    def _directory_is_never_tree_reference(self, relpath):
 
743
        return False
 
744
 
 
745
    def _directory_may_be_tree_reference(self, relpath):
 
746
        # as a special case, if a directory contains control files then
 
747
        # it's a tree reference, except that the root of the tree is not
 
748
        return relpath and osutils.isdir(self.abspath(relpath) + u"/.bzr")
 
749
        # TODO: We could ask all the control formats whether they
 
750
        # recognize this directory, but at the moment there's no cheap api
 
751
        # to do that.  Since we probably can only nest bzr checkouts and
 
752
        # they always use this name it's ok for now.  -- mbp 20060306
 
753
        #
 
754
        # FIXME: There is an unhandled case here of a subdirectory
 
755
        # containing .bzr but not a branch; that will probably blow up
 
756
        # when you try to commit it.  It might happen if there is a
 
757
        # checkout in a subdirectory.  This can be avoided by not adding
 
758
        # it.  mbp 20070306
 
759
 
 
760
    def extract(self, path, file_id=None, format=None):
724
761
        """Extract a subtree from this tree.
725
762
 
726
763
        A new branch will be created, relative to the path for this tree.
731
768
        """Write the in memory meta data to disk."""
732
769
        raise NotImplementedError(self.flush)
733
770
 
734
 
    def kind(self, relpath):
 
771
    def kind(self, relpath, file_id=None):
735
772
        return osutils.file_kind(self.abspath(relpath))
736
773
 
737
 
    def list_files(self, include_root=False, from_dir=None, recursive=True,
738
 
                   recurse_nested=False):
 
774
    def list_files(self, include_root=False, from_dir=None, recursive=True):
739
775
        """List all files as (path, class, kind, id, entry).
740
776
 
741
777
        Lists, but does not descend into unversioned directories.
821
857
 
822
858
    def pull(self, source, overwrite=False, stop_revision=None,
823
859
             change_reporter=None, possible_transports=None, local=False,
824
 
             show_base=False, tag_selector=None):
 
860
             show_base=False):
825
861
        with self.lock_write(), source.lock_read():
826
862
            old_revision_info = self.branch.last_revision_info()
827
863
            basis_tree = self.basis_tree()
828
864
            count = self.branch.pull(source, overwrite, stop_revision,
829
865
                                     possible_transports=possible_transports,
830
 
                                     local=local, tag_selector=tag_selector)
 
866
                                     local=local)
831
867
            new_revision_info = self.branch.last_revision_info()
832
868
            if new_revision_info != old_revision_info:
833
869
                repository = self.branch.repository
839
875
                with basis_tree.lock_read():
840
876
                    new_basis_tree = self.branch.basis_tree()
841
877
                    merge.merge_inner(
842
 
                        self.branch,
843
 
                        new_basis_tree,
844
 
                        basis_tree,
845
 
                        this_tree=self,
846
 
                        change_reporter=change_reporter,
847
 
                        show_base=show_base)
848
 
                    basis_root_id = basis_tree.path2id('')
849
 
                    new_root_id = new_basis_tree.path2id('')
 
878
                                self.branch,
 
879
                                new_basis_tree,
 
880
                                basis_tree,
 
881
                                this_tree=self,
 
882
                                change_reporter=change_reporter,
 
883
                                show_base=show_base)
 
884
                    basis_root_id = basis_tree.get_root_id()
 
885
                    new_root_id = new_basis_tree.get_root_id()
850
886
                    if new_root_id is not None and basis_root_id != new_root_id:
851
887
                        self.set_root_id(new_root_id)
852
888
                # TODO - dedup parents list with things merged by pull ?
864
900
                merges = self.get_parent_ids()[1:]
865
901
                parent_trees.extend([
866
902
                    (parent, repository.revision_tree(parent)) for
867
 
                    parent in merges])
 
903
                     parent in merges])
868
904
                self.set_parent_trees(parent_trees)
869
905
            return count
870
906
 
871
 
    def put_file_bytes_non_atomic(self, path, bytes):
 
907
    def put_file_bytes_non_atomic(self, path, bytes, file_id=None):
872
908
        """See MutableTree.put_file_bytes_non_atomic."""
873
 
        with self.lock_write(), open(self.abspath(path), 'wb') as stream:
874
 
            stream.write(bytes)
 
909
        with self.lock_write(), file(self.abspath(path), 'wb') as stream:
 
910
                stream.write(bytes)
875
911
 
876
912
    def extras(self):
877
913
        """Yield all unversioned files in this WorkingTree.
878
914
 
879
 
        If there are any unversioned directories and the file format
880
 
        supports versioning directories, then only the directory is returned,
881
 
        not all its children. But if there are unversioned files under a
882
 
        versioned subdirectory, they are returned.
 
915
        If there are any unversioned directories then only the directory is
 
916
        returned, not all its children.  But if there are unversioned files
 
917
        under a versioned subdirectory, they are returned.
883
918
 
884
919
        Currently returned depth-first, sorted by name within directories.
885
920
        This is the same order used by 'osutils.walkdirs'.
898
933
        """
899
934
        raise NotImplementedError(self.is_ignored)
900
935
 
901
 
    def stored_kind(self, path):
 
936
    def stored_kind(self, path, file_id=None):
902
937
        """See Tree.stored_kind"""
903
938
        raise NotImplementedError(self.stored_kind)
904
939
 
1002
1037
    def revert(self, filenames=None, old_tree=None, backups=True,
1003
1038
               pb=None, report_changes=False):
1004
1039
        from .conflicts import resolve
1005
 
        with cleanup.ExitStack() as exit_stack:
1006
 
            exit_stack.enter_context(self.lock_tree_write())
 
1040
        with self.lock_tree_write():
1007
1041
            if old_tree is None:
1008
1042
                basis_tree = self.basis_tree()
1009
 
                exit_stack.enter_context(basis_tree.lock_read())
 
1043
                basis_tree.lock_read()
1010
1044
                old_tree = basis_tree
1011
1045
            else:
1012
1046
                basis_tree = None
1013
 
            conflicts = transform.revert(self, old_tree, filenames, backups, pb,
1014
 
                                         report_changes)
1015
 
            if filenames is None and len(self.get_parent_ids()) > 1:
1016
 
                parent_trees = []
1017
 
                last_revision = self.last_revision()
1018
 
                if last_revision != _mod_revision.NULL_REVISION:
1019
 
                    if basis_tree is None:
1020
 
                        basis_tree = self.basis_tree()
1021
 
                        exit_stack.enter_context(basis_tree.lock_read())
1022
 
                    parent_trees.append((last_revision, basis_tree))
1023
 
                self.set_parent_trees(parent_trees)
1024
 
                resolve(self)
1025
 
            else:
1026
 
                resolve(self, filenames, ignore_misses=True, recursive=True)
 
1047
            try:
 
1048
                conflicts = transform.revert(self, old_tree, filenames, backups, pb,
 
1049
                                             report_changes)
 
1050
                if filenames is None and len(self.get_parent_ids()) > 1:
 
1051
                    parent_trees = []
 
1052
                    last_revision = self.last_revision()
 
1053
                    if last_revision != _mod_revision.NULL_REVISION:
 
1054
                        if basis_tree is None:
 
1055
                            basis_tree = self.basis_tree()
 
1056
                            basis_tree.lock_read()
 
1057
                        parent_trees.append((last_revision, basis_tree))
 
1058
                    self.set_parent_trees(parent_trees)
 
1059
                    resolve(self)
 
1060
                else:
 
1061
                    resolve(self, filenames, ignore_misses=True, recursive=True)
 
1062
            finally:
 
1063
                if basis_tree is not None:
 
1064
                    basis_tree.unlock()
1027
1065
            return conflicts
1028
1066
 
1029
1067
    def store_uncommitted(self):
1047
1085
        if not self.supports_setting_file_ids():
1048
1086
            raise SettingFileIdUnsupported()
1049
1087
        with self.lock_tree_write():
1050
 
            # for compatibility
 
1088
            # for compatability
1051
1089
            if file_id is None:
1052
1090
                raise ValueError(
1053
1091
                    'WorkingTree.set_root_id with fileid=None')
1156
1194
            if not _mod_revision.is_null(old_tip) and old_tip != last_rev:
1157
1195
                # the branch we are bound to was updated
1158
1196
                # merge those changes in first
1159
 
                base_tree = self.basis_tree()
 
1197
                base_tree  = self.basis_tree()
1160
1198
                other_tree = self.branch.repository.revision_tree(old_tip)
1161
1199
                nb_conflicts = merge.merge_inner(self.branch, other_tree,
1162
1200
                                                 base_tree, this_tree=self,
1171
1209
                # the working tree is up to date with the branch
1172
1210
                # we can merge the specified revision from master
1173
1211
                to_tree = self.branch.repository.revision_tree(revision)
1174
 
                to_root_id = to_tree.path2id('')
 
1212
                to_root_id = to_tree.get_root_id()
1175
1213
 
1176
1214
                basis = self.basis_tree()
1177
1215
                with basis.lock_read():
1178
 
                    if (basis.path2id('') is None or basis.path2id('') != to_root_id):
 
1216
                    if (basis.get_root_id() is None or basis.get_root_id() != to_root_id):
1179
1217
                        self.set_root_id(to_root_id)
1180
1218
                        self.flush()
1181
1219
 
1234
1272
        """
1235
1273
        raise NotImplementedError(self.walkdirs)
1236
1274
 
1237
 
    @deprecated_method(deprecated_in((3, 0, 1)))
1238
1275
    def auto_resolve(self):
1239
1276
        """Automatically resolve text conflicts according to contents.
1240
1277
 
1248
1285
        with self.lock_tree_write():
1249
1286
            un_resolved = _mod_conflicts.ConflictList()
1250
1287
            resolved = _mod_conflicts.ConflictList()
 
1288
            conflict_re = re.compile('^(<{7}|={7}|>{7})')
1251
1289
            for conflict in self.conflicts():
1252
 
                try:
1253
 
                    conflict.action_auto(self)
1254
 
                except NotImplementedError:
 
1290
                path = self.id2path(conflict.file_id)
 
1291
                if (conflict.typestring != 'text conflict' or
 
1292
                    self.kind(path, conflict.file_id) != 'file'):
1255
1293
                    un_resolved.append(conflict)
1256
 
                else:
1257
 
                    conflict.cleanup(self)
1258
 
                    resolved.append(conflict)
 
1294
                    continue
 
1295
                with open(self.abspath(path), 'rb') as my_file:
 
1296
                    for line in my_file:
 
1297
                        if conflict_re.search(line):
 
1298
                            un_resolved.append(conflict)
 
1299
                            break
 
1300
                    else:
 
1301
                        resolved.append(conflict)
 
1302
            resolved.remove_files(self)
1259
1303
            self.set_conflicts(un_resolved)
1260
1304
            return un_resolved, resolved
1261
1305
 
1286
1330
        """See Tree._get_rules_searcher."""
1287
1331
        if self._rules_searcher is None:
1288
1332
            self._rules_searcher = super(WorkingTree,
1289
 
                                         self)._get_rules_searcher(default_searcher)
 
1333
                self)._get_rules_searcher(default_searcher)
1290
1334
        return self._rules_searcher
1291
1335
 
1292
1336
    def get_shelf_manager(self):
1293
1337
        """Return the ShelfManager for this WorkingTree."""
1294
1338
        raise NotImplementedError(self.get_shelf_manager)
1295
1339
 
1296
 
    def get_canonical_paths(self, paths):
1297
 
        """Like get_canonical_path() but works on multiple items.
1298
 
 
1299
 
        :param paths: A sequence of paths relative to the root of the tree.
1300
 
        :return: A list of paths, with each item the corresponding input path
1301
 
            adjusted to account for existing elements that match case
1302
 
            insensitively.
1303
 
        """
1304
 
        with self.lock_read():
1305
 
            for path in paths:
1306
 
                yield path
1307
 
 
1308
 
    def get_canonical_path(self, path):
1309
 
        """Returns the first item in the tree that matches a path.
1310
 
 
1311
 
        This is meant to allow case-insensitive path lookups on e.g.
1312
 
        FAT filesystems.
1313
 
 
1314
 
        If a path matches exactly, it is returned. If no path matches exactly
1315
 
        but more than one path matches according to the underlying file system,
1316
 
        it is implementation defined which is returned.
1317
 
 
1318
 
        If no path matches according to the file system, the input path is
1319
 
        returned, but with as many path entries that do exist changed to their
1320
 
        canonical form.
1321
 
 
1322
 
        If you need to resolve many names from the same tree, you should
1323
 
        use get_canonical_paths() to avoid O(N) behaviour.
1324
 
 
1325
 
        :param path: A paths relative to the root of the tree.
1326
 
        :return: The input path adjusted to account for existing elements
1327
 
        that match case insensitively.
1328
 
        """
1329
 
        with self.lock_read():
1330
 
            return next(self.get_canonical_paths([path]))
1331
 
 
1332
 
    def reference_parent(self, path, branch=None, possible_transports=None):
1333
 
        raise errors.UnsupportedOperation(self.reference_parent, self)
1334
 
 
1335
 
    def get_reference_info(self, path, branch=None):
1336
 
        raise errors.UnsupportedOperation(self.get_reference_info, self)
1337
 
 
1338
 
    def set_reference_info(self, tree_path, branch_location):
1339
 
        raise errors.UnsupportedOperation(self.set_reference_info, self)
1340
 
 
1341
 
 
1342
 
class WorkingTreeFormatRegistry(ControlComponentFormatRegistry):
 
1340
 
 
1341
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
1343
1342
    """Registry for working tree formats."""
1344
1343
 
1345
1344
    def __init__(self, other_registry=None):
1350
1349
    def get_default(self):
1351
1350
        """Return the current default format."""
1352
1351
        if (self._default_format_key is not None and
1353
 
                self._default_format is None):
 
1352
            self._default_format is None):
1354
1353
            self._default_format = self.get(self._default_format_key)
1355
1354
        return self._default_format
1356
1355
 
1368
1367
format_registry = WorkingTreeFormatRegistry()
1369
1368
 
1370
1369
 
1371
 
class WorkingTreeFormat(ControlComponentFormat):
 
1370
class WorkingTreeFormat(controldir.ControlComponentFormat):
1372
1371
    """An encapsulation of the initialization and open routines for a format.
1373
1372
 
1374
1373
    Formats provide three things:
1469
1468
 
1470
1469
 
1471
1470
format_registry.register_lazy(b"Bazaar Working Tree Format 4 (bzr 0.15)\n",
1472
 
                              "breezy.bzr.workingtree_4", "WorkingTreeFormat4")
 
1471
    "breezy.bzr.workingtree_4", "WorkingTreeFormat4")
1473
1472
format_registry.register_lazy(b"Bazaar Working Tree Format 5 (bzr 1.11)\n",
1474
 
                              "breezy.bzr.workingtree_4", "WorkingTreeFormat5")
 
1473
    "breezy.bzr.workingtree_4", "WorkingTreeFormat5")
1475
1474
format_registry.register_lazy(b"Bazaar Working Tree Format 6 (bzr 1.14)\n",
1476
 
                              "breezy.bzr.workingtree_4", "WorkingTreeFormat6")
 
1475
    "breezy.bzr.workingtree_4", "WorkingTreeFormat6")
1477
1476
format_registry.register_lazy(b"Bazaar-NG Working Tree format 3",
1478
 
                              "breezy.bzr.workingtree_3", "WorkingTreeFormat3")
 
1477
    "breezy.bzr.workingtree_3", "WorkingTreeFormat3")
1479
1478
format_registry.set_default_key(b"Bazaar Working Tree Format 6 (bzr 1.14)\n")