/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
17
"""Weave-era working tree objects."""
18
19
from cStringIO import StringIO
20
21
from bzrlib import (
22
    conflicts as _mod_conflicts,
23
    errors,
24
    inventory,
25
    osutils,
26
    revision as _mod_revision,
27
    transform,
28
    xml5,
29
    )
30
from bzrlib.decorators import needs_read_lock
31
from bzrlib.transport.local import LocalTransport
32
from bzrlib.workingtree import (
5777.5.2 by Jelmer Vernooij
Split inventory-specific methods and WorkingTree interface method
33
    InventoryWorkingTree,
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
34
    WorkingTreeFormat,
35
    )
36
37
38
def get_conflicted_stem(path):
39
    for suffix in _mod_conflicts.CONFLICT_SUFFIXES:
40
        if path.endswith(suffix):
41
            return path[:-len(suffix)]
42
43
44
class WorkingTreeFormat2(WorkingTreeFormat):
45
    """The second working tree format.
46
47
    This format modified the hash cache from the format 1 hash cache.
48
    """
49
50
    upgrade_recommended = True
51
52
    requires_normalized_unicode_filenames = True
53
54
    case_sensitive_filename = "Branch-FoRMaT"
55
56
    missing_parent_conflicts = False
57
5993.3.1 by Jelmer Vernooij
Add WorkingTreeFormat.supports_versioned_directories attribute.
58
    supports_versioned_directories = True
59
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
60
    def get_format_description(self):
61
        """See WorkingTreeFormat.get_format_description()."""
62
        return "Working tree format 2"
63
64
    def _stub_initialize_on_transport(self, transport, file_mode):
65
        """Workaround: create control files for a remote working tree.
66
67
        This ensures that it can later be updated and dealt with locally,
68
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
69
        no working tree.  (See bug #43064).
70
        """
71
        sio = StringIO()
72
        inv = inventory.Inventory()
73
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
74
        sio.seek(0)
75
        transport.put_file('inventory', sio, file_mode)
76
        transport.put_bytes('pending-merges', '', file_mode)
77
78
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
79
                   accelerator_tree=None, hardlink=False):
80
        """See WorkingTreeFormat.initialize()."""
81
        if not isinstance(a_bzrdir.transport, LocalTransport):
82
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
83
        if from_branch is not None:
84
            branch = from_branch
85
        else:
86
            branch = a_bzrdir.open_branch()
87
        if revision_id is None:
88
            revision_id = _mod_revision.ensure_null(branch.last_revision())
89
        branch.lock_write()
90
        try:
91
            branch.generate_revision_history(revision_id)
92
        finally:
93
            branch.unlock()
94
        inv = inventory.Inventory()
95
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
96
                         branch,
97
                         inv,
98
                         _internal=True,
99
                         _format=self,
100
                         _bzrdir=a_bzrdir,
101
                         _control_files=branch.control_files)
102
        basis_tree = branch.repository.revision_tree(revision_id)
103
        if basis_tree.inventory.root is not None:
104
            wt.set_root_id(basis_tree.get_root_id())
105
        # set the parent list and cache the basis tree.
106
        if _mod_revision.is_null(revision_id):
107
            parent_trees = []
108
        else:
109
            parent_trees = [(revision_id, basis_tree)]
110
        wt.set_parent_trees(parent_trees)
111
        transform.build_tree(basis_tree, wt)
112
        return wt
113
114
    def __init__(self):
115
        super(WorkingTreeFormat2, self).__init__()
5582.12.6 by Jelmer Vernooij
merge bzr.dev.
116
        from bzrlib.plugins.weave_fmt.bzrdir import BzrDirFormat6
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
117
        self._matchingbzrdir = BzrDirFormat6()
118
119
    def open(self, a_bzrdir, _found=False):
120
        """Return the WorkingTree object for a_bzrdir
121
122
        _found is a private parameter, do not use it. It is used to indicate
123
               if format probing has already been done.
124
        """
125
        if not _found:
126
            # we are being called directly and must probe.
127
            raise NotImplementedError
128
        if not isinstance(a_bzrdir.transport, LocalTransport):
129
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
130
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
131
                           _internal=True,
132
                           _format=self,
133
                           _bzrdir=a_bzrdir,
134
                           _control_files=a_bzrdir.open_branch().control_files)
135
        return wt
136
137
5777.5.2 by Jelmer Vernooij
Split inventory-specific methods and WorkingTree interface method
138
class WorkingTree2(InventoryWorkingTree):
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
139
    """This is the Format 2 working tree.
140
141
    This was the first weave based working tree.
142
     - uses os locks for locking.
143
     - uses the branch last-revision.
144
    """
145
146
    def __init__(self, *args, **kwargs):
147
        super(WorkingTree2, self).__init__(*args, **kwargs)
148
        # WorkingTree2 has more of a constraint that self._inventory must
149
        # exist. Because this is an older format, we don't mind the overhead
150
        # caused by the extra computation here.
151
152
        # Newer WorkingTree's should only have self._inventory set when they
153
        # have a read lock.
154
        if self._inventory is None:
155
            self.read_working_inventory()
156
157
    def _get_check_refs(self):
158
        """Return the references needed to perform a check of this tree."""
159
        return [('trees', self.last_revision())]
160
161
    def lock_tree_write(self):
162
        """See WorkingTree.lock_tree_write().
163
164
        In Format2 WorkingTrees we have a single lock for the branch and tree
165
        so lock_tree_write() degrades to lock_write().
166
167
        :return: An object with an unlock method which will release the lock
168
            obtained.
169
        """
170
        self.branch.lock_write()
171
        try:
172
            self._control_files.lock_write()
173
            return self
174
        except:
175
            self.branch.unlock()
176
            raise
177
178
    def unlock(self):
179
        # we share control files:
180
        if self._control_files._lock_count == 3:
5900.1.2 by Jelmer Vernooij
Fix weave plugin.
181
            # do non-implementation specific cleanup
182
            self._cleanup()
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
183
            # _inventory_is_modified is always False during a read lock.
184
            if self._inventory_is_modified:
185
                self.flush()
186
            self._write_hashcache_if_dirty()
187
188
        # reverse order of locking.
189
        try:
190
            return self._control_files.unlock()
191
        finally:
192
            self.branch.unlock()
193
194
    def _iter_conflicts(self):
195
        conflicted = set()
196
        for info in self.list_files():
197
            path = info[0]
198
            stem = get_conflicted_stem(path)
199
            if stem is None:
200
                continue
201
            if stem not in conflicted:
202
                conflicted.add(stem)
203
                yield stem
204
205
    @needs_read_lock
206
    def conflicts(self):
207
        conflicts = _mod_conflicts.ConflictList()
208
        for conflicted in self._iter_conflicts():
209
            text = True
210
            try:
211
                if osutils.file_kind(self.abspath(conflicted)) != "file":
212
                    text = False
213
            except errors.NoSuchFile:
214
                text = False
215
            if text is True:
216
                for suffix in ('.THIS', '.OTHER'):
217
                    try:
218
                        kind = osutils.file_kind(self.abspath(conflicted+suffix))
219
                        if kind != "file":
220
                            text = False
221
                    except errors.NoSuchFile:
222
                        text = False
223
                    if text == False:
224
                        break
225
            ctype = {True: 'text conflict', False: 'contents conflict'}[text]
226
            conflicts.append(_mod_conflicts.Conflict.factory(ctype,
227
                             path=conflicted,
228
                             file_id=self.path2id(conflicted)))
229
        return conflicts
230
5816.5.5 by Jelmer Vernooij
Fix conflict handling for wt2.
231
    def set_conflicts(self, arg):
232
        raise errors.UnsupportedOperation(self.set_conflicts, self)
5697.1.1 by Jelmer Vernooij
Move WorkingTreeFormat2 to a separate file.
233
5816.5.5 by Jelmer Vernooij
Fix conflict handling for wt2.
234
    def add_conflicts(self, arg):
235
        raise errors.UnsupportedOperation(self.add_conflicts, self)