/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
453 by Martin Pool
- Split WorkingTree into its own file
1
# Copyright (C) 2005 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
17
"""WorkingTree object and friends.
18
19
A WorkingTree represents the editable working copy of a branch.
20
Operations which represent the WorkingTree are also done here, 
21
such as renaming or adding files.  The WorkingTree has an inventory 
22
which is updated by these operations.  A commit produces a 
23
new revision based on the workingtree and its inventory.
24
25
At the moment every WorkingTree has its own branch.  Remote
26
WorkingTrees aren't supported.
27
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
28
To get a WorkingTree, call bzrdir.open_workingtree() or
29
WorkingTree.open(dir).
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
30
"""
31
32
956 by Martin Pool
doc
33
# FIXME: I don't know if writing out the cache from the destructor is really a
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
34
# good idea, because destructors are considered poor taste in Python, and it's
35
# not predictable when it will be written out.
36
37
# TODO: Give the workingtree sole responsibility for the working inventory;
38
# remove the variable and references to it from the branch.  This may require
39
# updating the commit code so as to update the inventory within the working
40
# copy, and making sure there's only one WorkingTree for any directory on disk.
41
# At the momenthey may alias the inventory and have old copies of it in memory.
956 by Martin Pool
doc
42
1508.1.8 by Robert Collins
move move() from Branch to WorkingTree.
43
from copy import deepcopy
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
44
from cStringIO import StringIO
45
import errno
46
import fnmatch
453 by Martin Pool
- Split WorkingTree into its own file
47
import os
1398 by Robert Collins
integrate in Gustavos x-bit patch
48
import stat
1457.1.1 by Robert Collins
rather than getting the branch inventory, WorkingTree can use the whole Branch, or make its own.
49
 
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
50
51
from bzrlib.atomicfile import AtomicFile
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
52
from bzrlib.branch import (Branch,
53
                           quotefn)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
54
import bzrlib.bzrdir as bzrdir
1534.4.28 by Robert Collins
first cut at merge from integration.
55
from bzrlib.decorators import needs_read_lock, needs_write_lock
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
56
import bzrlib.errors as errors
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
57
from bzrlib.errors import (BzrCheckError,
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
58
                           BzrError,
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
59
                           DivergedBranches,
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
60
                           WeaveRevisionNotPresent,
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
61
                           NotBranchError,
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
62
                           NoSuchFile,
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
63
                           NotVersionedError)
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
64
from bzrlib.inventory import InventoryEntry, Inventory
1534.4.28 by Robert Collins
first cut at merge from integration.
65
from bzrlib.lockable_files import LockableFiles
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
66
from bzrlib.merge import merge_inner, transform_tree
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
67
from bzrlib.osutils import (appendpath,
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
68
                            compact_date,
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
69
                            file_kind,
70
                            isdir,
1185.31.39 by John Arbash Meinel
Replacing os.getcwdu() with osutils.getcwd(),
71
                            getcwd,
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
72
                            pathjoin,
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
73
                            pumpfile,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
74
                            safe_unicode,
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
75
                            splitpath,
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
76
                            rand_bytes,
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
77
                            abspath,
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
78
                            normpath,
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
79
                            realpath,
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
80
                            relpath,
1534.7.25 by Aaron Bentley
Added set_executability
81
                            rename,
82
                            supports_executable,
83
                            )
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
84
from bzrlib.revision import NULL_REVISION
1534.4.25 by Robert Collins
Add a --transport parameter to the test suite to set the default transport to be used in the test suite.
85
from bzrlib.symbol_versioning import *
1185.33.92 by Martin Pool
[patch] fix for 'bzr rm -v' (Wouter van Heyst)
86
from bzrlib.textui import show_status
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
87
import bzrlib.tree
1140 by Martin Pool
- lift out import statements within WorkingTree
88
from bzrlib.trace import mutter
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
89
from bzrlib.transform import build_tree
1534.4.28 by Robert Collins
first cut at merge from integration.
90
from bzrlib.transport import get_transport
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
91
from bzrlib.transport.local import LocalTransport
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
92
import bzrlib.xml5
453 by Martin Pool
- Split WorkingTree into its own file
93
1465 by Robert Collins
Bugfix the new pull --clobber to not generate spurious conflicts.
94
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
95
def gen_file_id(name):
96
    """Return new file id.
97
98
    This should probably generate proper UUIDs, but for the moment we
99
    cope with just randomness because running uuidgen every time is
100
    slow."""
101
    import re
102
    from binascii import hexlify
103
    from time import time
104
105
    # get last component
106
    idx = name.rfind('/')
107
    if idx != -1:
108
        name = name[idx+1 : ]
109
    idx = name.rfind('\\')
110
    if idx != -1:
111
        name = name[idx+1 : ]
112
113
    # make it not a hidden file
114
    name = name.lstrip('.')
115
116
    # remove any wierd characters; we don't escape them but rather
117
    # just pull them out
118
    name = re.sub(r'[^\w.]', '', name)
119
120
    s = hexlify(rand_bytes(8))
121
    return '-'.join((name, compact_date(time()), s))
122
123
124
def gen_root_id():
125
    """Return a new tree-root file id."""
126
    return gen_file_id('TREE_ROOT')
127
128
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
129
class TreeEntry(object):
130
    """An entry that implements the minium interface used by commands.
131
132
    This needs further inspection, it may be better to have 
133
    InventoryEntries without ids - though that seems wrong. For now,
134
    this is a parallel hierarchy to InventoryEntry, and needs to become
135
    one of several things: decorates to that hierarchy, children of, or
136
    parents of it.
1399.1.3 by Robert Collins
move change detection for text and metadata from delta to entry.detect_changes
137
    Another note is that these objects are currently only used when there is
138
    no InventoryEntry available - i.e. for unversioned objects.
139
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
140
    """
141
 
142
    def __eq__(self, other):
143
        # yes, this us ugly, TODO: best practice __eq__ style.
144
        return (isinstance(other, TreeEntry)
145
                and other.__class__ == self.__class__)
146
 
147
    def kind_character(self):
148
        return "???"
149
150
151
class TreeDirectory(TreeEntry):
152
    """See TreeEntry. This is a directory in a working tree."""
153
154
    def __eq__(self, other):
155
        return (isinstance(other, TreeDirectory)
156
                and other.__class__ == self.__class__)
157
158
    def kind_character(self):
159
        return "/"
160
161
162
class TreeFile(TreeEntry):
163
    """See TreeEntry. This is a regular file in a working tree."""
164
165
    def __eq__(self, other):
166
        return (isinstance(other, TreeFile)
167
                and other.__class__ == self.__class__)
168
169
    def kind_character(self):
170
        return ''
171
172
173
class TreeLink(TreeEntry):
174
    """See TreeEntry. This is a symlink in a working tree."""
175
176
    def __eq__(self, other):
177
        return (isinstance(other, TreeLink)
178
                and other.__class__ == self.__class__)
179
180
    def kind_character(self):
181
        return ''
182
183
453 by Martin Pool
- Split WorkingTree into its own file
184
class WorkingTree(bzrlib.tree.Tree):
185
    """Working copy tree.
186
187
    The inventory is held in the `Branch` working-inventory, and the
188
    files are in a directory on disk.
189
190
    It is possible for a `WorkingTree` to have a filename which is
191
    not listed in the Inventory and vice versa.
192
    """
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
193
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
194
    def __init__(self, basedir='.',
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
195
                 branch=DEPRECATED_PARAMETER,
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
196
                 _inventory=None,
197
                 _control_files=None,
198
                 _internal=False,
199
                 _format=None,
200
                 _bzrdir=None):
1457.1.1 by Robert Collins
rather than getting the branch inventory, WorkingTree can use the whole Branch, or make its own.
201
        """Construct a WorkingTree for basedir.
202
203
        If the branch is not supplied, it is opened automatically.
204
        If the branch is supplied, it must be the branch for this basedir.
205
        (branch.base is not cross checked, because for remote branches that
206
        would be meaningless).
207
        """
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
208
        self._format = _format
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
209
        self.bzrdir = _bzrdir
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
210
        if not _internal:
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
211
            # not created via open etc.
1508.1.25 by Robert Collins
Update per review comments.
212
            warn("WorkingTree() is deprecated as of bzr version 0.8. "
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
213
                 "Please use bzrdir.open_workingtree or WorkingTree.open().",
214
                 DeprecationWarning,
215
                 stacklevel=2)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
216
            wt = WorkingTree.open(basedir)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
217
            self.branch = wt.branch
218
            self.basedir = wt.basedir
219
            self._control_files = wt._control_files
220
            self._hashcache = wt._hashcache
221
            self._set_inventory(wt._inventory)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
222
            self._format = wt._format
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
223
            self.bzrdir = wt.bzrdir
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
224
        from bzrlib.hashcache import HashCache
225
        from bzrlib.trace import note, mutter
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
226
        assert isinstance(basedir, basestring), \
227
            "base directory %r is not a string" % basedir
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
228
        basedir = safe_unicode(basedir)
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
229
        mutter("opening working tree %r", basedir)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
230
        if deprecated_passed(branch):
231
            if not _internal:
232
                warn("WorkingTree(..., branch=XXX) is deprecated as of bzr 0.8."
1508.1.26 by Robert Collins
Forgot to update the last warn() to reference WorkingTree.open().
233
                     " Please use bzrdir.open_workingtree() or WorkingTree.open().",
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
234
                     DeprecationWarning,
235
                     stacklevel=2
236
                     )
237
            self.branch = branch
238
        else:
239
            self.branch = self.bzrdir.open_branch()
240
        assert isinstance(self.branch, Branch), \
241
            "branch %r is not a Branch" % self.branch
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
242
        self.basedir = realpath(basedir)
1534.4.28 by Robert Collins
first cut at merge from integration.
243
        # if branch is at our basedir and is a format 6 or less
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
244
        if isinstance(self._format, WorkingTreeFormat2):
245
            # share control object
1534.4.28 by Robert Collins
first cut at merge from integration.
246
            self._control_files = self.branch.control_files
247
        elif _control_files is not None:
248
            assert False, "not done yet"
249
#            self._control_files = _control_files
250
        else:
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
251
            # only ready for format 3
252
            assert isinstance(self._format, WorkingTreeFormat3)
1534.4.28 by Robert Collins
first cut at merge from integration.
253
            self._control_files = LockableFiles(
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
254
                self.bzrdir.get_workingtree_transport(None),
255
                'lock')
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
256
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
257
        # update the whole cache up front and write to disk if anything changed;
258
        # in the future we might want to do this more selectively
1467 by Robert Collins
WorkingTree.__del__ has been removed.
259
        # two possible ways offer themselves : in self._unlock, write the cache
260
        # if needed, or, when the cache sees a change, append it to the hash
261
        # cache file, and have the parser take the most recent entry for a
262
        # given path only.
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
263
        cache_filename = self.bzrdir.get_workingtree_transport(None).abspath('stat-cache')
264
        hc = self._hashcache = HashCache(basedir, cache_filename, self._control_files._file_mode)
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
265
        hc.read()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
266
        # is this scan needed ? it makes things kinda slow.
954 by Martin Pool
- separate out code that just scans the hash cache to find files that are possibly
267
        hc.scan()
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
268
269
        if hc.needs_write:
270
            mutter("write hc")
271
            hc.write()
453 by Martin Pool
- Split WorkingTree into its own file
272
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
273
        if _inventory is None:
274
            self._set_inventory(self.read_working_inventory())
275
        else:
276
            self._set_inventory(_inventory)
1185.60.6 by Aaron Bentley
Fixed hashcache
277
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
278
    def _set_inventory(self, inv):
279
        self._inventory = inv
280
        self.path2id = self._inventory.path2id
281
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
282
    def is_control_filename(self, filename):
1534.5.16 by Robert Collins
Review feedback.
283
        """True if filename is the name of a control file in this tree.
284
        
285
        This is true IF and ONLY IF the filename is part of the meta data
286
        that bzr controls in this tree. I.E. a random .bzr directory placed
287
        on disk will not be a control file for this tree.
288
        """
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
289
        try:
290
            self.bzrdir.transport.relpath(self.abspath(filename))
291
            return True
292
        except errors.PathNotChild:
293
            return False
294
1508.1.1 by Robert Collins
Provide a open_containing for WorkingTree.
295
    @staticmethod
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
296
    def open(path=None, _unsupported=False):
297
        """Open an existing working tree at path.
298
299
        """
300
        if path is None:
301
            path = os.path.getcwdu()
302
        control = bzrdir.BzrDir.open(path, _unsupported)
303
        return control.open_workingtree(_unsupported)
304
        
305
    @staticmethod
1508.1.1 by Robert Collins
Provide a open_containing for WorkingTree.
306
    def open_containing(path=None):
307
        """Open an existing working tree which has its root about path.
308
        
309
        This probes for a working tree at path and searches upwards from there.
310
311
        Basically we keep looking up until we find the control directory or
312
        run into /.  If there isn't one, raises NotBranchError.
313
        TODO: give this a new exception.
314
        If there is one, it is returned, along with the unused portion of path.
315
        """
316
        if path is None:
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
317
            path = os.getcwdu()
318
        control, relpath = bzrdir.BzrDir.open_containing(path)
319
        return control.open_workingtree(), relpath
320
321
    @staticmethod
322
    def open_downlevel(path=None):
323
        """Open an unsupported working tree.
324
325
        Only intended for advanced situations like upgrading part of a bzrdir.
326
        """
327
        return WorkingTree.open(path, _unsupported=True)
1508.1.1 by Robert Collins
Provide a open_containing for WorkingTree.
328
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
329
    def __iter__(self):
330
        """Iterate through file_ids for this tree.
331
332
        file_ids are in a WorkingTree if they are in the working inventory
333
        and the working file exists.
334
        """
335
        inv = self._inventory
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
336
        for path, ie in inv.iter_entries():
1092.2.6 by Robert Collins
symlink support updated to work
337
            if bzrlib.osutils.lexists(self.abspath(path)):
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
338
                yield ie.file_id
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
339
453 by Martin Pool
- Split WorkingTree into its own file
340
    def __repr__(self):
341
        return "<%s of %s>" % (self.__class__.__name__,
954 by Martin Pool
- separate out code that just scans the hash cache to find files that are possibly
342
                               getattr(self, 'basedir', None))
453 by Martin Pool
- Split WorkingTree into its own file
343
344
    def abspath(self, filename):
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
345
        return pathjoin(self.basedir, filename)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
346
    
347
    def basis_tree(self):
348
        """Return RevisionTree for the current last revision."""
349
        revision_id = self.last_revision()
350
        if revision_id is not None:
351
            try:
352
                xml = self.read_basis_inventory(revision_id)
353
                inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
354
                return bzrlib.tree.RevisionTree(self.branch.repository, inv,
355
                                                revision_id)
356
            except NoSuchFile:
357
                pass
358
        return self.branch.repository.revision_tree(revision_id)
453 by Martin Pool
- Split WorkingTree into its own file
359
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
360
    @staticmethod
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
361
    @deprecated_method(zero_eight)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
362
    def create(branch, directory):
363
        """Create a workingtree for branch at directory.
364
365
        If existing_directory already exists it must have a .bzr directory.
366
        If it does not exist, it will be created.
367
368
        This returns a new WorkingTree object for the new checkout.
369
370
        TODO FIXME RBC 20060124 when we have checkout formats in place this
371
        should accept an optional revisionid to checkout [and reject this if
372
        checking out into the same dir as a pre-checkout-aware branch format.]
1551.1.2 by Martin Pool
Deprecation warnings for popular APIs that will change in BzrDir
373
374
        XXX: When BzrDir is present, these should be created through that 
375
        interface instead.
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
376
        """
1534.4.47 by Robert Collins
Split out repository into .bzr/repository
377
        warn('delete WorkingTree.create', stacklevel=3)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
378
        transport = get_transport(directory)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
379
        if branch.bzrdir.root_transport.base == transport.base:
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
380
            # same dir 
381
            return branch.bzrdir.create_workingtree()
382
        # different directory, 
383
        # create a branch reference
384
        # and now a working tree.
385
        raise NotImplementedError
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
386
 
387
    @staticmethod
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
388
    @deprecated_method(zero_eight)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
389
    def create_standalone(directory):
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
390
        """Create a checkout and a branch and a repo at directory.
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
391
392
        Directory must exist and be empty.
1551.1.2 by Martin Pool
Deprecation warnings for popular APIs that will change in BzrDir
393
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
394
        please use BzrDir.create_standalone_workingtree
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
395
        """
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
396
        return bzrdir.BzrDir.create_standalone_workingtree(directory)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
397
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
398
    def relpath(self, abs):
1457.1.3 by Robert Collins
make Branch.relpath delegate to the working tree.
399
        """Return the local path portion from a given absolute path."""
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
400
        return relpath(self.basedir, abs)
1457.1.3 by Robert Collins
make Branch.relpath delegate to the working tree.
401
453 by Martin Pool
- Split WorkingTree into its own file
402
    def has_filename(self, filename):
1092.2.6 by Robert Collins
symlink support updated to work
403
        return bzrlib.osutils.lexists(self.abspath(filename))
453 by Martin Pool
- Split WorkingTree into its own file
404
405
    def get_file(self, file_id):
406
        return self.get_file_byname(self.id2path(file_id))
407
408
    def get_file_byname(self, filename):
409
        return file(self.abspath(filename), 'rb')
410
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
411
    def get_root_id(self):
412
        """Return the id of this trees root"""
413
        inv = self.read_working_inventory()
414
        return inv.root.file_id
415
        
453 by Martin Pool
- Split WorkingTree into its own file
416
    def _get_store_filename(self, file_id):
1508.1.1 by Robert Collins
Provide a open_containing for WorkingTree.
417
        ## XXX: badly named; this is not in the store at all
453 by Martin Pool
- Split WorkingTree into its own file
418
        return self.abspath(self.id2path(file_id))
419
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
420
    @needs_read_lock
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
421
    def clone(self, to_bzrdir, revision_id=None, basis=None):
422
        """Duplicate this working tree into to_bzr, including all state.
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
423
        
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
424
        Specifically modified files are kept as modified, but
425
        ignored and unknown files are discarded.
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
426
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
427
        If you want to make a new line of development, see bzrdir.sprout()
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
428
429
        revision
430
            If not None, the cloned tree will have its last revision set to 
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
431
            revision, and and difference between the source trees last revision
432
            and this one merged in.
433
434
        basis
435
            If not None, a closer copy of a tree which may have some files in
436
            common, and which file content should be preferentially copied from.
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
437
        """
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
438
        # assumes the target bzr dir format is compatible.
439
        result = self._format.initialize(to_bzrdir)
440
        self.copy_content_into(result, revision_id)
441
        return result
442
443
    @needs_read_lock
444
    def copy_content_into(self, tree, revision_id=None):
445
        """Copy the current content and user files of this tree into tree."""
446
        if revision_id is None:
447
            transform_tree(tree, self)
448
        else:
449
            # TODO now merge from tree.last_revision to revision
450
            transform_tree(tree, self)
451
            tree.set_last_revision(revision_id)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
452
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
453
    @needs_write_lock
1534.4.25 by Robert Collins
Add a --transport parameter to the test suite to set the default transport to be used in the test suite.
454
    def commit(self, *args, **kwargs):
1457.1.17 by Robert Collins
Branch.commit() has moved to WorkingTree.commit(). (Robert Collins)
455
        from bzrlib.commit import Commit
1534.4.25 by Robert Collins
Add a --transport parameter to the test suite to set the default transport to be used in the test suite.
456
        # args for wt.commit start at message from the Commit.commit method,
457
        # but with branch a kwarg now, passing in args as is results in the
458
        #message being used for the branch
1534.4.32 by Robert Collins
Rename deprecated_nonce to DEPRECATED_PARAMETER
459
        args = (DEPRECATED_PARAMETER, ) + args
1534.4.25 by Robert Collins
Add a --transport parameter to the test suite to set the default transport to be used in the test suite.
460
        Commit().commit(working_tree=self, *args, **kwargs)
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
461
        self._set_inventory(self.read_working_inventory())
1248 by Martin Pool
- new weave based cleanup [broken]
462
463
    def id2abspath(self, file_id):
464
        return self.abspath(self.id2path(file_id))
465
1185.12.39 by abentley
Propogated has_or_had_id to Tree
466
    def has_id(self, file_id):
453 by Martin Pool
- Split WorkingTree into its own file
467
        # files that have been deleted are excluded
1185.12.39 by abentley
Propogated has_or_had_id to Tree
468
        inv = self._inventory
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
469
        if not inv.has_id(file_id):
453 by Martin Pool
- Split WorkingTree into its own file
470
            return False
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
471
        path = inv.id2path(file_id)
1092.2.6 by Robert Collins
symlink support updated to work
472
        return bzrlib.osutils.lexists(self.abspath(path))
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
473
1185.12.39 by abentley
Propogated has_or_had_id to Tree
474
    def has_or_had_id(self, file_id):
475
        if file_id == self.inventory.root.file_id:
476
            return True
477
        return self.inventory.has_id(file_id)
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
478
479
    __contains__ = has_id
480
453 by Martin Pool
- Split WorkingTree into its own file
481
    def get_file_size(self, file_id):
1248 by Martin Pool
- new weave based cleanup [broken]
482
        return os.path.getsize(self.id2abspath(file_id))
453 by Martin Pool
- Split WorkingTree into its own file
483
1185.60.6 by Aaron Bentley
Fixed hashcache
484
    @needs_read_lock
453 by Martin Pool
- Split WorkingTree into its own file
485
    def get_file_sha1(self, file_id):
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
486
        path = self._inventory.id2path(file_id)
487
        return self._hashcache.get_sha1(path)
453 by Martin Pool
- Split WorkingTree into its own file
488
1398 by Robert Collins
integrate in Gustavos x-bit patch
489
    def is_executable(self, file_id):
1534.7.25 by Aaron Bentley
Added set_executability
490
        if not supports_executable():
1398 by Robert Collins
integrate in Gustavos x-bit patch
491
            return self._inventory[file_id].executable
492
        else:
493
            path = self._inventory.id2path(file_id)
494
            mode = os.lstat(self.abspath(path)).st_mode
495
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC&mode)
496
1457.1.16 by Robert Collins
Move set_pending_merges to WorkingTree.
497
    @needs_write_lock
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
498
    def add(self, files, ids=None):
499
        """Make files versioned.
500
501
        Note that the command line normally calls smart_add instead,
502
        which can automatically recurse.
503
504
        This adds the files to the inventory, so that they will be
505
        recorded by the next commit.
506
507
        files
508
            List of paths to add, relative to the base of the tree.
509
510
        ids
511
            If set, use these instead of automatically generated ids.
512
            Must be the same length as the list of files, but may
513
            contain None for ids that are to be autogenerated.
514
515
        TODO: Perhaps have an option to add the ids even if the files do
516
              not (yet) exist.
517
518
        TODO: Perhaps callback with the ids and paths as they're added.
519
        """
520
        # TODO: Re-adding a file that is removed in the working copy
521
        # should probably put it back with the previous ID.
522
        if isinstance(files, basestring):
523
            assert(ids is None or isinstance(ids, basestring))
524
            files = [files]
525
            if ids is not None:
526
                ids = [ids]
527
528
        if ids is None:
529
            ids = [None] * len(files)
530
        else:
531
            assert(len(ids) == len(files))
532
533
        inv = self.read_working_inventory()
534
        for f,file_id in zip(files, ids):
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
535
            if self.is_control_filename(f):
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
536
                raise BzrError("cannot add control file %s" % quotefn(f))
537
538
            fp = splitpath(f)
539
540
            if len(fp) == 0:
541
                raise BzrError("cannot add top-level %r" % f)
542
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
543
            fullpath = normpath(self.abspath(f))
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
544
545
            try:
546
                kind = file_kind(fullpath)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
547
            except OSError, e:
548
                if e.errno == errno.ENOENT:
549
                    raise NoSuchFile(fullpath)
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
550
                # maybe something better?
551
                raise BzrError('cannot add: not a regular file, symlink or directory: %s' % quotefn(f))
552
553
            if not InventoryEntry.versionable_kind(kind):
554
                raise BzrError('cannot add: not a versionable file ('
555
                               'i.e. regular file, symlink or directory): %s' % quotefn(f))
556
557
            if file_id is None:
558
                file_id = gen_file_id(f)
559
            inv.add_path(f, kind=kind, file_id=file_id)
560
561
            mutter("add file %s file_id:{%s} kind=%r" % (f, file_id, kind))
562
        self._write_inventory(inv)
563
564
    @needs_write_lock
1457.1.15 by Robert Collins
Move add_pending_merge to WorkingTree.
565
    def add_pending_merge(self, *revision_ids):
566
        # TODO: Perhaps should check at this point that the
567
        # history of the revision is actually present?
568
        p = self.pending_merges()
569
        updated = False
570
        for rev_id in revision_ids:
571
            if rev_id in p:
572
                continue
573
            p.append(rev_id)
574
            updated = True
575
        if updated:
1457.1.16 by Robert Collins
Move set_pending_merges to WorkingTree.
576
            self.set_pending_merges(p)
1457.1.15 by Robert Collins
Move add_pending_merge to WorkingTree.
577
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
578
    @needs_read_lock
1457.1.14 by Robert Collins
Move pending_merges() to WorkingTree.
579
    def pending_merges(self):
580
        """Return a list of pending merges.
581
582
        These are revisions that have been merged into the working
583
        directory but not yet committed.
584
        """
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
585
        try:
1534.4.28 by Robert Collins
first cut at merge from integration.
586
            merges_file = self._control_files.get_utf8('pending-merges')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
587
        except OSError, e:
588
            if e.errno != errno.ENOENT:
589
                raise
1457.1.14 by Robert Collins
Move pending_merges() to WorkingTree.
590
            return []
591
        p = []
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
592
        for l in merges_file.readlines():
1457.1.14 by Robert Collins
Move pending_merges() to WorkingTree.
593
            p.append(l.rstrip('\n'))
594
        return p
595
1457.1.16 by Robert Collins
Move set_pending_merges to WorkingTree.
596
    @needs_write_lock
597
    def set_pending_merges(self, rev_list):
1534.4.28 by Robert Collins
first cut at merge from integration.
598
        self._control_files.put_utf8('pending-merges', '\n'.join(rev_list))
1457.1.16 by Robert Collins
Move set_pending_merges to WorkingTree.
599
1092.2.6 by Robert Collins
symlink support updated to work
600
    def get_symlink_target(self, file_id):
1185.15.10 by Scott James Remnant
Fix WorkingTree.get_symlink_target() to read the absolute path of the
601
        return os.readlink(self.id2abspath(file_id))
453 by Martin Pool
- Split WorkingTree into its own file
602
603
    def file_class(self, filename):
604
        if self.path2id(filename):
605
            return 'V'
606
        elif self.is_ignored(filename):
607
            return 'I'
608
        else:
609
            return '?'
610
611
    def list_files(self):
612
        """Recursively list all files as (path, class, kind, id).
613
614
        Lists, but does not descend into unversioned directories.
615
616
        This does not include files that have been deleted in this
617
        tree.
618
619
        Skips the control directory.
620
        """
866 by Martin Pool
- use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.
621
        inv = self._inventory
453 by Martin Pool
- Split WorkingTree into its own file
622
623
        def descend(from_dir_relpath, from_dir_id, dp):
624
            ls = os.listdir(dp)
625
            ls.sort()
626
            for f in ls:
627
                ## TODO: If we find a subdirectory with its own .bzr
628
                ## directory, then that is a separate tree and we
629
                ## should exclude it.
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
630
631
                # the bzrdir for this tree
632
                if self.bzrdir.transport.base.endswith(f + '/'):
453 by Martin Pool
- Split WorkingTree into its own file
633
                    continue
634
635
                # path within tree
636
                fp = appendpath(from_dir_relpath, f)
637
638
                # absolute path
639
                fap = appendpath(dp, f)
640
                
641
                f_ie = inv.get_child(from_dir_id, f)
642
                if f_ie:
643
                    c = 'V'
644
                elif self.is_ignored(fp):
645
                    c = 'I'
646
                else:
647
                    c = '?'
648
649
                fk = file_kind(fap)
650
651
                if f_ie:
652
                    if f_ie.kind != fk:
653
                        raise BzrCheckError("file %r entered as kind %r id %r, "
654
                                            "now of kind %r"
655
                                            % (fap, f_ie.kind, f_ie.file_id, fk))
656
1399.1.2 by Robert Collins
push kind character creation into InventoryEntry and TreeEntry
657
                # make a last minute entry
658
                if f_ie:
659
                    entry = f_ie
660
                else:
661
                    if fk == 'directory':
662
                        entry = TreeDirectory()
663
                    elif fk == 'file':
664
                        entry = TreeFile()
665
                    elif fk == 'symlink':
666
                        entry = TreeLink()
667
                    else:
668
                        entry = TreeEntry()
669
                
670
                yield fp, c, fk, (f_ie and f_ie.file_id), entry
453 by Martin Pool
- Split WorkingTree into its own file
671
672
                if fk != 'directory':
673
                    continue
674
675
                if c != 'V':
676
                    # don't descend unversioned directories
677
                    continue
678
                
679
                for ff in descend(fp, f_ie.file_id, fap):
680
                    yield ff
681
1185.33.66 by Martin Pool
[patch] use unicode literals for all hardcoded paths (Alexander Belchenko)
682
        for f in descend(u'', inv.root.file_id, self.basedir):
453 by Martin Pool
- Split WorkingTree into its own file
683
            yield f
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
684
685
    @needs_write_lock
1508.1.8 by Robert Collins
move move() from Branch to WorkingTree.
686
    def move(self, from_paths, to_name):
687
        """Rename files.
688
689
        to_name must exist in the inventory.
690
691
        If to_name exists and is a directory, the files are moved into
692
        it, keeping their old names.  
693
694
        Note that to_name is only the last component of the new name;
695
        this doesn't change the directory.
696
697
        This returns a list of (from_path, to_path) pairs for each
698
        entry that is moved.
699
        """
700
        result = []
701
        ## TODO: Option to move IDs only
702
        assert not isinstance(from_paths, basestring)
703
        inv = self.inventory
704
        to_abs = self.abspath(to_name)
705
        if not isdir(to_abs):
706
            raise BzrError("destination %r is not a directory" % to_abs)
707
        if not self.has_filename(to_name):
708
            raise BzrError("destination %r not in working directory" % to_abs)
709
        to_dir_id = inv.path2id(to_name)
710
        if to_dir_id == None and to_name != '':
711
            raise BzrError("destination %r is not a versioned directory" % to_name)
712
        to_dir_ie = inv[to_dir_id]
713
        if to_dir_ie.kind not in ('directory', 'root_directory'):
714
            raise BzrError("destination %r is not a directory" % to_abs)
715
716
        to_idpath = inv.get_idpath(to_dir_id)
717
718
        for f in from_paths:
719
            if not self.has_filename(f):
720
                raise BzrError("%r does not exist in working tree" % f)
721
            f_id = inv.path2id(f)
722
            if f_id == None:
723
                raise BzrError("%r is not versioned" % f)
724
            name_tail = splitpath(f)[-1]
725
            dest_path = appendpath(to_name, name_tail)
726
            if self.has_filename(dest_path):
727
                raise BzrError("destination %r already exists" % dest_path)
728
            if f_id in to_idpath:
729
                raise BzrError("can't move %r to a subdirectory of itself" % f)
730
731
        # OK, so there's a race here, it's possible that someone will
732
        # create a file in this interval and then the rename might be
733
        # left half-done.  But we should have caught most problems.
734
        orig_inv = deepcopy(self.inventory)
735
        try:
736
            for f in from_paths:
737
                name_tail = splitpath(f)[-1]
738
                dest_path = appendpath(to_name, name_tail)
739
                result.append((f, dest_path))
740
                inv.rename(inv.path2id(f), to_dir_id, name_tail)
741
                try:
742
                    rename(self.abspath(f), self.abspath(dest_path))
743
                except OSError, e:
744
                    raise BzrError("failed to rename %r to %r: %s" %
745
                                   (f, dest_path, e[1]),
746
                            ["rename rolled back"])
747
        except:
748
            # restore the inventory on error
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
749
            self._set_inventory(orig_inv)
1508.1.8 by Robert Collins
move move() from Branch to WorkingTree.
750
            raise
751
        self._write_inventory(inv)
752
        return result
753
754
    @needs_write_lock
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
755
    def rename_one(self, from_rel, to_rel):
756
        """Rename one file.
757
758
        This can change the directory or the filename or both.
759
        """
760
        inv = self.inventory
761
        if not self.has_filename(from_rel):
762
            raise BzrError("can't rename: old working file %r does not exist" % from_rel)
763
        if self.has_filename(to_rel):
764
            raise BzrError("can't rename: new working file %r already exists" % to_rel)
765
766
        file_id = inv.path2id(from_rel)
767
        if file_id == None:
768
            raise BzrError("can't rename: old name %r is not versioned" % from_rel)
769
770
        entry = inv[file_id]
771
        from_parent = entry.parent_id
772
        from_name = entry.name
773
        
774
        if inv.path2id(to_rel):
775
            raise BzrError("can't rename: new name %r is already versioned" % to_rel)
776
777
        to_dir, to_tail = os.path.split(to_rel)
778
        to_dir_id = inv.path2id(to_dir)
779
        if to_dir_id == None and to_dir != '':
780
            raise BzrError("can't determine destination directory id for %r" % to_dir)
781
782
        mutter("rename_one:")
783
        mutter("  file_id    {%s}" % file_id)
784
        mutter("  from_rel   %r" % from_rel)
785
        mutter("  to_rel     %r" % to_rel)
786
        mutter("  to_dir     %r" % to_dir)
787
        mutter("  to_dir_id  {%s}" % to_dir_id)
788
789
        inv.rename(file_id, to_dir_id, to_tail)
790
791
        from_abs = self.abspath(from_rel)
792
        to_abs = self.abspath(to_rel)
793
        try:
794
            rename(from_abs, to_abs)
795
        except OSError, e:
796
            inv.rename(file_id, from_parent, from_name)
797
            raise BzrError("failed to rename %r to %r: %s"
798
                    % (from_abs, to_abs, e[1]),
799
                    ["rename rolled back"])
800
        self._write_inventory(inv)
801
802
    @needs_read_lock
453 by Martin Pool
- Split WorkingTree into its own file
803
    def unknowns(self):
1508.1.6 by Robert Collins
Move Branch.unknowns() to WorkingTree.
804
        """Return all unknown files.
805
806
        These are files in the working directory that are not versioned or
807
        control files or ignored.
808
        
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
809
        >>> from bzrlib.bzrdir import ScratchDir
810
        >>> d = ScratchDir(files=['foo', 'foo~'])
811
        >>> b = d.open_branch()
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
812
        >>> tree = d.open_workingtree()
1508.1.6 by Robert Collins
Move Branch.unknowns() to WorkingTree.
813
        >>> map(str, tree.unknowns())
814
        ['foo']
815
        >>> tree.add('foo')
816
        >>> list(b.unknowns())
817
        []
818
        >>> tree.remove('foo')
819
        >>> list(b.unknowns())
820
        [u'foo']
821
        """
453 by Martin Pool
- Split WorkingTree into its own file
822
        for subp in self.extras():
823
            if not self.is_ignored(subp):
824
                yield subp
825
1185.14.6 by Aaron Bentley
Made iter_conflicts a WorkingTree method
826
    def iter_conflicts(self):
827
        conflicted = set()
828
        for path in (s[0] for s in self.list_files()):
829
            stem = get_conflicted_stem(path)
830
            if stem is None:
831
                continue
832
            if stem not in conflicted:
833
                conflicted.add(stem)
834
                yield stem
453 by Martin Pool
- Split WorkingTree into its own file
835
1442.1.67 by Robert Collins
Factor out the guts of 'pull' from the command into WorkingTree.pull().
836
    @needs_write_lock
1185.76.1 by Erik BÃ¥gfors
Support for --revision in pull
837
    def pull(self, source, overwrite=False, stop_revision=None):
1442.1.67 by Robert Collins
Factor out the guts of 'pull' from the command into WorkingTree.pull().
838
        source.lock_read()
839
        try:
840
            old_revision_history = self.branch.revision_history()
1534.4.54 by Robert Collins
Merge from integration.
841
            count = self.branch.pull(source, overwrite, stop_revision)
1442.1.67 by Robert Collins
Factor out the guts of 'pull' from the command into WorkingTree.pull().
842
            new_revision_history = self.branch.revision_history()
843
            if new_revision_history != old_revision_history:
1465 by Robert Collins
Bugfix the new pull --clobber to not generate spurious conflicts.
844
                if len(old_revision_history):
845
                    other_revision = old_revision_history[-1]
846
                else:
847
                    other_revision = None
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
848
                repository = self.branch.repository
1465 by Robert Collins
Bugfix the new pull --clobber to not generate spurious conflicts.
849
                merge_inner(self.branch,
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
850
                            self.basis_tree(), 
1534.4.28 by Robert Collins
first cut at merge from integration.
851
                            repository.revision_tree(other_revision),
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
852
                            this_tree=self)
853
                self.set_last_revision(self.branch.last_revision())
1185.33.44 by Martin Pool
[patch] show number of revisions pushed/pulled/merged (Robey Pointer)
854
            return count
1442.1.67 by Robert Collins
Factor out the guts of 'pull' from the command into WorkingTree.pull().
855
        finally:
856
            source.unlock()
857
453 by Martin Pool
- Split WorkingTree into its own file
858
    def extras(self):
859
        """Yield all unknown files in this WorkingTree.
860
861
        If there are any unknown directories then only the directory is
862
        returned, not all its children.  But if there are unknown files
863
        under a versioned subdirectory, they are returned.
864
865
        Currently returned depth-first, sorted by name within directories.
866
        """
867
        ## TODO: Work from given directory downwards
868
        for path, dir_entry in self.inventory.directories():
1185.31.4 by John Arbash Meinel
Fixing mutter() calls to not have to do string processing.
869
            mutter("search for unknowns in %r", path)
453 by Martin Pool
- Split WorkingTree into its own file
870
            dirabs = self.abspath(path)
871
            if not isdir(dirabs):
872
                # e.g. directory deleted
873
                continue
874
875
            fl = []
876
            for subf in os.listdir(dirabs):
877
                if (subf != '.bzr'
878
                    and (subf not in dir_entry.children)):
879
                    fl.append(subf)
880
            
881
            fl.sort()
882
            for subf in fl:
883
                subp = appendpath(path, subf)
884
                yield subp
885
886
887
    def ignored_files(self):
888
        """Yield list of PATH, IGNORE_PATTERN"""
889
        for subp in self.extras():
890
            pat = self.is_ignored(subp)
891
            if pat != None:
892
                yield subp, pat
893
894
895
    def get_ignore_list(self):
896
        """Return list of ignore patterns.
897
898
        Cached in the Tree object after the first call.
899
        """
900
        if hasattr(self, '_ignorelist'):
901
            return self._ignorelist
902
903
        l = bzrlib.DEFAULT_IGNORE[:]
904
        if self.has_filename(bzrlib.IGNORE_FILENAME):
905
            f = self.get_file_byname(bzrlib.IGNORE_FILENAME)
906
            l.extend([line.rstrip("\n\r") for line in f.readlines()])
907
        self._ignorelist = l
908
        return l
909
910
911
    def is_ignored(self, filename):
912
        r"""Check whether the filename matches an ignore pattern.
913
914
        Patterns containing '/' or '\' need to match the whole path;
915
        others match against only the last component.
916
917
        If the file is ignored, returns the pattern which caused it to
918
        be ignored, otherwise None.  So this can simply be used as a
919
        boolean if desired."""
920
921
        # TODO: Use '**' to match directories, and other extended
922
        # globbing stuff from cvs/rsync.
923
924
        # XXX: fnmatch is actually not quite what we want: it's only
925
        # approximately the same as real Unix fnmatch, and doesn't
926
        # treat dotfiles correctly and allows * to match /.
927
        # Eventually it should be replaced with something more
928
        # accurate.
929
        
930
        for pat in self.get_ignore_list():
931
            if '/' in pat or '\\' in pat:
932
                
933
                # as a special case, you can put ./ at the start of a
934
                # pattern; this is good to match in the top-level
935
                # only;
936
                
937
                if (pat[:2] == './') or (pat[:2] == '.\\'):
938
                    newpat = pat[2:]
939
                else:
940
                    newpat = pat
941
                if fnmatch.fnmatchcase(filename, newpat):
942
                    return pat
943
            else:
944
                if fnmatch.fnmatchcase(splitpath(filename)[-1], pat):
945
                    return pat
946
        else:
947
            return None
1185.14.6 by Aaron Bentley
Made iter_conflicts a WorkingTree method
948
1185.12.28 by Aaron Bentley
Removed use of readonly path for executability test
949
    def kind(self, file_id):
950
        return file_kind(self.id2abspath(file_id))
951
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
952
    @needs_read_lock
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
953
    def last_revision(self):
954
        """Return the last revision id of this working tree.
955
956
        In early branch formats this was == the branch last_revision,
957
        but that cannot be relied upon - for working tree operations,
958
        always use tree.last_revision().
959
        """
960
        return self.branch.last_revision()
961
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
962
    def lock_read(self):
963
        """See Branch.lock_read, and WorkingTree.unlock."""
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
964
        self.branch.lock_read()
965
        try:
966
            return self._control_files.lock_read()
967
        except:
968
            self.branch.unlock()
969
            raise
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
970
971
    def lock_write(self):
972
        """See Branch.lock_write, and WorkingTree.unlock."""
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
973
        self.branch.lock_write()
974
        try:
975
            return self._control_files.lock_write()
976
        except:
977
            self.branch.unlock()
978
            raise
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
979
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
980
    def _basis_inventory_name(self, revision_id):
981
        return 'basis-inventory.%s' % revision_id
982
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
983
    @needs_write_lock
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
984
    def set_last_revision(self, new_revision, old_revision=None):
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
985
        """Change the last revision in the working tree."""
986
        self._remove_old_basis(old_revision)
987
        if self._change_last_revision(new_revision):
988
            self._cache_basis_inventory(new_revision)
989
990
    def _change_last_revision(self, new_revision):
991
        """Template method part of set_last_revision to perform the change."""
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
992
        if new_revision is None:
993
            self.branch.set_revision_history([])
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
994
            return False
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
995
        # current format is locked in with the branch
996
        revision_history = self.branch.revision_history()
997
        try:
998
            position = revision_history.index(new_revision)
999
        except ValueError:
1000
            raise errors.NoSuchRevision(self.branch, new_revision)
1001
        self.branch.set_revision_history(revision_history[:position + 1])
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1002
        return True
1003
1004
    def _cache_basis_inventory(self, new_revision):
1005
        """Cache new_revision as the basis inventory."""
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
1006
        try:
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
1007
            xml = self.branch.repository.get_inventory_xml(new_revision)
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
1008
            path = self._basis_inventory_name(new_revision)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1009
            self._control_files.put_utf8(path, xml)
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
1010
        except WeaveRevisionNotPresent:
1011
            pass
1012
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1013
    def _remove_old_basis(self, old_revision):
1014
        """Remove the old basis inventory 'old_revision'."""
1015
        if old_revision is not None:
1016
            try:
1017
                path = self._basis_inventory_name(old_revision)
1018
                path = self._control_files._escape(path)
1019
                self._control_files._transport.delete(path)
1020
            except NoSuchFile:
1021
                pass
1022
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
1023
    def read_basis_inventory(self, revision_id):
1024
        """Read the cached basis inventory."""
1025
        path = self._basis_inventory_name(revision_id)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1026
        return self._control_files.get_utf8(path).read()
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
1027
        
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
1028
    @needs_read_lock
1029
    def read_working_inventory(self):
1030
        """Read the working inventory."""
1031
        # ElementTree does its own conversion from UTF-8, so open in
1032
        # binary.
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1033
        result = bzrlib.xml5.serializer_v5.read_inventory(
1534.4.28 by Robert Collins
first cut at merge from integration.
1034
            self._control_files.get('inventory'))
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1035
        self._set_inventory(result)
1036
        return result
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
1037
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1038
    @needs_write_lock
1039
    def remove(self, files, verbose=False):
1040
        """Remove nominated files from the working inventory..
1041
1042
        This does not remove their text.  This does not run on XXX on what? RBC
1043
1044
        TODO: Refuse to remove modified files unless --force is given?
1045
1046
        TODO: Do something useful with directories.
1047
1048
        TODO: Should this remove the text or not?  Tough call; not
1049
        removing may be useful and the user can just use use rm, and
1050
        is the opposite of add.  Removing it is consistent with most
1051
        other tools.  Maybe an option.
1052
        """
1053
        ## TODO: Normalize names
1054
        ## TODO: Remove nested loops; better scalability
1055
        if isinstance(files, basestring):
1056
            files = [files]
1057
1058
        inv = self.inventory
1059
1060
        # do this before any modifications
1061
        for f in files:
1062
            fid = inv.path2id(f)
1063
            if not fid:
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
1064
                # TODO: Perhaps make this just a warning, and continue?
1065
                # This tends to happen when 
1066
                raise NotVersionedError(path=f)
1185.31.4 by John Arbash Meinel
Fixing mutter() calls to not have to do string processing.
1067
            mutter("remove inventory entry %s {%s}", quotefn(f), fid)
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1068
            if verbose:
1069
                # having remove it, it must be either ignored or unknown
1070
                if self.is_ignored(f):
1071
                    new_status = 'I'
1072
                else:
1073
                    new_status = '?'
1074
                show_status(new_status, inv[fid].kind, quotefn(f))
1075
            del inv[fid]
1076
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1077
        self._write_inventory(inv)
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1078
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
1079
    @needs_write_lock
1501 by Robert Collins
Move revert from Branch to WorkingTree.
1080
    def revert(self, filenames, old_tree=None, backups=True):
1534.7.47 by Aaron Bentley
Started work on 'revert'
1081
        from transform import revert
1501 by Robert Collins
Move revert from Branch to WorkingTree.
1082
        if old_tree is None:
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1083
            old_tree = self.basis_tree()
1534.7.56 by Aaron Bentley
Implemented the backup file detritus
1084
        revert(self, old_tree, filenames, backups)
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
1085
        if not len(filenames):
1457.1.16 by Robert Collins
Move set_pending_merges to WorkingTree.
1086
            self.set_pending_merges([])
1501 by Robert Collins
Move revert from Branch to WorkingTree.
1087
1088
    @needs_write_lock
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
1089
    def set_inventory(self, new_inventory_list):
1090
        from bzrlib.inventory import (Inventory,
1091
                                      InventoryDirectory,
1092
                                      InventoryEntry,
1093
                                      InventoryFile,
1094
                                      InventoryLink)
1095
        inv = Inventory(self.get_root_id())
1096
        for path, file_id, parent, kind in new_inventory_list:
1097
            name = os.path.basename(path)
1098
            if name == "":
1099
                continue
1100
            # fixme, there should be a factory function inv,add_?? 
1101
            if kind == 'directory':
1102
                inv.add(InventoryDirectory(file_id, name, parent))
1103
            elif kind == 'file':
1104
                inv.add(InventoryFile(file_id, name, parent))
1105
            elif kind == 'symlink':
1106
                inv.add(InventoryLink(file_id, name, parent))
1107
            else:
1108
                raise BzrError("unknown kind %r" % kind)
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1109
        self._write_inventory(inv)
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
1110
1457.1.10 by Robert Collins
Move set_root_id to WorkingTree.
1111
    @needs_write_lock
1112
    def set_root_id(self, file_id):
1113
        """Set the root id for this tree."""
1114
        inv = self.read_working_inventory()
1115
        orig_root_id = inv.root.file_id
1116
        del inv._byid[inv.root.file_id]
1117
        inv.root.file_id = file_id
1118
        inv._byid[inv.root.file_id] = inv.root
1119
        for fid in inv:
1120
            entry = inv[fid]
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1121
            if entry.parent_id == orig_root_id:
1457.1.10 by Robert Collins
Move set_root_id to WorkingTree.
1122
                entry.parent_id = inv.root.file_id
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1123
        self._write_inventory(inv)
1457.1.10 by Robert Collins
Move set_root_id to WorkingTree.
1124
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1125
    def unlock(self):
1126
        """See Branch.unlock.
1127
        
1128
        WorkingTree locking just uses the Branch locking facilities.
1129
        This is current because all working trees have an embedded branch
1130
        within them. IF in the future, we were to make branch data shareable
1131
        between multiple working trees, i.e. via shared storage, then we 
1132
        would probably want to lock both the local tree, and the branch.
1133
        """
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
1134
        # FIXME: We want to write out the hashcache only when the last lock on
1135
        # this working copy is released.  Peeking at the lock count is a bit
1136
        # of a nasty hack; probably it's better to have a transaction object,
1137
        # which can do some finalization when it's either successfully or
1138
        # unsuccessfully completed.  (Denys's original patch did that.)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1139
        # RBC 20060206 hookinhg into transaction will couple lock and transaction
1140
        # wrongly. Hookinh into unllock on the control files object is fine though.
1141
        
1142
        # TODO: split this per format so there is no ugly if block
1143
        if self._hashcache.needs_write and (
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
1144
            # dedicated lock files
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1145
            self._control_files._lock_count==1 or 
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
1146
            # shared lock files
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1147
            (self._control_files is self.branch.control_files and 
1534.5.3 by Robert Collins
Make format 4/5/6 branches share a single LockableFiles instance across wt/branch/repository.
1148
             self._control_files._lock_count==3)):
1185.60.6 by Aaron Bentley
Fixed hashcache
1149
            self._hashcache.write()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1150
        # reverse order of locking.
1151
        result = self._control_files.unlock()
1152
        try:
1153
            self.branch.unlock()
1154
        finally:
1155
            return result
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1156
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1157
    @needs_write_lock
1508.1.24 by Robert Collins
Add update command for use with checkouts.
1158
    def update(self):
1159
        self.branch.lock_read()
1160
        try:
1161
            if self.last_revision() == self.branch.last_revision():
1162
                return
1163
            basis = self.basis_tree()
1164
            to_tree = self.branch.basis_tree()
1165
            result = merge_inner(self.branch,
1166
                                 to_tree,
1167
                                 basis,
1168
                                 this_tree=self)
1169
            self.set_last_revision(self.branch.last_revision())
1170
            return result
1171
        finally:
1172
            self.branch.unlock()
1173
1174
    @needs_write_lock
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1175
    def _write_inventory(self, inv):
1176
        """Write inventory as the current inventory."""
1177
        sio = StringIO()
1178
        bzrlib.xml5.serializer_v5.write_inventory(inv, sio)
1179
        sio.seek(0)
1534.4.28 by Robert Collins
first cut at merge from integration.
1180
        self._control_files.put('inventory', sio)
1508.1.10 by Robert Collins
bzrlib.add.smart_add_branch is now smart_add_tree. (Robert Collins)
1181
        self._set_inventory(inv)
1457.1.11 by Robert Collins
Move _write_inventory to WorkingTree.
1182
        mutter('wrote working inventory')
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1183
1184
1185
class WorkingTree3(WorkingTree):
1186
    """This is the Format 3 working tree.
1187
1188
    This differs from the base WorkingTree by:
1189
     - having its own file lock
1190
     - having its own last-revision property.
1191
    """
1192
1193
    @needs_read_lock
1194
    def last_revision(self):
1195
        """See WorkingTree.last_revision."""
1196
        try:
1197
            return self._control_files.get_utf8('last-revision').read()
1198
        except NoSuchFile:
1199
            return None
1200
1201
    def _change_last_revision(self, revision_id):
1202
        """See WorkingTree._change_last_revision."""
1203
        if revision_id is None or revision_id == NULL_REVISION:
1204
            try:
1205
                self._control_files._transport.delete('last-revision')
1206
            except errors.NoSuchFile:
1207
                pass
1208
            return False
1209
        else:
1210
            try:
1211
                self.branch.revision_history().index(revision_id)
1212
            except ValueError:
1213
                raise errors.NoSuchRevision(self.branch, revision_id)
1214
            self._control_files.put_utf8('last-revision', revision_id)
1215
            return True
1216
1442.1.65 by Robert Collins
Branch.remove has been moved to WorkingTree.
1217
1185.14.6 by Aaron Bentley
Made iter_conflicts a WorkingTree method
1218
CONFLICT_SUFFIXES = ('.THIS', '.BASE', '.OTHER')
1219
def get_conflicted_stem(path):
1220
    for suffix in CONFLICT_SUFFIXES:
1221
        if path.endswith(suffix):
1222
            return path[:-len(suffix)]
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1223
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
1224
@deprecated_function(zero_eight)
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1225
def is_control_file(filename):
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
1226
    """See WorkingTree.is_control_filename(filename)."""
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1227
    ## FIXME: better check
1228
    filename = normpath(filename)
1229
    while filename != '':
1230
        head, tail = os.path.split(filename)
1231
        ## mutter('check %r for control file' % ((head, tail),))
1534.5.5 by Robert Collins
Move is_control_file into WorkingTree.is_control_filename and test.
1232
        if tail == '.bzr':
1534.4.41 by Robert Collins
Branch now uses BzrDir reasonably sanely.
1233
            return True
1234
        if filename == head:
1235
            break
1236
        filename = head
1237
    return False
1238
1239
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1240
class WorkingTreeFormat(object):
1241
    """An encapsulation of the initialization and open routines for a format.
1242
1243
    Formats provide three things:
1244
     * An initialization routine,
1245
     * a format string,
1246
     * an open routine.
1247
1248
    Formats are placed in an dict by their format string for reference 
1249
    during workingtree opening. Its not required that these be instances, they
1250
    can be classes themselves with class methods - it simply depends on 
1251
    whether state is needed for a given format or not.
1252
1253
    Once a format is deprecated, just deprecate the initialize and open
1254
    methods on the format class. Do not deprecate the object, as the 
1255
    object will be created every time regardless.
1256
    """
1257
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1258
    _default_format = None
1259
    """The default format used for new trees."""
1260
1261
    _formats = {}
1262
    """The known formats."""
1263
1264
    @classmethod
1265
    def find_format(klass, a_bzrdir):
1266
        """Return the format for the working tree object in a_bzrdir."""
1267
        try:
1268
            transport = a_bzrdir.get_workingtree_transport(None)
1269
            format_string = transport.get("format").read()
1270
            return klass._formats[format_string]
1271
        except NoSuchFile:
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1272
            raise errors.NoWorkingTree(base=transport.base)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1273
        except KeyError:
1274
            raise errors.UnknownFormatError(format_string)
1275
1276
    @classmethod
1277
    def get_default_format(klass):
1278
        """Return the current default format."""
1279
        return klass._default_format
1280
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1281
    def get_format_string(self):
1282
        """Return the ASCII format string that identifies this format."""
1283
        raise NotImplementedError(self.get_format_string)
1284
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1285
    def is_supported(self):
1286
        """Is this format supported?
1287
1288
        Supported formats can be initialized and opened.
1289
        Unsupported formats may not support initialization or committing or 
1290
        some other features depending on the reason for not being supported.
1291
        """
1292
        return True
1293
1294
    @classmethod
1295
    def register_format(klass, format):
1296
        klass._formats[format.get_format_string()] = format
1297
1298
    @classmethod
1299
    def set_default_format(klass, format):
1300
        klass._default_format = format
1301
1302
    @classmethod
1303
    def unregister_format(klass, format):
1304
        assert klass._formats[format.get_format_string()] is format
1305
        del klass._formats[format.get_format_string()]
1306
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1307
1308
1309
class WorkingTreeFormat2(WorkingTreeFormat):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1310
    """The second working tree format. 
1311
1312
    This format modified the hash cache from the format 1 hash cache.
1313
    """
1314
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1315
    def initialize(self, a_bzrdir, revision_id=None):
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1316
        """See WorkingTreeFormat.initialize()."""
1317
        if not isinstance(a_bzrdir.transport, LocalTransport):
1318
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1319
        branch = a_bzrdir.open_branch()
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1320
        if revision_id is not None:
1321
            branch.lock_write()
1322
            try:
1323
                revision_history = branch.revision_history()
1324
                try:
1325
                    position = revision_history.index(revision_id)
1326
                except ValueError:
1327
                    raise errors.NoSuchRevision(branch, revision_id)
1328
                branch.set_revision_history(revision_history[:position + 1])
1329
            finally:
1330
                branch.unlock()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1331
        revision = branch.last_revision()
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
1332
        inv = Inventory() 
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1333
        wt = WorkingTree(a_bzrdir.root_transport.base,
1334
                         branch,
1335
                         inv,
1336
                         _internal=True,
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
1337
                         _format=self,
1338
                         _bzrdir=a_bzrdir)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1339
        wt._write_inventory(inv)
1340
        wt.set_root_id(inv.root.file_id)
1341
        wt.set_last_revision(revision)
1342
        wt.set_pending_merges([])
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
1343
        build_tree(wt.basis_tree(), wt)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1344
        return wt
1345
1346
    def __init__(self):
1347
        super(WorkingTreeFormat2, self).__init__()
1348
        self._matchingbzrdir = bzrdir.BzrDirFormat6()
1534.4.42 by Robert Collins
add working tree to the BzrDir facilities.
1349
1350
    def open(self, a_bzrdir, _found=False):
1351
        """Return the WorkingTree object for a_bzrdir
1352
1353
        _found is a private parameter, do not use it. It is used to indicate
1354
               if format probing has already been done.
1355
        """
1356
        if not _found:
1357
            # we are being called directly and must probe.
1358
            raise NotImplementedError
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1359
        if not isinstance(a_bzrdir.transport, LocalTransport):
1360
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
1361
        return WorkingTree(a_bzrdir.root_transport.base,
1362
                           _internal=True,
1363
                           _format=self,
1364
                           _bzrdir=a_bzrdir)
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1365
1366
1367
class WorkingTreeFormat3(WorkingTreeFormat):
1368
    """The second working tree format updated to record a format marker.
1369
1370
    This format modified the hash cache from the format 1 hash cache.
1371
    """
1372
1373
    def get_format_string(self):
1374
        """See WorkingTreeFormat.get_format_string()."""
1375
        return "Bazaar-NG Working Tree format 3"
1376
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1377
    def initialize(self, a_bzrdir, revision_id=None):
1378
        """See WorkingTreeFormat.initialize().
1379
        
1380
        revision_id allows creating a working tree at a differnet
1381
        revision than the branch is at.
1382
        """
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1383
        if not isinstance(a_bzrdir.transport, LocalTransport):
1384
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1385
        transport = a_bzrdir.get_workingtree_transport(self)
1386
        control_files = LockableFiles(transport, 'lock')
1387
        control_files.put_utf8('format', self.get_format_string())
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1388
        branch = a_bzrdir.open_branch()
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1389
        if revision_id is None:
1390
            revision_id = branch.last_revision()
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
1391
        inv = Inventory() 
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1392
        wt = WorkingTree3(a_bzrdir.root_transport.base,
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
1393
                         branch,
1394
                         inv,
1395
                         _internal=True,
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
1396
                         _format=self,
1397
                         _bzrdir=a_bzrdir)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1398
        wt._write_inventory(inv)
1399
        wt.set_root_id(inv.root.file_id)
1508.1.21 by Robert Collins
Implement -r limit for checkout command.
1400
        wt.set_last_revision(revision_id)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1401
        wt.set_pending_merges([])
1534.7.165 by Aaron Bentley
Switched to build_tree instead of revert
1402
        build_tree(wt.basis_tree(), wt)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1403
        return wt
1404
1405
    def __init__(self):
1406
        super(WorkingTreeFormat3, self).__init__()
1407
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1534.4.45 by Robert Collins
Start WorkingTree -> .bzr/checkout transition
1408
1409
    def open(self, a_bzrdir, _found=False):
1410
        """Return the WorkingTree object for a_bzrdir
1411
1412
        _found is a private parameter, do not use it. It is used to indicate
1413
               if format probing has already been done.
1414
        """
1415
        if not _found:
1416
            # we are being called directly and must probe.
1417
            raise NotImplementedError
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1418
        if not isinstance(a_bzrdir.transport, LocalTransport):
1419
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
1420
        return WorkingTree3(a_bzrdir.root_transport.base,
1534.4.51 by Robert Collins
Test the disk layout of format3 working trees.
1421
                           _internal=True,
1422
                           _format=self,
1423
                           _bzrdir=a_bzrdir)
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1424
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
1425
    def __str__(self):
1426
        return self.get_format_string()
1427
1534.4.46 by Robert Collins
Nearly complete .bzr/checkout splitout.
1428
1429
# formats which have no format string are not discoverable
1430
# and not independently creatable, so are not registered.
1431
__default_format = WorkingTreeFormat3()
1432
WorkingTreeFormat.register_format(__default_format)
1433
WorkingTreeFormat.set_default_format(__default_format)
1434
_legacy_formats = [WorkingTreeFormat2(),
1435
                   ]
1436
1437
1438
class WorkingTreeTestProviderAdapter(object):
1439
    """A tool to generate a suite testing multiple workingtree formats at once.
1440
1441
    This is done by copying the test once for each transport and injecting
1442
    the transport_server, transport_readonly_server, and workingtree_format
1443
    classes into each copy. Each copy is also given a new id() to make it
1444
    easy to identify.
1445
    """
1446
1447
    def __init__(self, transport_server, transport_readonly_server, formats):
1448
        self._transport_server = transport_server
1449
        self._transport_readonly_server = transport_readonly_server
1450
        self._formats = formats
1451
    
1452
    def adapt(self, test):
1453
        from bzrlib.tests import TestSuite
1454
        result = TestSuite()
1455
        for workingtree_format, bzrdir_format in self._formats:
1456
            new_test = deepcopy(test)
1457
            new_test.transport_server = self._transport_server
1458
            new_test.transport_readonly_server = self._transport_readonly_server
1459
            new_test.bzrdir_format = bzrdir_format
1460
            new_test.workingtree_format = workingtree_format
1461
            def make_new_test_id():
1462
                new_id = "%s(%s)" % (new_test.id(), workingtree_format.__class__.__name__)
1463
                return lambda: new_id
1464
            new_test.id = make_new_test_id()
1465
            result.addTest(new_test)
1466
        return result