/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
1
# Copyright (C) 2005-2010 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
17
"""Weave-era working tree objects."""
18
6379.6.3 by Jelmer Vernooij
Use absolute_import.
19
from __future__ import absolute_import
20
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
21
from ... import (
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
22
    conflicts as _mod_conflicts,
23
    errors,
24
    inventory,
25
    osutils,
26
    revision as _mod_revision,
27
    transform,
28
    xml5,
29
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
30
from ...decorators import needs_read_lock
31
from ...mutabletree import MutableTree
32
from ...sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
33
    BytesIO,
34
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
35
from ...transport.local import LocalTransport
36
from ...workingtree import (
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
37
    WorkingTreeFormat,
38
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from ...workingtree_3 import (
6110.4.4 by Jelmer Vernooij
Add common base class.
40
    PreDirStateWorkingTree,
41
    )
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
42
43
44
def get_conflicted_stem(path):
45
    for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
46
        if path.endswith(suffix):
47
            return path[:-len(suffix)]
48
49
50
class WorkingTreeFormat2(WorkingTreeFormat):
51
    """The second working tree format.
52
53
    This format modified the hash cache from the format 1 hash cache.
54
    """
55
56
    upgrade_recommended = True
57
58
    requires_normalized_unicode_filenames = True
59
60
    case_sensitive_filename = "Branch-FoRMaT"
61
62
    missing_parent_conflicts = False
63
5993.3.1 by Jelmer Vernooij
Add WorkingTreeFormat.supports_versioned_directories attribute.
64
    supports_versioned_directories = True
65
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
66
    def get_format_description(self):
67
        """See WorkingTreeFormat.get_format_description()."""
68
        return "Working tree format 2"
69
70
    def _stub_initialize_on_transport(self, transport, file_mode):
71
        """Workaround: create control files for a remote working tree.
72
73
        This ensures that it can later be updated and dealt with locally,
74
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
75
        no working tree.  (See bug #43064).
76
        """
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
77
        sio = BytesIO()
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
78
        inv = inventory.Inventory()
79
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
80
        sio.seek(0)
81
        transport.put_file('inventory', sio, file_mode)
82
        transport.put_bytes('pending-merges', '', file_mode)
83
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
84
    def initialize(self, a_controldir, revision_id=None, from_branch=None,
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
85
                   accelerator_tree=None, hardlink=False):
86
        """See WorkingTreeFormat.initialize()."""
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
87
        if not isinstance(a_controldir.transport, LocalTransport):
88
            raise errors.NotLocalUrl(a_controldir.transport.base)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
89
        if from_branch is not None:
90
            branch = from_branch
91
        else:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
92
            branch = a_controldir.open_branch()
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
93
        if revision_id is None:
94
            revision_id = _mod_revision.ensure_null(branch.last_revision())
95
        branch.lock_write()
96
        try:
97
            branch.generate_revision_history(revision_id)
98
        finally:
99
            branch.unlock()
100
        inv = inventory.Inventory()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
101
        wt = WorkingTree2(a_controldir.root_transport.local_abspath('.'),
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
102
                         branch,
103
                         inv,
104
                         _internal=True,
105
                         _format=self,
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
106
                         _bzrdir=a_controldir,
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
107
                         _control_files=branch.control_files)
108
        basis_tree = branch.repository.revision_tree(revision_id)
6405.2.6 by Jelmer Vernooij
Lots of test fixes.
109
        if basis_tree.get_root_id() is not None:
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
110
            wt.set_root_id(basis_tree.get_root_id())
111
        # set the parent list and cache the basis tree.
112
        if _mod_revision.is_null(revision_id):
113
            parent_trees = []
114
        else:
115
            parent_trees = [(revision_id, basis_tree)]
116
        wt.set_parent_trees(parent_trees)
117
        transform.build_tree(basis_tree, wt)
6435.1.1 by Jelmer Vernooij
Add post_build_tree hook.
118
        for hook in MutableTree.hooks['post_build_tree']:
119
            hook(wt)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
120
        return wt
121
122
    def __init__(self):
123
        super(WorkingTreeFormat2, self).__init__()
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
124
        from breezy.plugins.weave_fmt.bzrdir import BzrDirFormat6
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
125
        self._matchingbzrdir = BzrDirFormat6()
126
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
127
    def open(self, a_controldir, _found=False):
128
        """Return the WorkingTree object for a_controldir
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
129
130
        _found is a private parameter, do not use it. It is used to indicate
131
               if format probing has already been done.
132
        """
133
        if not _found:
134
            # we are being called directly and must probe.
135
            raise NotImplementedError
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
136
        if not isinstance(a_controldir.transport, LocalTransport):
137
            raise errors.NotLocalUrl(a_controldir.transport.base)
138
        wt = WorkingTree2(a_controldir.root_transport.local_abspath('.'),
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
139
                           _internal=True,
140
                           _format=self,
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
141
                           _bzrdir=a_controldir,
142
                           _control_files=a_controldir.open_branch().control_files)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
143
        return wt
144
145
6110.4.4 by Jelmer Vernooij
Add common base class.
146
class WorkingTree2(PreDirStateWorkingTree):
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
147
    """This is the Format 2 working tree.
148
149
    This was the first weave based working tree.
150
     - uses os locks for locking.
151
     - uses the branch last-revision.
152
    """
153
6110.4.2 by Jelmer Vernooij
Move hashcache use to bzrlib.workingtree_3 and bzrlib.plugins.weave_fmt.workingtree.
154
    def __init__(self, basedir, *args, **kwargs):
155
        super(WorkingTree2, self).__init__(basedir, *args, **kwargs)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
156
        # WorkingTree2 has more of a constraint that self._inventory must
157
        # exist. Because this is an older format, we don't mind the overhead
158
        # caused by the extra computation here.
159
160
        # Newer WorkingTree's should only have self._inventory set when they
161
        # have a read lock.
162
        if self._inventory is None:
163
            self.read_working_inventory()
164
165
    def _get_check_refs(self):
166
        """Return the references needed to perform a check of this tree."""
167
        return [('trees', self.last_revision())]
168
6110.4.2 by Jelmer Vernooij
Move hashcache use to bzrlib.workingtree_3 and bzrlib.plugins.weave_fmt.workingtree.
169
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
170
    def lock_tree_write(self):
171
        """See WorkingTree.lock_tree_write().
172
173
        In Format2 WorkingTrees we have a single lock for the branch and tree
174
        so lock_tree_write() degrades to lock_write().
175
176
        :return: An object with an unlock method which will release the lock
177
            obtained.
178
        """
179
        self.branch.lock_write()
180
        try:
181
            self._control_files.lock_write()
182
            return self
183
        except:
184
            self.branch.unlock()
185
            raise
186
187
    def unlock(self):
188
        # we share control files:
189
        if self._control_files._lock_count == 3:
5900.1.2 by Jelmer Vernooij
Fix weave plugin.
190
            # do non-implementation specific cleanup
191
            self._cleanup()
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
192
            # _inventory_is_modified is always False during a read lock.
193
            if self._inventory_is_modified:
194
                self.flush()
195
            self._write_hashcache_if_dirty()
196
197
        # reverse order of locking.
198
        try:
199
            return self._control_files.unlock()
200
        finally:
201
            self.branch.unlock()
202
203
    def _iter_conflicts(self):
204
        conflicted = set()
205
        for info in self.list_files():
206
            path = info[0]
207
            stem = get_conflicted_stem(path)
208
            if stem is None:
209
                continue
210
            if stem not in conflicted:
211
                conflicted.add(stem)
212
                yield stem
213
214
    @needs_read_lock
215
    def conflicts(self):
216
        conflicts = _mod_conflicts.ConflictList()
217
        for conflicted in self._iter_conflicts():
218
            text = True
219
            try:
220
                if osutils.file_kind(self.abspath(conflicted)) != "file":
221
                    text = False
222
            except errors.NoSuchFile:
223
                text = False
224
            if text is True:
225
                for suffix in ('.THIS', '.OTHER'):
226
                    try:
227
                        kind = osutils.file_kind(self.abspath(conflicted+suffix))
228
                        if kind != "file":
229
                            text = False
230
                    except errors.NoSuchFile:
231
                        text = False
232
                    if text == False:
233
                        break
234
            ctype = {True: 'text conflict', False: 'contents conflict'}[text]
235
            conflicts.append(_mod_conflicts.Conflict.factory(ctype,
236
                             path=conflicted,
237
                             file_id=self.path2id(conflicted)))
238
        return conflicts
239
5816.5.5 by Jelmer Vernooij
Fix conflict handling for wt2.
240
    def set_conflicts(self, arg):
241
        raise errors.UnsupportedOperation(self.set_conflicts, self)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
242
5816.5.5 by Jelmer Vernooij
Fix conflict handling for wt2.
243
    def add_conflicts(self, arg):
244
        raise errors.UnsupportedOperation(self.add_conflicts, self)