/usr/lib/python2.7/dist-packages/bzrlib/workingtree_3.py is in python-bzrlib 2.7.0-2ubuntu3.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | # Copyright (C) 2007-2011 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""WorkingTree3 format and implementation.
"""
from __future__ import absolute_import
import errno
from bzrlib import (
bzrdir,
errors,
hashcache,
inventory,
revision as _mod_revision,
trace,
transform,
)
from bzrlib.decorators import (
needs_read_lock,
)
from bzrlib.lockable_files import LockableFiles
from bzrlib.lockdir import LockDir
from bzrlib.mutabletree import MutableTree
from bzrlib.transport.local import LocalTransport
from bzrlib.workingtree import (
InventoryWorkingTree,
WorkingTreeFormatMetaDir,
)
class PreDirStateWorkingTree(InventoryWorkingTree):
def __init__(self, basedir='.', *args, **kwargs):
super(PreDirStateWorkingTree, self).__init__(basedir, *args, **kwargs)
# update the whole cache up front and write to disk if anything changed;
# in the future we might want to do this more selectively
# two possible ways offer themselves : in self._unlock, write the cache
# if needed, or, when the cache sees a change, append it to the hash
# cache file, and have the parser take the most recent entry for a
# given path only.
wt_trans = self.bzrdir.get_workingtree_transport(None)
cache_filename = wt_trans.local_abspath('stat-cache')
self._hashcache = hashcache.HashCache(basedir, cache_filename,
self.bzrdir._get_file_mode(),
self._content_filter_stack_provider())
hc = self._hashcache
hc.read()
# is this scan needed ? it makes things kinda slow.
#hc.scan()
if hc.needs_write:
trace.mutter("write hc")
hc.write()
def _write_hashcache_if_dirty(self):
"""Write out the hashcache if it is dirty."""
if self._hashcache.needs_write:
try:
self._hashcache.write()
except OSError, e:
if e.errno not in (errno.EPERM, errno.EACCES):
raise
# TODO: jam 20061219 Should this be a warning? A single line
# warning might be sufficient to let the user know what
# is going on.
trace.mutter('Could not write hashcache for %s\nError: %s',
self._hashcache.cache_file_name(), e)
@needs_read_lock
def get_file_sha1(self, file_id, path=None, stat_value=None):
if not path:
path = self._inventory.id2path(file_id)
return self._hashcache.get_sha1(path, stat_value)
class WorkingTree3(PreDirStateWorkingTree):
"""This is the Format 3 working tree.
This differs from the base WorkingTree by:
- having its own file lock
- having its own last-revision property.
This is new in bzr 0.8
"""
@needs_read_lock
def _last_revision(self):
"""See Mutable.last_revision."""
try:
return self._transport.get_bytes('last-revision')
except errors.NoSuchFile:
return _mod_revision.NULL_REVISION
def _change_last_revision(self, revision_id):
"""See WorkingTree._change_last_revision."""
if revision_id is None or revision_id == _mod_revision.NULL_REVISION:
try:
self._transport.delete('last-revision')
except errors.NoSuchFile:
pass
return False
else:
self._transport.put_bytes('last-revision', revision_id,
mode=self.bzrdir._get_file_mode())
return True
def _get_check_refs(self):
"""Return the references needed to perform a check of this tree."""
return [('trees', self.last_revision())]
def unlock(self):
if self._control_files._lock_count == 1:
# do non-implementation specific cleanup
self._cleanup()
# _inventory_is_modified is always False during a read lock.
if self._inventory_is_modified:
self.flush()
self._write_hashcache_if_dirty()
# reverse order of locking.
try:
return self._control_files.unlock()
finally:
self.branch.unlock()
class WorkingTreeFormat3(WorkingTreeFormatMetaDir):
"""The second working tree format updated to record a format marker.
This format:
- exists within a metadir controlling .bzr
- includes an explicit version marker for the workingtree control
files, separate from the ControlDir format
- modifies the hash cache format
- is new in bzr 0.8
- uses a LockDir to guard access for writes.
"""
upgrade_recommended = True
missing_parent_conflicts = True
supports_versioned_directories = True
@classmethod
def get_format_string(cls):
"""See WorkingTreeFormat.get_format_string()."""
return "Bazaar-NG Working Tree format 3"
def get_format_description(self):
"""See WorkingTreeFormat.get_format_description()."""
return "Working tree format 3"
_tree_class = WorkingTree3
def __get_matchingbzrdir(self):
return bzrdir.BzrDirMetaFormat1()
_matchingbzrdir = property(__get_matchingbzrdir)
def _open_control_files(self, a_bzrdir):
transport = a_bzrdir.get_workingtree_transport(None)
return LockableFiles(transport, 'lock', LockDir)
def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
accelerator_tree=None, hardlink=False):
"""See WorkingTreeFormat.initialize().
:param revision_id: if supplied, create a working tree at a different
revision than the branch is at.
:param accelerator_tree: A tree which can be used for retrieving file
contents more quickly than the revision tree, i.e. a workingtree.
The revision tree will be used for cases where accelerator_tree's
content is different.
:param hardlink: If true, hard-link files from accelerator_tree,
where possible.
"""
if not isinstance(a_bzrdir.transport, LocalTransport):
raise errors.NotLocalUrl(a_bzrdir.transport.base)
transport = a_bzrdir.get_workingtree_transport(self)
control_files = self._open_control_files(a_bzrdir)
control_files.create_lock()
control_files.lock_write()
transport.put_bytes('format', self.as_string(),
mode=a_bzrdir._get_file_mode())
if from_branch is not None:
branch = from_branch
else:
branch = a_bzrdir.open_branch()
if revision_id is None:
revision_id = _mod_revision.ensure_null(branch.last_revision())
# WorkingTree3 can handle an inventory which has a unique root id.
# as of bzr 0.12. However, bzr 0.11 and earlier fail to handle
# those trees. And because there isn't a format bump inbetween, we
# are maintaining compatibility with older clients.
# inv = Inventory(root_id=gen_root_id())
inv = self._initial_inventory()
wt = self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
branch,
inv,
_internal=True,
_format=self,
_bzrdir=a_bzrdir,
_control_files=control_files)
wt.lock_tree_write()
try:
basis_tree = branch.repository.revision_tree(revision_id)
# only set an explicit root id if there is one to set.
if basis_tree.get_root_id() is not None:
wt.set_root_id(basis_tree.get_root_id())
if revision_id == _mod_revision.NULL_REVISION:
wt.set_parent_trees([])
else:
wt.set_parent_trees([(revision_id, basis_tree)])
transform.build_tree(basis_tree, wt)
for hook in MutableTree.hooks['post_build_tree']:
hook(wt)
finally:
# Unlock in this order so that the unlock-triggers-flush in
# WorkingTree is given a chance to fire.
control_files.unlock()
wt.unlock()
return wt
def _initial_inventory(self):
return inventory.Inventory()
def open(self, a_bzrdir, _found=False):
"""Return the WorkingTree object for a_bzrdir
_found is a private parameter, do not use it. It is used to indicate
if format probing has already been done.
"""
if not _found:
# we are being called directly and must probe.
raise NotImplementedError
if not isinstance(a_bzrdir.transport, LocalTransport):
raise errors.NotLocalUrl(a_bzrdir.transport.base)
wt = self._open(a_bzrdir, self._open_control_files(a_bzrdir))
return wt
def _open(self, a_bzrdir, control_files):
"""Open the tree itself.
:param a_bzrdir: the dir for the tree.
:param control_files: the control files for the tree.
"""
return self._tree_class(a_bzrdir.root_transport.local_abspath('.'),
_internal=True,
_format=self,
_bzrdir=a_bzrdir,
_control_files=control_files)
|