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

  • Committer: Jelmer Vernooij
  • Date: 2011-03-08 17:51:43 UTC
  • mfrom: (5684.2.5 per-repository-vf)
  • mto: This revision was merged to the branch mainline in revision 5710.
  • Revision ID: jelmer@samba.org-20110308175143-949n8c8lodfb4tvc
Merge per-repository-vf, move scenarios to test_check_reconcile.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1653
1653
            # - RBC 20060907
1654
1654
            self._write_inventory(self._inventory)
1655
1655
 
1656
 
    def _iter_conflicts(self):
1657
 
        conflicted = set()
1658
 
        for info in self.list_files():
1659
 
            path = info[0]
1660
 
            stem = get_conflicted_stem(path)
1661
 
            if stem is None:
1662
 
                continue
1663
 
            if stem not in conflicted:
1664
 
                conflicted.add(stem)
1665
 
                yield stem
1666
 
 
1667
1656
    @needs_write_lock
1668
1657
    def pull(self, source, overwrite=False, stop_revision=None,
1669
1658
             change_reporter=None, possible_transports=None, local=False,
2428
2417
    def add_conflicts(self, arg):
2429
2418
        raise errors.UnsupportedOperation(self.add_conflicts, self)
2430
2419
 
2431
 
    @needs_read_lock
2432
2420
    def conflicts(self):
2433
 
        conflicts = _mod_conflicts.ConflictList()
2434
 
        for conflicted in self._iter_conflicts():
2435
 
            text = True
2436
 
            try:
2437
 
                if file_kind(self.abspath(conflicted)) != "file":
2438
 
                    text = False
2439
 
            except errors.NoSuchFile:
2440
 
                text = False
2441
 
            if text is True:
2442
 
                for suffix in ('.THIS', '.OTHER'):
2443
 
                    try:
2444
 
                        kind = file_kind(self.abspath(conflicted+suffix))
2445
 
                        if kind != "file":
2446
 
                            text = False
2447
 
                    except errors.NoSuchFile:
2448
 
                        text = False
2449
 
                    if text == False:
2450
 
                        break
2451
 
            ctype = {True: 'text conflict', False: 'contents conflict'}[text]
2452
 
            conflicts.append(_mod_conflicts.Conflict.factory(ctype,
2453
 
                             path=conflicted,
2454
 
                             file_id=self.path2id(conflicted)))
2455
 
        return conflicts
 
2421
        raise NotImplementedError(self.conflicts)
2456
2422
 
2457
2423
    def walkdirs(self, prefix=""):
2458
2424
        """Walk the directories of this tree.
2717
2683
        return ShelfManager(self, self._transport)
2718
2684
 
2719
2685
 
2720
 
class WorkingTree2(WorkingTree):
2721
 
    """This is the Format 2 working tree.
2722
 
 
2723
 
    This was the first weave based working tree.
2724
 
     - uses os locks for locking.
2725
 
     - uses the branch last-revision.
2726
 
    """
2727
 
 
2728
 
    def __init__(self, *args, **kwargs):
2729
 
        super(WorkingTree2, self).__init__(*args, **kwargs)
2730
 
        # WorkingTree2 has more of a constraint that self._inventory must
2731
 
        # exist. Because this is an older format, we don't mind the overhead
2732
 
        # caused by the extra computation here.
2733
 
 
2734
 
        # Newer WorkingTree's should only have self._inventory set when they
2735
 
        # have a read lock.
2736
 
        if self._inventory is None:
2737
 
            self.read_working_inventory()
2738
 
 
2739
 
    def _get_check_refs(self):
2740
 
        """Return the references needed to perform a check of this tree."""
2741
 
        return [('trees', self.last_revision())]
2742
 
 
2743
 
    def lock_tree_write(self):
2744
 
        """See WorkingTree.lock_tree_write().
2745
 
 
2746
 
        In Format2 WorkingTrees we have a single lock for the branch and tree
2747
 
        so lock_tree_write() degrades to lock_write().
2748
 
 
2749
 
        :return: An object with an unlock method which will release the lock
2750
 
            obtained.
2751
 
        """
2752
 
        self.branch.lock_write()
2753
 
        try:
2754
 
            self._control_files.lock_write()
2755
 
            return self
2756
 
        except:
2757
 
            self.branch.unlock()
2758
 
            raise
2759
 
 
2760
 
    def unlock(self):
2761
 
        # do non-implementation specific cleanup
2762
 
        self._cleanup()
2763
 
 
2764
 
        # we share control files:
2765
 
        if self._control_files._lock_count == 3:
2766
 
            # _inventory_is_modified is always False during a read lock.
2767
 
            if self._inventory_is_modified:
2768
 
                self.flush()
2769
 
            self._write_hashcache_if_dirty()
2770
 
 
2771
 
        # reverse order of locking.
2772
 
        try:
2773
 
            return self._control_files.unlock()
2774
 
        finally:
2775
 
            self.branch.unlock()
2776
 
 
2777
 
 
2778
2686
class WorkingTree3(WorkingTree):
2779
2687
    """This is the Format 3 working tree.
2780
2688
 
2853
2761
            self.branch.unlock()
2854
2762
 
2855
2763
 
2856
 
def get_conflicted_stem(path):
2857
 
    for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
2858
 
        if path.endswith(suffix):
2859
 
            return path[:-len(suffix)]
2860
 
 
2861
 
 
2862
 
class WorkingTreeFormatRegistry(registry.FormatRegistry):
 
2764
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2863
2765
    """Registry for working tree formats."""
2864
2766
 
2865
2767
    def __init__(self, other_registry=None):
2866
2768
        super(WorkingTreeFormatRegistry, self).__init__(other_registry)
2867
 
        self._extra_formats = []
2868
2769
        self._default_format = None
2869
2770
 
2870
 
    def register(self, format):
2871
 
        """Register a new repository format."""
2872
 
        super(WorkingTreeFormatRegistry, self).register(
2873
 
            format.get_format_string(), format)
2874
 
 
2875
 
    def remove(self, format):
2876
 
        """Remove a registered repository format."""
2877
 
        super(WorkingTreeFormatRegistry, self).remove(format.get_format_string())
2878
 
 
2879
 
    def register_extra(self, format):
2880
 
        """Register a repository format that can not be used in a metadir.
2881
 
 
2882
 
        This is mainly useful to allow custom repository formats, such as older
2883
 
        Bazaar formats and foreign formats, to be tested.
2884
 
        """
2885
 
        self._extra_formats.append(registry._ObjectGetter(format))
2886
 
 
2887
 
    def remove_extra(self, format):
2888
 
        """Remove an extra repository format.
2889
 
        """
2890
 
        self._extra_formats.remove(registry._ObjectGetter(format))
2891
 
 
2892
 
    def register_extra_lazy(self, module_name, member_name):
2893
 
        """Register a repository format lazily.
2894
 
        """
2895
 
        self._extra_formats.append(
2896
 
            registry._LazyObjectGetter(module_name, member_name))
2897
 
 
2898
2771
    def get_default(self):
2899
2772
        """Return the current default format."""
2900
2773
        return self._default_format
2902
2775
    def set_default(self, format):
2903
2776
        self._default_format = format
2904
2777
 
2905
 
    def _get_extra(self):
2906
 
        result = []
2907
 
        for getter in self._extra_formats:
2908
 
            f = getter.get_obj()
2909
 
            if callable(f):
2910
 
                f = f()
2911
 
            result.append(f)
2912
 
        return result
2913
 
 
2914
 
    def _get_all(self):
2915
 
        """Return all repository formats, even those not usable in metadirs.
2916
 
        """
2917
 
        return [self.get(k) for k in self.keys()] + self._get_extra()
2918
 
 
2919
2778
 
2920
2779
format_registry = WorkingTreeFormatRegistry()
2921
2780
 
2922
2781
 
2923
 
class WorkingTreeFormat(object):
 
2782
class WorkingTreeFormat(controldir.ControlComponentFormat):
2924
2783
    """An encapsulation of the initialization and open routines for a format.
2925
2784
 
2926
2785
    Formats provide three things:
2962
2821
            raise errors.UnknownFormatError(format=format_string,
2963
2822
                                            kind="working tree")
2964
2823
 
 
2824
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
 
2825
                   accelerator_tree=None, hardlink=False):
 
2826
        """Initialize a new working tree in a_bzrdir.
 
2827
 
 
2828
        :param a_bzrdir: BzrDir to initialize the working tree in.
 
2829
        :param revision_id: allows creating a working tree at a different
 
2830
            revision than the branch is at.
 
2831
        :param from_branch: Branch to checkout
 
2832
        :param accelerator_tree: A tree which can be used for retrieving file
 
2833
            contents more quickly than the revision tree, i.e. a workingtree.
 
2834
            The revision tree will be used for cases where accelerator_tree's
 
2835
            content is different.
 
2836
        :param hardlink: If true, hard-link files from accelerator_tree,
 
2837
            where possible.
 
2838
        """
 
2839
        raise NotImplementedError(self.initialize)
 
2840
 
2965
2841
    def __eq__(self, other):
2966
2842
        return self.__class__ is other.__class__
2967
2843
 
3037
2913
        format_registry.remove(format)
3038
2914
 
3039
2915
 
3040
 
class WorkingTreeFormat2(WorkingTreeFormat):
3041
 
    """The second working tree format.
3042
 
 
3043
 
    This format modified the hash cache from the format 1 hash cache.
3044
 
    """
3045
 
 
3046
 
    upgrade_recommended = True
3047
 
 
3048
 
    requires_normalized_unicode_filenames = True
3049
 
 
3050
 
    case_sensitive_filename = "Branch-FoRMaT"
3051
 
 
3052
 
    missing_parent_conflicts = False
3053
 
 
3054
 
    def get_format_description(self):
3055
 
        """See WorkingTreeFormat.get_format_description()."""
3056
 
        return "Working tree format 2"
3057
 
 
3058
 
    def _stub_initialize_on_transport(self, transport, file_mode):
3059
 
        """Workaround: create control files for a remote working tree.
3060
 
 
3061
 
        This ensures that it can later be updated and dealt with locally,
3062
 
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
3063
 
        no working tree.  (See bug #43064).
3064
 
        """
3065
 
        sio = StringIO()
3066
 
        inv = inventory.Inventory()
3067
 
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
3068
 
        sio.seek(0)
3069
 
        transport.put_file('inventory', sio, file_mode)
3070
 
        transport.put_bytes('pending-merges', '', file_mode)
3071
 
 
3072
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
3073
 
                   accelerator_tree=None, hardlink=False):
3074
 
        """See WorkingTreeFormat.initialize()."""
3075
 
        if not isinstance(a_bzrdir.transport, LocalTransport):
3076
 
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
3077
 
        if from_branch is not None:
3078
 
            branch = from_branch
3079
 
        else:
3080
 
            branch = a_bzrdir.open_branch()
3081
 
        if revision_id is None:
3082
 
            revision_id = _mod_revision.ensure_null(branch.last_revision())
3083
 
        branch.lock_write()
3084
 
        try:
3085
 
            branch.generate_revision_history(revision_id)
3086
 
        finally:
3087
 
            branch.unlock()
3088
 
        inv = inventory.Inventory()
3089
 
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
3090
 
                         branch,
3091
 
                         inv,
3092
 
                         _internal=True,
3093
 
                         _format=self,
3094
 
                         _bzrdir=a_bzrdir,
3095
 
                         _control_files=branch.control_files)
3096
 
        basis_tree = branch.repository.revision_tree(revision_id)
3097
 
        if basis_tree.inventory.root is not None:
3098
 
            wt.set_root_id(basis_tree.get_root_id())
3099
 
        # set the parent list and cache the basis tree.
3100
 
        if _mod_revision.is_null(revision_id):
3101
 
            parent_trees = []
3102
 
        else:
3103
 
            parent_trees = [(revision_id, basis_tree)]
3104
 
        wt.set_parent_trees(parent_trees)
3105
 
        transform.build_tree(basis_tree, wt)
3106
 
        return wt
3107
 
 
3108
 
    def __init__(self):
3109
 
        super(WorkingTreeFormat2, self).__init__()
3110
 
        self._matchingbzrdir = bzrdir.BzrDirFormat6()
3111
 
 
3112
 
    def open(self, a_bzrdir, _found=False):
3113
 
        """Return the WorkingTree object for a_bzrdir
3114
 
 
3115
 
        _found is a private parameter, do not use it. It is used to indicate
3116
 
               if format probing has already been done.
3117
 
        """
3118
 
        if not _found:
3119
 
            # we are being called directly and must probe.
3120
 
            raise NotImplementedError
3121
 
        if not isinstance(a_bzrdir.transport, LocalTransport):
3122
 
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
3123
 
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
3124
 
                           _internal=True,
3125
 
                           _format=self,
3126
 
                           _bzrdir=a_bzrdir,
3127
 
                           _control_files=a_bzrdir.open_branch().control_files)
3128
 
        return wt
3129
 
 
3130
2916
class WorkingTreeFormat3(WorkingTreeFormat):
3131
2917
    """The second working tree format updated to record a format marker.
3132
2918
 
3272
3058
# Register extra formats which have no format string are not discoverable
3273
3059
# and not independently creatable. They are implicitly created as part of
3274
3060
# e.g. older Bazaar formats or foreign formats.
3275
 
format_registry.register_extra(WorkingTreeFormat2())
 
3061
format_registry.register_extra_lazy("bzrlib.workingtree_2",
 
3062
    "WorkingTreeFormat2")