~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: John Arbash Meinel
  • Author(s): Mark Hammond
  • Date: 2008-09-09 17:02:21 UTC
  • mto: This revision was merged to the branch mainline in revision 3697.
  • Revision ID: john@arbash-meinel.com-20080909170221-svim3jw2mrz0amp3
An updated transparent icon for bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""WorkingTree object and friends.
18
18
 
19
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
 
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
23
new revision based on the workingtree and its inventory.
24
24
 
25
25
At the moment every WorkingTree has its own branch.  Remote
48
48
import itertools
49
49
import operator
50
50
import stat
 
51
from time import time
 
52
import warnings
51
53
import re
52
54
 
53
55
import bzrlib
55
57
    branch,
56
58
    bzrdir,
57
59
    conflicts as _mod_conflicts,
 
60
    dirstate,
58
61
    errors,
59
62
    generate_ids,
60
63
    globbing,
61
 
    graph as _mod_graph,
62
64
    hashcache,
63
65
    ignores,
64
 
    inventory,
65
66
    merge,
66
67
    revision as _mod_revision,
67
68
    revisiontree,
 
69
    repository,
68
70
    textui,
69
71
    trace,
70
72
    transform,
71
73
    ui,
72
 
    views,
 
74
    urlutils,
73
75
    xml5,
 
76
    xml6,
74
77
    xml7,
75
78
    )
76
79
import bzrlib.branch
77
80
from bzrlib.transport import get_transport
78
 
from bzrlib.workingtree_4 import (
79
 
    WorkingTreeFormat4,
80
 
    WorkingTreeFormat5,
81
 
    WorkingTreeFormat6,
82
 
    )
 
81
import bzrlib.ui
 
82
from bzrlib.workingtree_4 import WorkingTreeFormat4
83
83
""")
84
84
 
85
85
from bzrlib import symbol_versioning
86
86
from bzrlib.decorators import needs_read_lock, needs_write_lock
87
 
from bzrlib.lockable_files import LockableFiles
 
87
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, TreeReference
 
88
from bzrlib.lockable_files import LockableFiles, TransportLock
88
89
from bzrlib.lockdir import LockDir
89
90
import bzrlib.mutabletree
90
91
from bzrlib.mutabletree import needs_tree_write_lock
91
92
from bzrlib import osutils
92
93
from bzrlib.osutils import (
 
94
    compact_date,
93
95
    file_kind,
94
96
    isdir,
95
97
    normpath,
96
98
    pathjoin,
 
99
    rand_chars,
97
100
    realpath,
98
101
    safe_unicode,
99
102
    splitpath,
100
103
    supports_executable,
101
104
    )
102
 
from bzrlib.filters import filtered_input_file
103
105
from bzrlib.trace import mutter, note
104
106
from bzrlib.transport.local import LocalTransport
105
107
from bzrlib.progress import DummyProgress, ProgressPhase
106
 
from bzrlib.revision import CURRENT_REVISION
 
108
from bzrlib.revision import NULL_REVISION, CURRENT_REVISION
107
109
from bzrlib.rio import RioReader, rio_file, Stanza
108
 
from bzrlib.symbol_versioning import (
109
 
    deprecated_passed,
110
 
    DEPRECATED_PARAMETER,
111
 
    )
 
110
from bzrlib.symbol_versioning import (deprecated_passed,
 
111
        deprecated_method,
 
112
        deprecated_function,
 
113
        DEPRECATED_PARAMETER,
 
114
        )
112
115
 
113
116
 
114
117
MERGE_MODIFIED_HEADER_1 = "BZR merge-modified list format 1"
120
123
class TreeEntry(object):
121
124
    """An entry that implements the minimum interface used by commands.
122
125
 
123
 
    This needs further inspection, it may be better to have
 
126
    This needs further inspection, it may be better to have 
124
127
    InventoryEntries without ids - though that seems wrong. For now,
125
128
    this is a parallel hierarchy to InventoryEntry, and needs to become
126
129
    one of several things: decorates to that hierarchy, children of, or
129
132
    no InventoryEntry available - i.e. for unversioned objects.
130
133
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
131
134
    """
132
 
 
 
135
 
133
136
    def __eq__(self, other):
134
137
        # yes, this us ugly, TODO: best practice __eq__ style.
135
138
        return (isinstance(other, TreeEntry)
136
139
                and other.__class__ == self.__class__)
137
 
 
 
140
 
138
141
    def kind_character(self):
139
142
        return "???"
140
143
 
182
185
    not listed in the Inventory and vice versa.
183
186
    """
184
187
 
185
 
    # override this to set the strategy for storing views
186
 
    def _make_views(self):
187
 
        return views.DisabledViews(self)
188
 
 
189
188
    def __init__(self, basedir='.',
190
189
                 branch=DEPRECATED_PARAMETER,
191
190
                 _inventory=None,
226
225
        wt_trans = self.bzrdir.get_workingtree_transport(None)
227
226
        cache_filename = wt_trans.local_abspath('stat-cache')
228
227
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
229
 
            self.bzrdir._get_file_mode(),
230
 
            self._content_filter_stack_provider())
 
228
            self.bzrdir._get_file_mode())
231
229
        hc = self._hashcache
232
230
        hc.read()
233
231
        # is this scan needed ? it makes things kinda slow.
249
247
            self._set_inventory(_inventory, dirty=False)
250
248
        self._detect_case_handling()
251
249
        self._rules_searcher = None
252
 
        self.views = self._make_views()
253
250
 
254
251
    def _detect_case_handling(self):
255
252
        wt_trans = self.bzrdir.get_workingtree_transport(None)
281
278
        self._control_files.break_lock()
282
279
        self.branch.break_lock()
283
280
 
284
 
    def _get_check_refs(self):
285
 
        """Return the references needed to perform a check of this tree.
286
 
        
287
 
        The default implementation returns no refs, and is only suitable for
288
 
        trees that have no local caching and can commit on ghosts at any time.
289
 
 
290
 
        :seealso: bzrlib.check for details about check_refs.
291
 
        """
292
 
        return []
293
 
 
294
281
    def requires_rich_root(self):
295
282
        return self._format.requires_rich_root
296
283
 
297
284
    def supports_tree_reference(self):
298
285
        return False
299
286
 
300
 
    def supports_content_filtering(self):
301
 
        return self._format.supports_content_filtering()
302
 
 
303
 
    def supports_views(self):
304
 
        return self.views.supports_views()
305
 
 
306
287
    def _set_inventory(self, inv, dirty):
307
288
        """Set the internal cached inventory.
308
289
 
322
303
 
323
304
        """
324
305
        if path is None:
325
 
            path = osutils.getcwd()
 
306
            path = os.path.getcwdu()
326
307
        control = bzrdir.BzrDir.open(path, _unsupported)
327
308
        return control.open_workingtree(_unsupported)
328
 
 
 
309
        
329
310
    @staticmethod
330
311
    def open_containing(path=None):
331
312
        """Open an existing working tree which has its root about path.
332
 
 
 
313
        
333
314
        This probes for a working tree at path and searches upwards from there.
334
315
 
335
316
        Basically we keep looking up until we find the control directory or
396
377
 
397
378
    def basis_tree(self):
398
379
        """Return RevisionTree for the current last revision.
399
 
 
 
380
        
400
381
        If the left most parent is a ghost then the returned tree will be an
401
 
        empty tree - one obtained by calling
402
 
        repository.revision_tree(NULL_REVISION).
 
382
        empty tree - one obtained by calling repository.revision_tree(None).
403
383
        """
404
384
        try:
405
385
            revision_id = self.get_parent_ids()[0]
407
387
            # no parents, return an empty revision tree.
408
388
            # in the future this should return the tree for
409
389
            # 'empty:' - the implicit root empty tree.
410
 
            return self.branch.repository.revision_tree(
411
 
                       _mod_revision.NULL_REVISION)
 
390
            return self.branch.repository.revision_tree(None)
412
391
        try:
413
392
            return self.revision_tree(revision_id)
414
393
        except errors.NoSuchRevision:
420
399
            return self.branch.repository.revision_tree(revision_id)
421
400
        except (errors.RevisionNotPresent, errors.NoSuchRevision):
422
401
            # the basis tree *may* be a ghost or a low level error may have
423
 
            # occurred. If the revision is present, its a problem, if its not
 
402
            # occured. If the revision is present, its a problem, if its not
424
403
            # its a ghost.
425
404
            if self.branch.repository.has_revision(revision_id):
426
405
                raise
427
406
            # the basis tree is a ghost so return an empty tree.
428
 
            return self.branch.repository.revision_tree(
429
 
                       _mod_revision.NULL_REVISION)
 
407
            return self.branch.repository.revision_tree(None)
430
408
 
431
409
    def _cleanup(self):
432
410
        self._flush_ignore_list_cache()
433
411
 
434
412
    def relpath(self, path):
435
413
        """Return the local path portion from a given path.
436
 
 
437
 
        The path may be absolute or relative. If its a relative path it is
 
414
        
 
415
        The path may be absolute or relative. If its a relative path it is 
438
416
        interpreted relative to the python current working directory.
439
417
        """
440
418
        return osutils.relpath(self.basedir, path)
442
420
    def has_filename(self, filename):
443
421
        return osutils.lexists(self.abspath(filename))
444
422
 
445
 
    def get_file(self, file_id, path=None, filtered=True):
446
 
        return self.get_file_with_stat(file_id, path, filtered=filtered)[0]
447
 
 
448
 
    def get_file_with_stat(self, file_id, path=None, filtered=True,
449
 
        _fstat=os.fstat):
450
 
        """See Tree.get_file_with_stat."""
 
423
    def get_file(self, file_id, path=None):
451
424
        if path is None:
452
425
            path = self.id2path(file_id)
453
 
        file_obj = self.get_file_byname(path, filtered=False)
454
 
        stat_value = _fstat(file_obj.fileno())
455
 
        if filtered and self.supports_content_filtering():
456
 
            filters = self._content_filter_stack(path)
457
 
            file_obj = filtered_input_file(file_obj, filters)
458
 
        return (file_obj, stat_value)
459
 
 
460
 
    def get_file_text(self, file_id, path=None, filtered=True):
461
 
        return self.get_file(file_id, path=path, filtered=filtered).read()
462
 
 
463
 
    def get_file_byname(self, filename, filtered=True):
464
 
        path = self.abspath(filename)
465
 
        f = file(path, 'rb')
466
 
        if filtered and self.supports_content_filtering():
467
 
            filters = self._content_filter_stack(filename)
468
 
            return filtered_input_file(f, filters)
469
 
        else:
470
 
            return f
471
 
 
472
 
    def get_file_lines(self, file_id, path=None, filtered=True):
473
 
        """See Tree.get_file_lines()"""
474
 
        file = self.get_file(file_id, path, filtered=filtered)
475
 
        try:
476
 
            return file.readlines()
477
 
        finally:
478
 
            file.close()
 
426
        return self.get_file_byname(path)
 
427
 
 
428
    def get_file_text(self, file_id):
 
429
        return self.get_file(file_id).read()
 
430
 
 
431
    def get_file_byname(self, filename):
 
432
        return file(self.abspath(filename), 'rb')
479
433
 
480
434
    @needs_read_lock
481
435
    def annotate_iter(self, file_id, default_revision=CURRENT_REVISION):
488
442
        incorrectly attributed to CURRENT_REVISION (but after committing, the
489
443
        attribution will be correct).
490
444
        """
491
 
        maybe_file_parent_keys = []
492
 
        for parent_id in self.get_parent_ids():
493
 
            try:
494
 
                parent_tree = self.revision_tree(parent_id)
495
 
            except errors.NoSuchRevisionInTree:
496
 
                parent_tree = self.branch.repository.revision_tree(parent_id)
497
 
            parent_tree.lock_read()
498
 
            try:
499
 
                if file_id not in parent_tree:
500
 
                    continue
501
 
                ie = parent_tree.inventory[file_id]
502
 
                if ie.kind != 'file':
503
 
                    # Note: this is slightly unnecessary, because symlinks and
504
 
                    # directories have a "text" which is the empty text, and we
505
 
                    # know that won't mess up annotations. But it seems cleaner
506
 
                    continue
507
 
                parent_text_key = (file_id, ie.revision)
508
 
                if parent_text_key not in maybe_file_parent_keys:
509
 
                    maybe_file_parent_keys.append(parent_text_key)
510
 
            finally:
511
 
                parent_tree.unlock()
512
 
        graph = _mod_graph.Graph(self.branch.repository.texts)
513
 
        heads = graph.heads(maybe_file_parent_keys)
514
 
        file_parent_keys = []
515
 
        for key in maybe_file_parent_keys:
516
 
            if key in heads:
517
 
                file_parent_keys.append(key)
518
 
 
519
 
        # Now we have the parents of this content
520
 
        annotator = self.branch.repository.texts.get_annotator()
521
 
        text = self.get_file(file_id).read()
522
 
        this_key =(file_id, default_revision)
523
 
        annotator.add_special_text(this_key, file_parent_keys, text)
524
 
        annotations = [(key[-1], line)
525
 
                       for key, line in annotator.annotate_flat(this_key)]
526
 
        return annotations
 
445
        basis = self.basis_tree()
 
446
        basis.lock_read()
 
447
        try:
 
448
            changes = self.iter_changes(basis, True, [self.id2path(file_id)],
 
449
                require_versioned=True).next()
 
450
            changed_content, kind = changes[2], changes[6]
 
451
            if not changed_content:
 
452
                return basis.annotate_iter(file_id)
 
453
            if kind[1] is None:
 
454
                return None
 
455
            import annotate
 
456
            if kind[0] != 'file':
 
457
                old_lines = []
 
458
            else:
 
459
                old_lines = list(basis.annotate_iter(file_id))
 
460
            old = [old_lines]
 
461
            for tree in self.branch.repository.revision_trees(
 
462
                self.get_parent_ids()[1:]):
 
463
                if file_id not in tree:
 
464
                    continue
 
465
                old.append(list(tree.annotate_iter(file_id)))
 
466
            return annotate.reannotate(old, self.get_file(file_id).readlines(),
 
467
                                       default_revision)
 
468
        finally:
 
469
            basis.unlock()
527
470
 
528
471
    def _get_ancestors(self, default_revision):
529
472
        ancestors = set([default_revision])
534
477
 
535
478
    def get_parent_ids(self):
536
479
        """See Tree.get_parent_ids.
537
 
 
 
480
        
538
481
        This implementation reads the pending merges list and last_revision
539
482
        value and uses that to decide what the parents list should be.
540
483
        """
557
500
    def get_root_id(self):
558
501
        """Return the id of this trees root"""
559
502
        return self._inventory.root.file_id
560
 
 
 
503
        
561
504
    def _get_store_filename(self, file_id):
562
505
        ## XXX: badly named; this is not in the store at all
563
506
        return self.abspath(self.id2path(file_id))
565
508
    @needs_read_lock
566
509
    def clone(self, to_bzrdir, revision_id=None):
567
510
        """Duplicate this working tree into to_bzr, including all state.
568
 
 
 
511
        
569
512
        Specifically modified files are kept as modified, but
570
513
        ignored and unknown files are discarded.
571
514
 
572
515
        If you want to make a new line of development, see bzrdir.sprout()
573
516
 
574
517
        revision
575
 
            If not None, the cloned tree will have its last revision set to
576
 
            revision, and difference between the source trees last revision
 
518
            If not None, the cloned tree will have its last revision set to 
 
519
            revision, and and difference between the source trees last revision
577
520
            and this one merged in.
578
521
        """
579
522
        # assumes the target bzr dir format is compatible.
661
604
        """See MutableTree._add."""
662
605
        # TODO: Re-adding a file that is removed in the working copy
663
606
        # should probably put it back with the previous ID.
664
 
        # the read and write working inventory should not occur in this
 
607
        # the read and write working inventory should not occur in this 
665
608
        # function - they should be part of lock_write and unlock.
666
609
        inv = self.inventory
667
610
        for f, file_id, kind in zip(files, ids, kinds):
761
704
                kind = 'tree-reference'
762
705
            return kind, None, None, None
763
706
        elif kind == 'symlink':
764
 
            target = osutils.readlink(abspath)
765
 
            return ('symlink', None, None, target)
 
707
            return ('symlink', None, None, os.readlink(abspath))
766
708
        else:
767
709
            return (kind, None, None, None)
768
710
 
781
723
    def _set_merges_from_parent_ids(self, parent_ids):
782
724
        merges = parent_ids[1:]
783
725
        self._transport.put_bytes('pending-merges', '\n'.join(merges),
784
 
            mode=self.bzrdir._get_file_mode())
 
726
            mode=self._control_files._file_mode)
785
727
 
786
728
    def _filter_parent_ids_by_ancestry(self, revision_ids):
787
729
        """Check that all merged revisions are proper 'heads'.
788
730
 
789
731
        This will always return the first revision_id, and any merged revisions
790
 
        which are
 
732
        which are 
791
733
        """
792
734
        if len(revision_ids) == 0:
793
735
            return revision_ids
805
747
    @needs_tree_write_lock
806
748
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
807
749
        """Set the parent ids to revision_ids.
808
 
 
 
750
        
809
751
        See also set_parent_trees. This api will try to retrieve the tree data
810
752
        for each element of revision_ids from the trees repository. If you have
811
753
        tree data already available, it is more efficient to use
887
829
        self._must_be_locked()
888
830
        my_file = rio_file(stanzas, header)
889
831
        self._transport.put_file(filename, my_file,
890
 
            mode=self.bzrdir._get_file_mode())
 
832
            mode=self._control_files._file_mode)
891
833
 
892
834
    @needs_write_lock # because merge pulls data into the branch.
893
835
    def merge_from_branch(self, branch, to_revision=None, from_revision=None,
901
843
            branch.last_revision().
902
844
        """
903
845
        from bzrlib.merge import Merger, Merge3Merger
904
 
        pb = ui.ui_factory.nested_progress_bar()
 
846
        pb = bzrlib.ui.ui_factory.nested_progress_bar()
905
847
        try:
906
848
            merger = Merger(self.branch, this_tree=self, pb=pb)
907
849
            merger.pp = ProgressPhase("Merge phase", 5, pb)
944
886
    def merge_modified(self):
945
887
        """Return a dictionary of files modified by a merge.
946
888
 
947
 
        The list is initialized by WorkingTree.set_merge_modified, which is
 
889
        The list is initialized by WorkingTree.set_merge_modified, which is 
948
890
        typically called after we make some automatic updates to the tree
949
891
        because of a merge.
950
892
 
955
897
            hashfile = self._transport.get('merge-hashes')
956
898
        except errors.NoSuchFile:
957
899
            return {}
 
900
        merge_hashes = {}
958
901
        try:
959
 
            merge_hashes = {}
960
 
            try:
961
 
                if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
962
 
                    raise errors.MergeModifiedFormatError()
963
 
            except StopIteration:
 
902
            if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
964
903
                raise errors.MergeModifiedFormatError()
965
 
            for s in RioReader(hashfile):
966
 
                # RioReader reads in Unicode, so convert file_ids back to utf8
967
 
                file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
968
 
                if file_id not in self.inventory:
969
 
                    continue
970
 
                text_hash = s.get("hash")
971
 
                if text_hash == self.get_file_sha1(file_id):
972
 
                    merge_hashes[file_id] = text_hash
973
 
            return merge_hashes
974
 
        finally:
975
 
            hashfile.close()
 
904
        except StopIteration:
 
905
            raise errors.MergeModifiedFormatError()
 
906
        for s in RioReader(hashfile):
 
907
            # RioReader reads in Unicode, so convert file_ids back to utf8
 
908
            file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
 
909
            if file_id not in self.inventory:
 
910
                continue
 
911
            text_hash = s.get("hash")
 
912
            if text_hash == self.get_file_sha1(file_id):
 
913
                merge_hashes[file_id] = text_hash
 
914
        return merge_hashes
976
915
 
977
916
    @needs_write_lock
978
917
    def mkdir(self, path, file_id=None):
984
923
        return file_id
985
924
 
986
925
    def get_symlink_target(self, file_id):
987
 
        abspath = self.id2abspath(file_id)
988
 
        target = osutils.readlink(abspath)
989
 
        return target
 
926
        return os.readlink(self.id2abspath(file_id))
990
927
 
991
928
    @needs_write_lock
992
929
    def subsume(self, other_tree):
1042
979
        return False
1043
980
 
1044
981
    def _directory_may_be_tree_reference(self, relpath):
1045
 
        # as a special case, if a directory contains control files then
 
982
        # as a special case, if a directory contains control files then 
1046
983
        # it's a tree reference, except that the root of the tree is not
1047
984
        return relpath and osutils.isdir(self.abspath(relpath) + u"/.bzr")
1048
985
        # TODO: We could ask all the control formats whether they
1059
996
    @needs_tree_write_lock
1060
997
    def extract(self, file_id, format=None):
1061
998
        """Extract a subtree from this tree.
1062
 
 
 
999
        
1063
1000
        A new branch will be created, relative to the path for this tree.
1064
1001
        """
1065
1002
        self.flush()
1070
1007
                transport = transport.clone(name)
1071
1008
                transport.ensure_base()
1072
1009
            return transport
1073
 
 
 
1010
            
1074
1011
        sub_path = self.id2path(file_id)
1075
1012
        branch_transport = mkdirs(sub_path)
1076
1013
        if format is None:
1093
1030
            branch.BranchReferenceFormat().initialize(tree_bzrdir, new_branch)
1094
1031
        else:
1095
1032
            tree_bzrdir = branch_bzrdir
1096
 
        wt = tree_bzrdir.create_workingtree(_mod_revision.NULL_REVISION)
 
1033
        wt = tree_bzrdir.create_workingtree(NULL_REVISION)
1097
1034
        wt.set_parent_ids(self.get_parent_ids())
1098
1035
        my_inv = self.inventory
1099
 
        child_inv = inventory.Inventory(root_id=None)
 
1036
        child_inv = Inventory(root_id=None)
1100
1037
        new_root = my_inv[file_id]
1101
1038
        my_inv.remove_recursive_id(file_id)
1102
1039
        new_root.parent_id = None
1121
1058
        self._serialize(self._inventory, sio)
1122
1059
        sio.seek(0)
1123
1060
        self._transport.put_file('inventory', sio,
1124
 
            mode=self.bzrdir._get_file_mode())
 
1061
            mode=self._control_files._file_mode)
1125
1062
        self._inventory_is_modified = False
1126
1063
 
1127
1064
    def _kind(self, relpath):
1128
1065
        return osutils.file_kind(self.abspath(relpath))
1129
1066
 
1130
 
    def list_files(self, include_root=False, from_dir=None, recursive=True):
1131
 
        """List all files as (path, class, kind, id, entry).
 
1067
    def list_files(self, include_root=False):
 
1068
        """Recursively list all files as (path, class, kind, id, entry).
1132
1069
 
1133
1070
        Lists, but does not descend into unversioned directories.
 
1071
 
1134
1072
        This does not include files that have been deleted in this
1135
 
        tree. Skips the control directory.
 
1073
        tree.
1136
1074
 
1137
 
        :param include_root: if True, do not return an entry for the root
1138
 
        :param from_dir: start from this directory or None for the root
1139
 
        :param recursive: whether to recurse into subdirectories or not
 
1075
        Skips the control directory.
1140
1076
        """
1141
1077
        # list_files is an iterator, so @needs_read_lock doesn't work properly
1142
1078
        # with it. So callers should be careful to always read_lock the tree.
1144
1080
            raise errors.ObjectNotLocked(self)
1145
1081
 
1146
1082
        inv = self.inventory
1147
 
        if from_dir is None and include_root is True:
 
1083
        if include_root is True:
1148
1084
            yield ('', 'V', 'directory', inv.root.file_id, inv.root)
1149
1085
        # Convert these into local objects to save lookup times
1150
1086
        pathjoin = osutils.pathjoin
1157
1093
        fk_entries = {'directory':TreeDirectory, 'file':TreeFile, 'symlink':TreeLink}
1158
1094
 
1159
1095
        # directory file_id, relative path, absolute path, reverse sorted children
1160
 
        if from_dir is not None:
1161
 
            from_dir_id = inv.path2id(from_dir)
1162
 
            if from_dir_id is None:
1163
 
                # Directory not versioned
1164
 
                return
1165
 
            from_dir_abspath = pathjoin(self.basedir, from_dir)
1166
 
        else:
1167
 
            from_dir_id = inv.root.file_id
1168
 
            from_dir_abspath = self.basedir
1169
 
        children = os.listdir(from_dir_abspath)
 
1096
        children = os.listdir(self.basedir)
1170
1097
        children.sort()
1171
 
        # jam 20060527 The kernel sized tree seems equivalent whether we
 
1098
        # jam 20060527 The kernel sized tree seems equivalent whether we 
1172
1099
        # use a deque and popleft to keep them sorted, or if we use a plain
1173
1100
        # list and just reverse() them.
1174
1101
        children = collections.deque(children)
1175
 
        stack = [(from_dir_id, u'', from_dir_abspath, children)]
 
1102
        stack = [(inv.root.file_id, u'', self.basedir, children)]
1176
1103
        while stack:
1177
1104
            from_dir_id, from_dir_relpath, from_dir_abspath, children = stack[-1]
1178
1105
 
1194
1121
 
1195
1122
                # absolute path
1196
1123
                fap = from_dir_abspath + '/' + f
1197
 
 
 
1124
                
1198
1125
                f_ie = inv.get_child(from_dir_id, f)
1199
1126
                if f_ie:
1200
1127
                    c = 'V'
1232
1159
                    except KeyError:
1233
1160
                        yield fp[1:], c, fk, None, TreeEntry()
1234
1161
                    continue
1235
 
 
 
1162
                
1236
1163
                if fk != 'directory':
1237
1164
                    continue
1238
1165
 
1239
 
                # But do this child first if recursing down
1240
 
                if recursive:
1241
 
                    new_children = os.listdir(fap)
1242
 
                    new_children.sort()
1243
 
                    new_children = collections.deque(new_children)
1244
 
                    stack.append((f_ie.file_id, fp, fap, new_children))
1245
 
                    # Break out of inner loop,
1246
 
                    # so that we start outer loop with child
1247
 
                    break
 
1166
                # But do this child first
 
1167
                new_children = os.listdir(fap)
 
1168
                new_children.sort()
 
1169
                new_children = collections.deque(new_children)
 
1170
                stack.append((f_ie.file_id, fp, fap, new_children))
 
1171
                # Break out of inner loop,
 
1172
                # so that we start outer loop with child
 
1173
                break
1248
1174
            else:
1249
1175
                # if we finished all children, pop it off the stack
1250
1176
                stack.pop()
1256
1182
        to_dir must exist in the inventory.
1257
1183
 
1258
1184
        If to_dir exists and is a directory, the files are moved into
1259
 
        it, keeping their old names.
 
1185
        it, keeping their old names.  
1260
1186
 
1261
1187
        Note that to_dir is only the last component of the new name;
1262
1188
        this doesn't change the directory.
1428
1354
        inv = self.inventory
1429
1355
        for entry in moved:
1430
1356
            try:
1431
 
                self._move_entry(WorkingTree._RenameEntry(
1432
 
                    entry.to_rel, entry.from_id,
 
1357
                self._move_entry(_RenameEntry(entry.to_rel, entry.from_id,
1433
1358
                    entry.to_tail, entry.to_parent_id, entry.from_rel,
1434
1359
                    entry.from_tail, entry.from_parent_id,
1435
1360
                    entry.only_change_inv))
1486
1411
        from_tail = splitpath(from_rel)[-1]
1487
1412
        from_id = inv.path2id(from_rel)
1488
1413
        if from_id is None:
1489
 
            # if file is missing in the inventory maybe it's in the basis_tree
1490
 
            basis_tree = self.branch.basis_tree()
1491
 
            from_id = basis_tree.path2id(from_rel)
1492
 
            if from_id is None:
1493
 
                raise errors.BzrRenameFailedError(from_rel,to_rel,
1494
 
                    errors.NotVersionedError(path=str(from_rel)))
1495
 
            # put entry back in the inventory so we can rename it
1496
 
            from_entry = basis_tree.inventory[from_id].copy()
1497
 
            inv.add(from_entry)
1498
 
        else:
1499
 
            from_entry = inv[from_id]
 
1414
            raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1415
                errors.NotVersionedError(path=str(from_rel)))
 
1416
        from_entry = inv[from_id]
1500
1417
        from_parent_id = from_entry.parent_id
1501
1418
        to_dir, to_tail = os.path.split(to_rel)
1502
1419
        to_dir_id = inv.path2id(to_dir)
1548
1465
        These are files in the working directory that are not versioned or
1549
1466
        control files or ignored.
1550
1467
        """
1551
 
        # force the extras method to be fully executed before returning, to
 
1468
        # force the extras method to be fully executed before returning, to 
1552
1469
        # prevent race conditions with the lock
1553
1470
        return iter(
1554
1471
            [subp for subp in self.extras() if not self.is_ignored(subp)])
1564
1481
        :raises: NoSuchId if any fileid is not currently versioned.
1565
1482
        """
1566
1483
        for file_id in file_ids:
1567
 
            if file_id not in self._inventory:
1568
 
                raise errors.NoSuchId(self, file_id)
1569
 
        for file_id in file_ids:
1570
1484
            if self._inventory.has_id(file_id):
1571
1485
                self._inventory.remove_recursive_id(file_id)
 
1486
            else:
 
1487
                raise errors.NoSuchId(self, file_id)
1572
1488
        if len(file_ids):
1573
 
            # in the future this should just set a dirty bit to wait for the
 
1489
            # in the future this should just set a dirty bit to wait for the 
1574
1490
            # final unlock. However, until all methods of workingtree start
1575
 
            # with the current in -memory inventory rather than triggering
 
1491
            # with the current in -memory inventory rather than triggering 
1576
1492
            # a read, it is more complex - we need to teach read_inventory
1577
1493
            # to know when to read, and when to not read first... and possibly
1578
1494
            # to save first when the in memory one may be corrupted.
1579
1495
            # so for now, we just only write it if it is indeed dirty.
1580
1496
            # - RBC 20060907
1581
1497
            self._write_inventory(self._inventory)
1582
 
 
 
1498
    
1583
1499
    def _iter_conflicts(self):
1584
1500
        conflicted = set()
1585
1501
        for info in self.list_files():
1593
1509
 
1594
1510
    @needs_write_lock
1595
1511
    def pull(self, source, overwrite=False, stop_revision=None,
1596
 
             change_reporter=None, possible_transports=None, local=False):
1597
 
        top_pb = ui.ui_factory.nested_progress_bar()
 
1512
             change_reporter=None, possible_transports=None):
 
1513
        top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1598
1514
        source.lock_read()
1599
1515
        try:
1600
1516
            pp = ProgressPhase("Pull phase", 2, top_pb)
1602
1518
            old_revision_info = self.branch.last_revision_info()
1603
1519
            basis_tree = self.basis_tree()
1604
1520
            count = self.branch.pull(source, overwrite, stop_revision,
1605
 
                                     possible_transports=possible_transports,
1606
 
                                     local=local)
 
1521
                                     possible_transports=possible_transports)
1607
1522
            new_revision_info = self.branch.last_revision_info()
1608
1523
            if new_revision_info != old_revision_info:
1609
1524
                pp.next_phase()
1610
1525
                repository = self.branch.repository
1611
 
                pb = ui.ui_factory.nested_progress_bar()
 
1526
                pb = bzrlib.ui.ui_factory.nested_progress_bar()
1612
1527
                basis_tree.lock_read()
1613
1528
                try:
1614
1529
                    new_basis_tree = self.branch.basis_tree()
1629
1544
                # reuse the revisiontree we merged against to set the new
1630
1545
                # tree data.
1631
1546
                parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1632
 
                # we have to pull the merge trees out again, because
1633
 
                # merge_inner has set the ids. - this corner is not yet
 
1547
                # we have to pull the merge trees out again, because 
 
1548
                # merge_inner has set the ids. - this corner is not yet 
1634
1549
                # layered well enough to prevent double handling.
1635
1550
                # XXX TODO: Fix the double handling: telling the tree about
1636
1551
                # the already known parent data is wasteful.
1674
1589
 
1675
1590
            fl = []
1676
1591
            for subf in os.listdir(dirabs):
1677
 
                if self.bzrdir.is_control_filename(subf):
 
1592
                if subf == '.bzr':
1678
1593
                    continue
1679
1594
                if subf not in dir_entry.children:
1680
1595
                    try:
1690
1605
                            fl.append(subf_norm)
1691
1606
                    else:
1692
1607
                        fl.append(subf)
1693
 
 
 
1608
            
1694
1609
            fl.sort()
1695
1610
            for subf in fl:
1696
1611
                subp = pathjoin(path, subf)
1847
1762
 
1848
1763
    def _change_last_revision(self, new_revision):
1849
1764
        """Template method part of set_last_revision to perform the change.
1850
 
 
 
1765
        
1851
1766
        This is used to allow WorkingTree3 instances to not affect branch
1852
1767
        when their last revision is set.
1853
1768
        """
1866
1781
        path = self._basis_inventory_name()
1867
1782
        sio = StringIO(xml)
1868
1783
        self._transport.put_file(path, sio,
1869
 
            mode=self.bzrdir._get_file_mode())
 
1784
            mode=self._control_files._file_mode)
1870
1785
 
1871
1786
    def _create_basis_xml_from_inventory(self, revision_id, inventory):
1872
1787
        """Create the text that will be saved in basis-inventory"""
1879
1794
        # as commit already has that ready-to-use [while the format is the
1880
1795
        # same, that is].
1881
1796
        try:
1882
 
            # this double handles the inventory - unpack and repack -
 
1797
            # this double handles the inventory - unpack and repack - 
1883
1798
            # but is easier to understand. We can/should put a conditional
1884
1799
            # in here based on whether the inventory is in the latest format
1885
1800
            # - perhaps we should repack all inventories on a repository
1886
1801
            # upgrade ?
1887
1802
            # the fast path is to copy the raw xml from the repository. If the
1888
 
            # xml contains 'revision_id="', then we assume the right
 
1803
            # xml contains 'revision_id="', then we assume the right 
1889
1804
            # revision_id is set. We must check for this full string, because a
1890
1805
            # root node id can legitimately look like 'revision_id' but cannot
1891
1806
            # contain a '"'.
1892
1807
            xml = self.branch.repository.get_inventory_xml(new_revision)
1893
1808
            firstline = xml.split('\n', 1)[0]
1894
 
            if (not 'revision_id="' in firstline or
 
1809
            if (not 'revision_id="' in firstline or 
1895
1810
                'format="7"' not in firstline):
1896
1811
                inv = self.branch.repository.deserialise_inventory(
1897
1812
                    new_revision, xml)
1904
1819
        """Read the cached basis inventory."""
1905
1820
        path = self._basis_inventory_name()
1906
1821
        return self._transport.get_bytes(path)
1907
 
 
 
1822
        
1908
1823
    @needs_read_lock
1909
1824
    def read_working_inventory(self):
1910
1825
        """Read the working inventory.
1911
 
 
 
1826
        
1912
1827
        :raises errors.InventoryModified: read_working_inventory will fail
1913
1828
            when the current in memory inventory has been modified.
1914
1829
        """
1915
 
        # conceptually this should be an implementation detail of the tree.
 
1830
        # conceptually this should be an implementation detail of the tree. 
1916
1831
        # XXX: Deprecate this.
1917
1832
        # ElementTree does its own conversion from UTF-8, so open in
1918
1833
        # binary.
2000
1915
                        tree_delta.unversioned.extend((unknown_file,))
2001
1916
                raise errors.BzrRemoveChangedFilesError(tree_delta)
2002
1917
 
2003
 
        # Build inv_delta and delete files where applicable,
 
1918
        # Build inv_delta and delete files where applicaple,
2004
1919
        # do this before any modifications to inventory.
2005
1920
        for f in files:
2006
1921
            fid = self.path2id(f)
2063
1978
            if filenames is None and len(self.get_parent_ids()) > 1:
2064
1979
                parent_trees = []
2065
1980
                last_revision = self.last_revision()
2066
 
                if last_revision != _mod_revision.NULL_REVISION:
 
1981
                if last_revision != NULL_REVISION:
2067
1982
                    if basis_tree is None:
2068
1983
                        basis_tree = self.basis_tree()
2069
1984
                        basis_tree.lock_read()
2107
2022
    def set_inventory(self, new_inventory_list):
2108
2023
        from bzrlib.inventory import (Inventory,
2109
2024
                                      InventoryDirectory,
 
2025
                                      InventoryEntry,
2110
2026
                                      InventoryFile,
2111
2027
                                      InventoryLink)
2112
2028
        inv = Inventory(self.get_root_id())
2114
2030
            name = os.path.basename(path)
2115
2031
            if name == "":
2116
2032
                continue
2117
 
            # fixme, there should be a factory function inv,add_??
 
2033
            # fixme, there should be a factory function inv,add_?? 
2118
2034
            if kind == 'directory':
2119
2035
                inv.add(InventoryDirectory(file_id, name, parent))
2120
2036
            elif kind == 'file':
2128
2044
    @needs_tree_write_lock
2129
2045
    def set_root_id(self, file_id):
2130
2046
        """Set the root id for this tree."""
2131
 
        # for compatability
 
2047
        # for compatability 
2132
2048
        if file_id is None:
2133
2049
            raise ValueError(
2134
2050
                'WorkingTree.set_root_id with fileid=None')
2138
2054
    def _set_root_id(self, file_id):
2139
2055
        """Set the root id for this tree, in a format specific manner.
2140
2056
 
2141
 
        :param file_id: The file id to assign to the root. It must not be
 
2057
        :param file_id: The file id to assign to the root. It must not be 
2142
2058
            present in the current inventory or an error will occur. It must
2143
2059
            not be None, but rather a valid file id.
2144
2060
        """
2163
2079
 
2164
2080
    def unlock(self):
2165
2081
        """See Branch.unlock.
2166
 
 
 
2082
        
2167
2083
        WorkingTree locking just uses the Branch locking facilities.
2168
2084
        This is current because all working trees have an embedded branch
2169
2085
        within them. IF in the future, we were to make branch data shareable
2170
 
        between multiple working trees, i.e. via shared storage, then we
 
2086
        between multiple working trees, i.e. via shared storage, then we 
2171
2087
        would probably want to lock both the local tree, and the branch.
2172
2088
        """
2173
2089
        raise NotImplementedError(self.unlock)
2225
2141
        # cant set that until we update the working trees last revision to be
2226
2142
        # one from the new branch, because it will just get absorbed by the
2227
2143
        # parent de-duplication logic.
2228
 
        #
 
2144
        # 
2229
2145
        # We MUST save it even if an error occurs, because otherwise the users
2230
2146
        # local work is unreferenced and will appear to have been lost.
2231
 
        #
 
2147
        # 
2232
2148
        result = 0
2233
2149
        try:
2234
2150
            last_rev = self.get_parent_ids()[0]
2256
2172
            parent_trees = [(self.branch.last_revision(), to_tree)]
2257
2173
            merges = self.get_parent_ids()[1:]
2258
2174
            # Ideally we ask the tree for the trees here, that way the working
2259
 
            # tree can decide whether to give us the entire tree or give us a
 
2175
            # tree can decide whether to give us teh entire tree or give us a
2260
2176
            # lazy initialised tree. dirstate for instance will have the trees
2261
2177
            # in ram already, whereas a last-revision + basis-inventory tree
2262
2178
            # will not, but also does not need them when setting parents.
2404
2320
                    # value.
2405
2321
                    bzrdir_loc = bisect_left(cur_disk_dir_content,
2406
2322
                        ('.bzr', '.bzr'))
2407
 
                    if (bzrdir_loc < len(cur_disk_dir_content)
2408
 
                        and self.bzrdir.is_control_filename(
2409
 
                            cur_disk_dir_content[bzrdir_loc][0])):
 
2323
                    if cur_disk_dir_content[bzrdir_loc][0] == '.bzr':
2410
2324
                        # we dont yield the contents of, or, .bzr itself.
2411
2325
                        del cur_disk_dir_content[bzrdir_loc]
2412
2326
            if inv_finished:
2546
2460
        return un_resolved, resolved
2547
2461
 
2548
2462
    @needs_read_lock
2549
 
    def _check(self, references):
2550
 
        """Check the tree for consistency.
2551
 
 
2552
 
        :param references: A dict with keys matching the items returned by
2553
 
            self._get_check_refs(), and values from looking those keys up in
2554
 
            the repository.
2555
 
        """
 
2463
    def _check(self):
2556
2464
        tree_basis = self.basis_tree()
2557
2465
        tree_basis.lock_read()
2558
2466
        try:
2559
 
            repo_basis = references[('trees', self.last_revision())]
 
2467
            repo_basis = self.branch.repository.revision_tree(
 
2468
                self.last_revision())
2560
2469
            if len(list(repo_basis.iter_changes(tree_basis))) > 0:
2561
2470
                raise errors.BzrCheckError(
2562
2471
                    "Mismatched basis inventory content.")
2583
2492
                self)._get_rules_searcher(default_searcher)
2584
2493
        return self._rules_searcher
2585
2494
 
2586
 
    def get_shelf_manager(self):
2587
 
        """Return the ShelfManager for this WorkingTree."""
2588
 
        from bzrlib.shelf import ShelfManager
2589
 
        return ShelfManager(self, self._transport)
2590
 
 
2591
2495
 
2592
2496
class WorkingTree2(WorkingTree):
2593
2497
    """This is the Format 2 working tree.
2594
2498
 
2595
 
    This was the first weave based working tree.
 
2499
    This was the first weave based working tree. 
2596
2500
     - uses os locks for locking.
2597
2501
     - uses the branch last-revision.
2598
2502
    """
2608
2512
        if self._inventory is None:
2609
2513
            self.read_working_inventory()
2610
2514
 
2611
 
    def _get_check_refs(self):
2612
 
        """Return the references needed to perform a check of this tree."""
2613
 
        return [('trees', self.last_revision())]
2614
 
 
2615
2515
    def lock_tree_write(self):
2616
2516
        """See WorkingTree.lock_tree_write().
2617
2517
 
2635
2535
            if self._inventory_is_modified:
2636
2536
                self.flush()
2637
2537
            self._write_hashcache_if_dirty()
2638
 
 
 
2538
                    
2639
2539
        # reverse order of locking.
2640
2540
        try:
2641
2541
            return self._control_files.unlock()
2663
2563
 
2664
2564
    def _change_last_revision(self, revision_id):
2665
2565
        """See WorkingTree._change_last_revision."""
2666
 
        if revision_id is None or revision_id == _mod_revision.NULL_REVISION:
 
2566
        if revision_id is None or revision_id == NULL_REVISION:
2667
2567
            try:
2668
2568
                self._transport.delete('last-revision')
2669
2569
            except errors.NoSuchFile:
2671
2571
            return False
2672
2572
        else:
2673
2573
            self._transport.put_bytes('last-revision', revision_id,
2674
 
                mode=self.bzrdir._get_file_mode())
 
2574
                mode=self._control_files._file_mode)
2675
2575
            return True
2676
2576
 
2677
 
    def _get_check_refs(self):
2678
 
        """Return the references needed to perform a check of this tree."""
2679
 
        return [('trees', self.last_revision())]
2680
 
 
2681
2577
    @needs_tree_write_lock
2682
2578
    def set_conflicts(self, conflicts):
2683
 
        self._put_rio('conflicts', conflicts.to_stanzas(),
 
2579
        self._put_rio('conflicts', conflicts.to_stanzas(), 
2684
2580
                      CONFLICT_HEADER_1)
2685
2581
 
2686
2582
    @needs_tree_write_lock
2697
2593
        except errors.NoSuchFile:
2698
2594
            return _mod_conflicts.ConflictList()
2699
2595
        try:
2700
 
            try:
2701
 
                if confile.next() != CONFLICT_HEADER_1 + '\n':
2702
 
                    raise errors.ConflictFormatError()
2703
 
            except StopIteration:
 
2596
            if confile.next() != CONFLICT_HEADER_1 + '\n':
2704
2597
                raise errors.ConflictFormatError()
2705
 
            return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
2706
 
        finally:
2707
 
            confile.close()
 
2598
        except StopIteration:
 
2599
            raise errors.ConflictFormatError()
 
2600
        return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
2708
2601
 
2709
2602
    def unlock(self):
2710
2603
        # do non-implementation specific cleanup
2735
2628
     * a format string,
2736
2629
     * an open routine.
2737
2630
 
2738
 
    Formats are placed in an dict by their format string for reference
 
2631
    Formats are placed in an dict by their format string for reference 
2739
2632
    during workingtree opening. Its not required that these be instances, they
2740
 
    can be classes themselves with class methods - it simply depends on
 
2633
    can be classes themselves with class methods - it simply depends on 
2741
2634
    whether state is needed for a given format or not.
2742
2635
 
2743
2636
    Once a format is deprecated, just deprecate the initialize and open
2744
 
    methods on the format class. Do not deprecate the object, as the
 
2637
    methods on the format class. Do not deprecate the object, as the 
2745
2638
    object will be created every time regardless.
2746
2639
    """
2747
2640
 
2791
2684
        """Is this format supported?
2792
2685
 
2793
2686
        Supported formats can be initialized and opened.
2794
 
        Unsupported formats may not support initialization or committing or
 
2687
        Unsupported formats may not support initialization or committing or 
2795
2688
        some other features depending on the reason for not being supported.
2796
2689
        """
2797
2690
        return True
2798
2691
 
2799
 
    def supports_content_filtering(self):
2800
 
        """True if this format supports content filtering."""
2801
 
        return False
2802
 
 
2803
 
    def supports_views(self):
2804
 
        """True if this format supports stored views."""
2805
 
        return False
2806
 
 
2807
2692
    @classmethod
2808
2693
    def register_format(klass, format):
2809
2694
        klass._formats[format.get_format_string()] = format
2818
2703
 
2819
2704
 
2820
2705
class WorkingTreeFormat2(WorkingTreeFormat):
2821
 
    """The second working tree format.
 
2706
    """The second working tree format. 
2822
2707
 
2823
2708
    This format modified the hash cache from the format 1 hash cache.
2824
2709
    """
2837
2722
        no working tree.  (See bug #43064).
2838
2723
        """
2839
2724
        sio = StringIO()
2840
 
        inv = inventory.Inventory()
 
2725
        inv = Inventory()
2841
2726
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
2842
2727
        sio.seek(0)
2843
2728
        transport.put_file('inventory', sio, file_mode)
2859
2744
            branch.generate_revision_history(revision_id)
2860
2745
        finally:
2861
2746
            branch.unlock()
2862
 
        inv = inventory.Inventory()
 
2747
        inv = Inventory()
2863
2748
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2864
2749
                         branch,
2865
2750
                         inv,
2910
2795
        - is new in bzr 0.8
2911
2796
        - uses a LockDir to guard access for writes.
2912
2797
    """
2913
 
 
 
2798
    
2914
2799
    upgrade_recommended = True
2915
2800
 
2916
2801
    def get_format_string(self):
2933
2818
 
2934
2819
    def _open_control_files(self, a_bzrdir):
2935
2820
        transport = a_bzrdir.get_workingtree_transport(None)
2936
 
        return LockableFiles(transport, self._lock_file_name,
 
2821
        return LockableFiles(transport, self._lock_file_name, 
2937
2822
                             self._lock_class)
2938
2823
 
2939
2824
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2940
2825
                   accelerator_tree=None, hardlink=False):
2941
2826
        """See WorkingTreeFormat.initialize().
2942
 
 
 
2827
        
2943
2828
        :param revision_id: if supplied, create a working tree at a different
2944
2829
            revision than the branch is at.
2945
2830
        :param accelerator_tree: A tree which can be used for retrieving file
2956
2841
        control_files.create_lock()
2957
2842
        control_files.lock_write()
2958
2843
        transport.put_bytes('format', self.get_format_string(),
2959
 
            mode=a_bzrdir._get_file_mode())
 
2844
            mode=control_files._file_mode)
2960
2845
        if from_branch is not None:
2961
2846
            branch = from_branch
2962
2847
        else:
2982
2867
            # only set an explicit root id if there is one to set.
2983
2868
            if basis_tree.inventory.root is not None:
2984
2869
                wt.set_root_id(basis_tree.get_root_id())
2985
 
            if revision_id == _mod_revision.NULL_REVISION:
 
2870
            if revision_id == NULL_REVISION:
2986
2871
                wt.set_parent_trees([])
2987
2872
            else:
2988
2873
                wt.set_parent_trees([(revision_id, basis_tree)])
2995
2880
        return wt
2996
2881
 
2997
2882
    def _initial_inventory(self):
2998
 
        return inventory.Inventory()
 
2883
        return Inventory()
2999
2884
 
3000
2885
    def __init__(self):
3001
2886
        super(WorkingTreeFormat3, self).__init__()
3016
2901
 
3017
2902
    def _open(self, a_bzrdir, control_files):
3018
2903
        """Open the tree itself.
3019
 
 
 
2904
        
3020
2905
        :param a_bzrdir: the dir for the tree.
3021
2906
        :param control_files: the control files for the tree.
3022
2907
        """
3032
2917
 
3033
2918
__default_format = WorkingTreeFormat4()
3034
2919
WorkingTreeFormat.register_format(__default_format)
3035
 
WorkingTreeFormat.register_format(WorkingTreeFormat6())
3036
 
WorkingTreeFormat.register_format(WorkingTreeFormat5())
3037
2920
WorkingTreeFormat.register_format(WorkingTreeFormat3())
3038
2921
WorkingTreeFormat.set_default_format(__default_format)
3039
2922
# formats which have no format string are not discoverable