1
# Copyright (C) 2005-2010 Canonical Ltd
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.
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.
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
17
"""Weave-era working tree objects."""
19
from cStringIO import StringIO
23
revision as _mod_revision,
26
from bzrlib.transport.local import LocalTransport
27
from bzrlib.workingtree import (
33
class WorkingTreeFormat2(WorkingTreeFormat):
34
"""The second working tree format.
36
This format modified the hash cache from the format 1 hash cache.
39
upgrade_recommended = True
41
def get_format_description(self):
42
"""See WorkingTreeFormat.get_format_description()."""
43
return "Working tree format 2"
45
def _stub_initialize_on_transport(self, transport, file_mode):
46
"""Workaround: create control files for a remote working tree.
48
This ensures that it can later be updated and dealt with locally,
49
since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
50
no working tree. (See bug #43064).
53
inv = inventory.Inventory()
54
xml5.serializer_v5.write_inventory(inv, sio, working=True)
56
transport.put_file('inventory', sio, file_mode)
57
transport.put_bytes('pending-merges', '', file_mode)
59
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
60
accelerator_tree=None, hardlink=False):
61
"""See WorkingTreeFormat.initialize()."""
62
if not isinstance(a_bzrdir.transport, LocalTransport):
63
raise errors.NotLocalUrl(a_bzrdir.transport.base)
64
if from_branch is not None:
67
branch = a_bzrdir.open_branch()
68
if revision_id is None:
69
revision_id = _mod_revision.ensure_null(branch.last_revision())
72
branch.generate_revision_history(revision_id)
75
inv = inventory.Inventory()
76
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
82
basis_tree = branch.repository.revision_tree(revision_id)
83
if basis_tree.inventory.root is not None:
84
wt.set_root_id(basis_tree.get_root_id())
85
# set the parent list and cache the basis tree.
86
if _mod_revision.is_null(revision_id):
89
parent_trees = [(revision_id, basis_tree)]
90
wt.set_parent_trees(parent_trees)
91
transform.build_tree(basis_tree, wt)
95
super(WorkingTreeFormat2, self).__init__()
96
from bzrlib.plugins.weave_fmt.bzrdir import BzrDirFormat6
97
self._matchingbzrdir = BzrDirFormat6()
99
def open(self, a_bzrdir, _found=False):
100
"""Return the WorkingTree object for a_bzrdir
102
_found is a private parameter, do not use it. It is used to indicate
103
if format probing has already been done.
106
# we are being called directly and must probe.
107
raise NotImplementedError
108
if not isinstance(a_bzrdir.transport, LocalTransport):
109
raise errors.NotLocalUrl(a_bzrdir.transport.base)
110
wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
117
class WorkingTree2(WorkingTree):
118
"""This is the Format 2 working tree.
120
This was the first weave based working tree.
121
- uses os locks for locking.
122
- uses the branch last-revision.
125
def __init__(self, *args, **kwargs):
126
super(WorkingTree2, self).__init__(*args, **kwargs)
127
# WorkingTree2 has more of a constraint that self._inventory must
128
# exist. Because this is an older format, we don't mind the overhead
129
# caused by the extra computation here.
131
# Newer WorkingTree's should only have self._inventory set when they
133
if self._inventory is None:
134
self.read_working_inventory()
136
def _get_check_refs(self):
137
"""Return the references needed to perform a check of this tree."""
138
return [('trees', self.last_revision())]
140
def lock_tree_write(self):
141
"""See WorkingTree.lock_tree_write().
143
In Format2 WorkingTrees we have a single lock for the branch and tree
144
so lock_tree_write() degrades to lock_write().
146
:return: An object with an unlock method which will release the lock
149
self.branch.lock_write()
151
self._control_files.lock_write()
158
# do non-implementation specific cleanup
161
# we share control files:
162
if self._control_files._lock_count == 3:
163
# _inventory_is_modified is always False during a read lock.
164
if self._inventory_is_modified:
166
self._write_hashcache_if_dirty()
168
# reverse order of locking.
170
return self._control_files.unlock()
177
# formats which have no format string are not discoverable
178
# and not independently creatable, so are not registered.
179
_legacy_formats = [WorkingTreeFormat2(),