~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2011-03-03 11:32:03 UTC
  • mto: This revision was merged to the branch mainline in revision 5698.
  • Revision ID: jelmer@samba.org-20110303113203-vwsuztoorxn5dul8
Move WorkingTreeFormat2 to a separate file.

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
2764
class WorkingTreeFormatRegistry(controldir.ControlComponentFormatRegistry):
2863
2765
    """Registry for working tree formats."""
2864
2766
 
3011
2913
        format_registry.remove(format)
3012
2914
 
3013
2915
 
3014
 
class WorkingTreeFormat2(WorkingTreeFormat):
3015
 
    """The second working tree format.
3016
 
 
3017
 
    This format modified the hash cache from the format 1 hash cache.
3018
 
    """
3019
 
 
3020
 
    upgrade_recommended = True
3021
 
 
3022
 
    requires_normalized_unicode_filenames = True
3023
 
 
3024
 
    case_sensitive_filename = "Branch-FoRMaT"
3025
 
 
3026
 
    missing_parent_conflicts = False
3027
 
 
3028
 
    def get_format_description(self):
3029
 
        """See WorkingTreeFormat.get_format_description()."""
3030
 
        return "Working tree format 2"
3031
 
 
3032
 
    def _stub_initialize_on_transport(self, transport, file_mode):
3033
 
        """Workaround: create control files for a remote working tree.
3034
 
 
3035
 
        This ensures that it can later be updated and dealt with locally,
3036
 
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
3037
 
        no working tree.  (See bug #43064).
3038
 
        """
3039
 
        sio = StringIO()
3040
 
        inv = inventory.Inventory()
3041
 
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
3042
 
        sio.seek(0)
3043
 
        transport.put_file('inventory', sio, file_mode)
3044
 
        transport.put_bytes('pending-merges', '', file_mode)
3045
 
 
3046
 
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
3047
 
                   accelerator_tree=None, hardlink=False):
3048
 
        """See WorkingTreeFormat.initialize()."""
3049
 
        if not isinstance(a_bzrdir.transport, LocalTransport):
3050
 
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
3051
 
        if from_branch is not None:
3052
 
            branch = from_branch
3053
 
        else:
3054
 
            branch = a_bzrdir.open_branch()
3055
 
        if revision_id is None:
3056
 
            revision_id = _mod_revision.ensure_null(branch.last_revision())
3057
 
        branch.lock_write()
3058
 
        try:
3059
 
            branch.generate_revision_history(revision_id)
3060
 
        finally:
3061
 
            branch.unlock()
3062
 
        inv = inventory.Inventory()
3063
 
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
3064
 
                         branch,
3065
 
                         inv,
3066
 
                         _internal=True,
3067
 
                         _format=self,
3068
 
                         _bzrdir=a_bzrdir,
3069
 
                         _control_files=branch.control_files)
3070
 
        basis_tree = branch.repository.revision_tree(revision_id)
3071
 
        if basis_tree.inventory.root is not None:
3072
 
            wt.set_root_id(basis_tree.get_root_id())
3073
 
        # set the parent list and cache the basis tree.
3074
 
        if _mod_revision.is_null(revision_id):
3075
 
            parent_trees = []
3076
 
        else:
3077
 
            parent_trees = [(revision_id, basis_tree)]
3078
 
        wt.set_parent_trees(parent_trees)
3079
 
        transform.build_tree(basis_tree, wt)
3080
 
        return wt
3081
 
 
3082
 
    def __init__(self):
3083
 
        super(WorkingTreeFormat2, self).__init__()
3084
 
        self._matchingbzrdir = bzrdir.BzrDirFormat6()
3085
 
 
3086
 
    def open(self, a_bzrdir, _found=False):
3087
 
        """Return the WorkingTree object for a_bzrdir
3088
 
 
3089
 
        _found is a private parameter, do not use it. It is used to indicate
3090
 
               if format probing has already been done.
3091
 
        """
3092
 
        if not _found:
3093
 
            # we are being called directly and must probe.
3094
 
            raise NotImplementedError
3095
 
        if not isinstance(a_bzrdir.transport, LocalTransport):
3096
 
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
3097
 
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
3098
 
                           _internal=True,
3099
 
                           _format=self,
3100
 
                           _bzrdir=a_bzrdir,
3101
 
                           _control_files=a_bzrdir.open_branch().control_files)
3102
 
        return wt
3103
 
 
3104
2916
class WorkingTreeFormat3(WorkingTreeFormat):
3105
2917
    """The second working tree format updated to record a format marker.
3106
2918
 
3246
3058
# Register extra formats which have no format string are not discoverable
3247
3059
# and not independently creatable. They are implicitly created as part of
3248
3060
# e.g. older Bazaar formats or foreign formats.
3249
 
format_registry.register_extra(WorkingTreeFormat2())
 
3061
format_registry.register_extra_lazy("bzrlib.workingtree_2",
 
3062
    "WorkingTreeFormat2")