~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Ian Clatworthy
  • Date: 2009-03-20 04:22:44 UTC
  • mfrom: (3368.2.54 bzr.content-filters)
  • mto: This revision was merged to the branch mainline in revision 4173.
  • Revision ID: ian.clatworthy@canonical.com-20090320042244-xwqpk6gc4t9y9pbi
Content filters (Ian Clatworthy)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 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
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
72
72
    transform,
73
73
    ui,
74
74
    urlutils,
 
75
    views,
75
76
    xml5,
76
77
    xml6,
77
78
    xml7,
79
80
import bzrlib.branch
80
81
from bzrlib.transport import get_transport
81
82
import bzrlib.ui
82
 
from bzrlib.workingtree_4 import WorkingTreeFormat4
 
83
from bzrlib.workingtree_4 import WorkingTreeFormat4, WorkingTreeFormat5
83
84
""")
84
85
 
85
86
from bzrlib import symbol_versioning
86
87
from bzrlib.decorators import needs_read_lock, needs_write_lock
87
88
from bzrlib.inventory import InventoryEntry, Inventory, ROOT_ID, TreeReference
88
 
from bzrlib.lockable_files import LockableFiles, TransportLock
 
89
from bzrlib.lockable_files import LockableFiles
89
90
from bzrlib.lockdir import LockDir
90
91
import bzrlib.mutabletree
91
92
from bzrlib.mutabletree import needs_tree_write_lock
124
125
class TreeEntry(object):
125
126
    """An entry that implements the minimum interface used by commands.
126
127
 
127
 
    This needs further inspection, it may be better to have 
 
128
    This needs further inspection, it may be better to have
128
129
    InventoryEntries without ids - though that seems wrong. For now,
129
130
    this is a parallel hierarchy to InventoryEntry, and needs to become
130
131
    one of several things: decorates to that hierarchy, children of, or
133
134
    no InventoryEntry available - i.e. for unversioned objects.
134
135
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
135
136
    """
136
 
 
 
137
 
137
138
    def __eq__(self, other):
138
139
        # yes, this us ugly, TODO: best practice __eq__ style.
139
140
        return (isinstance(other, TreeEntry)
140
141
                and other.__class__ == self.__class__)
141
 
 
 
142
 
142
143
    def kind_character(self):
143
144
        return "???"
144
145
 
186
187
    not listed in the Inventory and vice versa.
187
188
    """
188
189
 
 
190
    # override this to set the strategy for storing views
 
191
    def _make_views(self):
 
192
        return views.DisabledViews(self)
 
193
 
189
194
    def __init__(self, basedir='.',
190
195
                 branch=DEPRECATED_PARAMETER,
191
196
                 _inventory=None,
227
232
        cache_filename = wt_trans.local_abspath('stat-cache')
228
233
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
229
234
            self.bzrdir._get_file_mode(),
230
 
            lambda path, file_id: self._content_filter_stack(path, file_id))
 
235
            self._content_filter_stack_provider())
231
236
        hc = self._hashcache
232
237
        hc.read()
233
238
        # is this scan needed ? it makes things kinda slow.
249
254
            self._set_inventory(_inventory, dirty=False)
250
255
        self._detect_case_handling()
251
256
        self._rules_searcher = None
 
257
        self.views = self._make_views()
252
258
 
253
259
    def _detect_case_handling(self):
254
260
        wt_trans = self.bzrdir.get_workingtree_transport(None)
286
292
    def supports_tree_reference(self):
287
293
        return False
288
294
 
 
295
    def supports_content_filtering(self):
 
296
        return self._format.supports_content_filtering()
 
297
 
 
298
    def supports_views(self):
 
299
        return self.views.supports_views()
 
300
 
289
301
    def _set_inventory(self, inv, dirty):
290
302
        """Set the internal cached inventory.
291
303
 
305
317
 
306
318
        """
307
319
        if path is None:
308
 
            path = os.path.getcwdu()
 
320
            path = osutils.getcwd()
309
321
        control = bzrdir.BzrDir.open(path, _unsupported)
310
322
        return control.open_workingtree(_unsupported)
311
 
        
 
323
 
312
324
    @staticmethod
313
325
    def open_containing(path=None):
314
326
        """Open an existing working tree which has its root about path.
315
 
        
 
327
 
316
328
        This probes for a working tree at path and searches upwards from there.
317
329
 
318
330
        Basically we keep looking up until we find the control directory or
379
391
 
380
392
    def basis_tree(self):
381
393
        """Return RevisionTree for the current last revision.
382
 
        
 
394
 
383
395
        If the left most parent is a ghost then the returned tree will be an
384
 
        empty tree - one obtained by calling repository.revision_tree(None).
 
396
        empty tree - one obtained by calling
 
397
        repository.revision_tree(NULL_REVISION).
385
398
        """
386
399
        try:
387
400
            revision_id = self.get_parent_ids()[0]
389
402
            # no parents, return an empty revision tree.
390
403
            # in the future this should return the tree for
391
404
            # 'empty:' - the implicit root empty tree.
392
 
            return self.branch.repository.revision_tree(None)
 
405
            return self.branch.repository.revision_tree(
 
406
                       _mod_revision.NULL_REVISION)
393
407
        try:
394
408
            return self.revision_tree(revision_id)
395
409
        except errors.NoSuchRevision:
406
420
            if self.branch.repository.has_revision(revision_id):
407
421
                raise
408
422
            # the basis tree is a ghost so return an empty tree.
409
 
            return self.branch.repository.revision_tree(None)
 
423
            return self.branch.repository.revision_tree(
 
424
                       _mod_revision.NULL_REVISION)
410
425
 
411
426
    def _cleanup(self):
412
427
        self._flush_ignore_list_cache()
413
428
 
414
429
    def relpath(self, path):
415
430
        """Return the local path portion from a given path.
416
 
        
417
 
        The path may be absolute or relative. If its a relative path it is 
 
431
 
 
432
        The path may be absolute or relative. If its a relative path it is
418
433
        interpreted relative to the python current working directory.
419
434
        """
420
435
        return osutils.relpath(self.basedir, path)
423
438
        return osutils.lexists(self.abspath(filename))
424
439
 
425
440
    def get_file(self, file_id, path=None, filtered=True):
 
441
        return self.get_file_with_stat(file_id, path, filtered=filtered)[0]
 
442
 
 
443
    def get_file_with_stat(self, file_id, path=None, filtered=True,
 
444
        _fstat=os.fstat):
 
445
        """See MutableTree.get_file_with_stat."""
426
446
        if path is None:
427
447
            path = self.id2path(file_id)
428
 
        return self.get_file_byname(path, filtered=filtered)
 
448
        file_obj = self.get_file_byname(path, filtered=False)
 
449
        stat_value = _fstat(file_obj.fileno())
 
450
        if self.supports_content_filtering() and filtered:
 
451
            filters = self._content_filter_stack(path)
 
452
            file_obj = filtered_input_file(file_obj, filters)
 
453
        return (file_obj, stat_value)
429
454
 
430
 
    def get_file_text(self, file_id, filtered=True):
431
 
        return self.get_file(file_id, filtered=filtered).read()
 
455
    def get_file_text(self, file_id, path=None, filtered=True):
 
456
        return self.get_file(file_id, path=path, filtered=filtered).read()
432
457
 
433
458
    def get_file_byname(self, filename, filtered=True):
434
459
        path = self.abspath(filename)
435
460
        f = file(path, 'rb')
436
 
        if filtered:
 
461
        if self.supports_content_filtering() and filtered:
437
462
            filters = self._content_filter_stack(filename)
438
463
            return filtered_input_file(f, filters)
439
464
        else:
440
465
            return f
441
466
 
442
 
    def get_special_file(self, type):
443
 
        """Get a file special to Bazaar.
444
 
 
445
 
        :type: a type of XXX maps to a file path .bzrXXX
446
 
        :return: a file-like object or None if the file does not exist
447
 
        """
448
 
        path = self.abspath(".bzr" + type)
 
467
    def get_file_lines(self, file_id, path=None, filtered=True):
 
468
        """See Tree.get_file_lines()"""
 
469
        file = self.get_file(file_id, path, filtered=filtered)
449
470
        try:
450
 
            return open(path, 'rb')
451
 
        except IOError:
452
 
            return None
 
471
            return file.readlines()
 
472
        finally:
 
473
            file.close()
453
474
 
454
475
    @needs_read_lock
455
476
    def annotate_iter(self, file_id, default_revision=CURRENT_REVISION):
497
518
 
498
519
    def get_parent_ids(self):
499
520
        """See Tree.get_parent_ids.
500
 
        
 
521
 
501
522
        This implementation reads the pending merges list and last_revision
502
523
        value and uses that to decide what the parents list should be.
503
524
        """
520
541
    def get_root_id(self):
521
542
        """Return the id of this trees root"""
522
543
        return self._inventory.root.file_id
523
 
        
 
544
 
524
545
    def _get_store_filename(self, file_id):
525
546
        ## XXX: badly named; this is not in the store at all
526
547
        return self.abspath(self.id2path(file_id))
528
549
    @needs_read_lock
529
550
    def clone(self, to_bzrdir, revision_id=None):
530
551
        """Duplicate this working tree into to_bzr, including all state.
531
 
        
 
552
 
532
553
        Specifically modified files are kept as modified, but
533
554
        ignored and unknown files are discarded.
534
555
 
535
556
        If you want to make a new line of development, see bzrdir.sprout()
536
557
 
537
558
        revision
538
 
            If not None, the cloned tree will have its last revision set to 
 
559
            If not None, the cloned tree will have its last revision set to
539
560
            revision, and and difference between the source trees last revision
540
561
            and this one merged in.
541
562
        """
542
563
        # assumes the target bzr dir format is compatible.
543
 
        result = self._format.initialize(to_bzrdir)
 
564
        result = to_bzrdir.create_workingtree()
544
565
        self.copy_content_into(result, revision_id)
545
566
        return result
546
567
 
624
645
        """See MutableTree._add."""
625
646
        # TODO: Re-adding a file that is removed in the working copy
626
647
        # should probably put it back with the previous ID.
627
 
        # the read and write working inventory should not occur in this 
 
648
        # the read and write working inventory should not occur in this
628
649
        # function - they should be part of lock_write and unlock.
629
650
        inv = self.inventory
630
651
        for f, file_id, kind in zip(files, ids, kinds):
724
745
                kind = 'tree-reference'
725
746
            return kind, None, None, None
726
747
        elif kind == 'symlink':
727
 
            return ('symlink', None, None, os.readlink(abspath))
 
748
            return ('symlink', None, None,
 
749
                    os.readlink(abspath.encode(osutils._fs_enc)
 
750
                                ).decode(osutils._fs_enc))
728
751
        else:
729
752
            return (kind, None, None, None)
730
753
 
749
772
        """Check that all merged revisions are proper 'heads'.
750
773
 
751
774
        This will always return the first revision_id, and any merged revisions
752
 
        which are 
 
775
        which are
753
776
        """
754
777
        if len(revision_ids) == 0:
755
778
            return revision_ids
767
790
    @needs_tree_write_lock
768
791
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
769
792
        """Set the parent ids to revision_ids.
770
 
        
 
793
 
771
794
        See also set_parent_trees. This api will try to retrieve the tree data
772
795
        for each element of revision_ids from the trees repository. If you have
773
796
        tree data already available, it is more efficient to use
906
929
    def merge_modified(self):
907
930
        """Return a dictionary of files modified by a merge.
908
931
 
909
 
        The list is initialized by WorkingTree.set_merge_modified, which is 
 
932
        The list is initialized by WorkingTree.set_merge_modified, which is
910
933
        typically called after we make some automatic updates to the tree
911
934
        because of a merge.
912
935
 
917
940
            hashfile = self._transport.get('merge-hashes')
918
941
        except errors.NoSuchFile:
919
942
            return {}
920
 
        merge_hashes = {}
921
943
        try:
922
 
            if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
 
944
            merge_hashes = {}
 
945
            try:
 
946
                if hashfile.next() != MERGE_MODIFIED_HEADER_1 + '\n':
 
947
                    raise errors.MergeModifiedFormatError()
 
948
            except StopIteration:
923
949
                raise errors.MergeModifiedFormatError()
924
 
        except StopIteration:
925
 
            raise errors.MergeModifiedFormatError()
926
 
        for s in RioReader(hashfile):
927
 
            # RioReader reads in Unicode, so convert file_ids back to utf8
928
 
            file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
929
 
            if file_id not in self.inventory:
930
 
                continue
931
 
            text_hash = s.get("hash")
932
 
            if text_hash == self.get_file_sha1(file_id):
933
 
                merge_hashes[file_id] = text_hash
934
 
        return merge_hashes
 
950
            for s in RioReader(hashfile):
 
951
                # RioReader reads in Unicode, so convert file_ids back to utf8
 
952
                file_id = osutils.safe_file_id(s.get("file_id"), warn=False)
 
953
                if file_id not in self.inventory:
 
954
                    continue
 
955
                text_hash = s.get("hash")
 
956
                if text_hash == self.get_file_sha1(file_id):
 
957
                    merge_hashes[file_id] = text_hash
 
958
            return merge_hashes
 
959
        finally:
 
960
            hashfile.close()
935
961
 
936
962
    @needs_write_lock
937
963
    def mkdir(self, path, file_id=None):
943
969
        return file_id
944
970
 
945
971
    def get_symlink_target(self, file_id):
946
 
        return os.readlink(self.id2abspath(file_id))
 
972
        return os.readlink(self.id2abspath(file_id).encode(osutils._fs_enc))
947
973
 
948
974
    @needs_write_lock
949
975
    def subsume(self, other_tree):
999
1025
        return False
1000
1026
 
1001
1027
    def _directory_may_be_tree_reference(self, relpath):
1002
 
        # as a special case, if a directory contains control files then 
 
1028
        # as a special case, if a directory contains control files then
1003
1029
        # it's a tree reference, except that the root of the tree is not
1004
1030
        return relpath and osutils.isdir(self.abspath(relpath) + u"/.bzr")
1005
1031
        # TODO: We could ask all the control formats whether they
1016
1042
    @needs_tree_write_lock
1017
1043
    def extract(self, file_id, format=None):
1018
1044
        """Extract a subtree from this tree.
1019
 
        
 
1045
 
1020
1046
        A new branch will be created, relative to the path for this tree.
1021
1047
        """
1022
1048
        self.flush()
1027
1053
                transport = transport.clone(name)
1028
1054
                transport.ensure_base()
1029
1055
            return transport
1030
 
            
 
1056
 
1031
1057
        sub_path = self.id2path(file_id)
1032
1058
        branch_transport = mkdirs(sub_path)
1033
1059
        if format is None:
1115
1141
        # directory file_id, relative path, absolute path, reverse sorted children
1116
1142
        children = os.listdir(self.basedir)
1117
1143
        children.sort()
1118
 
        # jam 20060527 The kernel sized tree seems equivalent whether we 
 
1144
        # jam 20060527 The kernel sized tree seems equivalent whether we
1119
1145
        # use a deque and popleft to keep them sorted, or if we use a plain
1120
1146
        # list and just reverse() them.
1121
1147
        children = collections.deque(children)
1141
1167
 
1142
1168
                # absolute path
1143
1169
                fap = from_dir_abspath + '/' + f
1144
 
                
 
1170
 
1145
1171
                f_ie = inv.get_child(from_dir_id, f)
1146
1172
                if f_ie:
1147
1173
                    c = 'V'
1179
1205
                    except KeyError:
1180
1206
                        yield fp[1:], c, fk, None, TreeEntry()
1181
1207
                    continue
1182
 
                
 
1208
 
1183
1209
                if fk != 'directory':
1184
1210
                    continue
1185
1211
 
1202
1228
        to_dir must exist in the inventory.
1203
1229
 
1204
1230
        If to_dir exists and is a directory, the files are moved into
1205
 
        it, keeping their old names.  
 
1231
        it, keeping their old names.
1206
1232
 
1207
1233
        Note that to_dir is only the last component of the new name;
1208
1234
        this doesn't change the directory.
1336
1362
                only_change_inv = True
1337
1363
            elif self.has_filename(from_rel) and not self.has_filename(to_rel):
1338
1364
                only_change_inv = False
1339
 
            elif (sys.platform == 'win32'
1340
 
                and from_rel.lower() == to_rel.lower()
1341
 
                and self.has_filename(from_rel)):
 
1365
            elif (not self.case_sensitive
 
1366
                  and from_rel.lower() == to_rel.lower()
 
1367
                  and self.has_filename(from_rel)):
1342
1368
                only_change_inv = False
1343
1369
            else:
1344
1370
                # something is wrong, so lets determine what exactly
1485
1511
        These are files in the working directory that are not versioned or
1486
1512
        control files or ignored.
1487
1513
        """
1488
 
        # force the extras method to be fully executed before returning, to 
 
1514
        # force the extras method to be fully executed before returning, to
1489
1515
        # prevent race conditions with the lock
1490
1516
        return iter(
1491
1517
            [subp for subp in self.extras() if not self.is_ignored(subp)])
1506
1532
            else:
1507
1533
                raise errors.NoSuchId(self, file_id)
1508
1534
        if len(file_ids):
1509
 
            # in the future this should just set a dirty bit to wait for the 
 
1535
            # in the future this should just set a dirty bit to wait for the
1510
1536
            # final unlock. However, until all methods of workingtree start
1511
 
            # with the current in -memory inventory rather than triggering 
 
1537
            # with the current in -memory inventory rather than triggering
1512
1538
            # a read, it is more complex - we need to teach read_inventory
1513
1539
            # to know when to read, and when to not read first... and possibly
1514
1540
            # to save first when the in memory one may be corrupted.
1515
1541
            # so for now, we just only write it if it is indeed dirty.
1516
1542
            # - RBC 20060907
1517
1543
            self._write_inventory(self._inventory)
1518
 
    
 
1544
 
1519
1545
    def _iter_conflicts(self):
1520
1546
        conflicted = set()
1521
1547
        for info in self.list_files():
1564
1590
                # reuse the revisiontree we merged against to set the new
1565
1591
                # tree data.
1566
1592
                parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1567
 
                # we have to pull the merge trees out again, because 
1568
 
                # merge_inner has set the ids. - this corner is not yet 
 
1593
                # we have to pull the merge trees out again, because
 
1594
                # merge_inner has set the ids. - this corner is not yet
1569
1595
                # layered well enough to prevent double handling.
1570
1596
                # XXX TODO: Fix the double handling: telling the tree about
1571
1597
                # the already known parent data is wasteful.
1625
1651
                            fl.append(subf_norm)
1626
1652
                    else:
1627
1653
                        fl.append(subf)
1628
 
            
 
1654
 
1629
1655
            fl.sort()
1630
1656
            for subf in fl:
1631
1657
                subp = pathjoin(path, subf)
1782
1808
 
1783
1809
    def _change_last_revision(self, new_revision):
1784
1810
        """Template method part of set_last_revision to perform the change.
1785
 
        
 
1811
 
1786
1812
        This is used to allow WorkingTree3 instances to not affect branch
1787
1813
        when their last revision is set.
1788
1814
        """
1814
1840
        # as commit already has that ready-to-use [while the format is the
1815
1841
        # same, that is].
1816
1842
        try:
1817
 
            # this double handles the inventory - unpack and repack - 
 
1843
            # this double handles the inventory - unpack and repack -
1818
1844
            # but is easier to understand. We can/should put a conditional
1819
1845
            # in here based on whether the inventory is in the latest format
1820
1846
            # - perhaps we should repack all inventories on a repository
1821
1847
            # upgrade ?
1822
1848
            # the fast path is to copy the raw xml from the repository. If the
1823
 
            # xml contains 'revision_id="', then we assume the right 
 
1849
            # xml contains 'revision_id="', then we assume the right
1824
1850
            # revision_id is set. We must check for this full string, because a
1825
1851
            # root node id can legitimately look like 'revision_id' but cannot
1826
1852
            # contain a '"'.
1827
1853
            xml = self.branch.repository.get_inventory_xml(new_revision)
1828
1854
            firstline = xml.split('\n', 1)[0]
1829
 
            if (not 'revision_id="' in firstline or 
 
1855
            if (not 'revision_id="' in firstline or
1830
1856
                'format="7"' not in firstline):
1831
1857
                inv = self.branch.repository.deserialise_inventory(
1832
1858
                    new_revision, xml)
1839
1865
        """Read the cached basis inventory."""
1840
1866
        path = self._basis_inventory_name()
1841
1867
        return self._transport.get_bytes(path)
1842
 
        
 
1868
 
1843
1869
    @needs_read_lock
1844
1870
    def read_working_inventory(self):
1845
1871
        """Read the working inventory.
1846
 
        
 
1872
 
1847
1873
        :raises errors.InventoryModified: read_working_inventory will fail
1848
1874
            when the current in memory inventory has been modified.
1849
1875
        """
1850
 
        # conceptually this should be an implementation detail of the tree. 
 
1876
        # conceptually this should be an implementation detail of the tree.
1851
1877
        # XXX: Deprecate this.
1852
1878
        # ElementTree does its own conversion from UTF-8, so open in
1853
1879
        # binary.
1879
1905
            # Recurse directory and add all files
1880
1906
            # so we can check if they have changed.
1881
1907
            for parent_info, file_infos in\
1882
 
                osutils.walkdirs(self.abspath(directory),
1883
 
                    directory):
1884
 
                for relpath, basename, kind, lstat, abspath in file_infos:
 
1908
                self.walkdirs(directory):
 
1909
                for relpath, basename, kind, lstat, fileid, kind in file_infos:
1885
1910
                    # Is it versioned or ignored?
1886
1911
                    if self.path2id(relpath) or self.is_ignored(relpath):
1887
1912
                        # Add nested content for deletion.
1897
1922
            filename = self.relpath(abspath)
1898
1923
            if len(filename) > 0:
1899
1924
                new_files.add(filename)
1900
 
                if osutils.isdir(abspath):
1901
 
                    recurse_directory_to_add_files(filename)
 
1925
                recurse_directory_to_add_files(filename)
1902
1926
 
1903
1927
        files = list(new_files)
1904
1928
 
2052
2076
            name = os.path.basename(path)
2053
2077
            if name == "":
2054
2078
                continue
2055
 
            # fixme, there should be a factory function inv,add_?? 
 
2079
            # fixme, there should be a factory function inv,add_??
2056
2080
            if kind == 'directory':
2057
2081
                inv.add(InventoryDirectory(file_id, name, parent))
2058
2082
            elif kind == 'file':
2066
2090
    @needs_tree_write_lock
2067
2091
    def set_root_id(self, file_id):
2068
2092
        """Set the root id for this tree."""
2069
 
        # for compatability 
 
2093
        # for compatability
2070
2094
        if file_id is None:
2071
2095
            raise ValueError(
2072
2096
                'WorkingTree.set_root_id with fileid=None')
2076
2100
    def _set_root_id(self, file_id):
2077
2101
        """Set the root id for this tree, in a format specific manner.
2078
2102
 
2079
 
        :param file_id: The file id to assign to the root. It must not be 
 
2103
        :param file_id: The file id to assign to the root. It must not be
2080
2104
            present in the current inventory or an error will occur. It must
2081
2105
            not be None, but rather a valid file id.
2082
2106
        """
2101
2125
 
2102
2126
    def unlock(self):
2103
2127
        """See Branch.unlock.
2104
 
        
 
2128
 
2105
2129
        WorkingTree locking just uses the Branch locking facilities.
2106
2130
        This is current because all working trees have an embedded branch
2107
2131
        within them. IF in the future, we were to make branch data shareable
2108
 
        between multiple working trees, i.e. via shared storage, then we 
 
2132
        between multiple working trees, i.e. via shared storage, then we
2109
2133
        would probably want to lock both the local tree, and the branch.
2110
2134
        """
2111
2135
        raise NotImplementedError(self.unlock)
2163
2187
        # cant set that until we update the working trees last revision to be
2164
2188
        # one from the new branch, because it will just get absorbed by the
2165
2189
        # parent de-duplication logic.
2166
 
        # 
 
2190
        #
2167
2191
        # We MUST save it even if an error occurs, because otherwise the users
2168
2192
        # local work is unreferenced and will appear to have been lost.
2169
 
        # 
 
2193
        #
2170
2194
        result = 0
2171
2195
        try:
2172
2196
            last_rev = self.get_parent_ids()[0]
2342
2366
                    # value.
2343
2367
                    bzrdir_loc = bisect_left(cur_disk_dir_content,
2344
2368
                        ('.bzr', '.bzr'))
2345
 
                    if cur_disk_dir_content[bzrdir_loc][0] == '.bzr':
 
2369
                    if (bzrdir_loc < len(cur_disk_dir_content)
 
2370
                        and cur_disk_dir_content[bzrdir_loc][0] == '.bzr'):
2346
2371
                        # we dont yield the contents of, or, .bzr itself.
2347
2372
                        del cur_disk_dir_content[bzrdir_loc]
2348
2373
            if inv_finished:
2438
2463
                relroot = ""
2439
2464
            # FIXME: stash the node in pending
2440
2465
            entry = inv[top_id]
2441
 
            for name, child in entry.sorted_children():
2442
 
                dirblock.append((relroot + name, name, child.kind, None,
2443
 
                    child.file_id, child.kind
2444
 
                    ))
 
2466
            if entry.kind == 'directory':
 
2467
                for name, child in entry.sorted_children():
 
2468
                    dirblock.append((relroot + name, name, child.kind, None,
 
2469
                        child.file_id, child.kind
 
2470
                        ))
2445
2471
            yield (currentdir[0], entry.file_id), dirblock
2446
2472
            # push the user specified dirs from dirblock
2447
2473
            for dir in reversed(dirblock):
2513
2539
                self)._get_rules_searcher(default_searcher)
2514
2540
        return self._rules_searcher
2515
2541
 
 
2542
    def get_shelf_manager(self):
 
2543
        """Return the ShelfManager for this WorkingTree."""
 
2544
        from bzrlib.shelf import ShelfManager
 
2545
        return ShelfManager(self, self._transport)
 
2546
 
2516
2547
 
2517
2548
class WorkingTree2(WorkingTree):
2518
2549
    """This is the Format 2 working tree.
2519
2550
 
2520
 
    This was the first weave based working tree. 
 
2551
    This was the first weave based working tree.
2521
2552
     - uses os locks for locking.
2522
2553
     - uses the branch last-revision.
2523
2554
    """
2556
2587
            if self._inventory_is_modified:
2557
2588
                self.flush()
2558
2589
            self._write_hashcache_if_dirty()
2559
 
                    
 
2590
 
2560
2591
        # reverse order of locking.
2561
2592
        try:
2562
2593
            return self._control_files.unlock()
2597
2628
 
2598
2629
    @needs_tree_write_lock
2599
2630
    def set_conflicts(self, conflicts):
2600
 
        self._put_rio('conflicts', conflicts.to_stanzas(), 
 
2631
        self._put_rio('conflicts', conflicts.to_stanzas(),
2601
2632
                      CONFLICT_HEADER_1)
2602
2633
 
2603
2634
    @needs_tree_write_lock
2614
2645
        except errors.NoSuchFile:
2615
2646
            return _mod_conflicts.ConflictList()
2616
2647
        try:
2617
 
            if confile.next() != CONFLICT_HEADER_1 + '\n':
 
2648
            try:
 
2649
                if confile.next() != CONFLICT_HEADER_1 + '\n':
 
2650
                    raise errors.ConflictFormatError()
 
2651
            except StopIteration:
2618
2652
                raise errors.ConflictFormatError()
2619
 
        except StopIteration:
2620
 
            raise errors.ConflictFormatError()
2621
 
        return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
 
2653
            return _mod_conflicts.ConflictList.from_stanzas(RioReader(confile))
 
2654
        finally:
 
2655
            confile.close()
2622
2656
 
2623
2657
    def unlock(self):
2624
2658
        # do non-implementation specific cleanup
2649
2683
     * a format string,
2650
2684
     * an open routine.
2651
2685
 
2652
 
    Formats are placed in an dict by their format string for reference 
 
2686
    Formats are placed in an dict by their format string for reference
2653
2687
    during workingtree opening. Its not required that these be instances, they
2654
 
    can be classes themselves with class methods - it simply depends on 
 
2688
    can be classes themselves with class methods - it simply depends on
2655
2689
    whether state is needed for a given format or not.
2656
2690
 
2657
2691
    Once a format is deprecated, just deprecate the initialize and open
2658
 
    methods on the format class. Do not deprecate the object, as the 
 
2692
    methods on the format class. Do not deprecate the object, as the
2659
2693
    object will be created every time regardless.
2660
2694
    """
2661
2695
 
2705
2739
        """Is this format supported?
2706
2740
 
2707
2741
        Supported formats can be initialized and opened.
2708
 
        Unsupported formats may not support initialization or committing or 
 
2742
        Unsupported formats may not support initialization or committing or
2709
2743
        some other features depending on the reason for not being supported.
2710
2744
        """
2711
2745
        return True
2712
2746
 
 
2747
    def supports_content_filtering(self):
 
2748
        """True if this format supports content filtering."""
 
2749
        return False
 
2750
 
 
2751
    def supports_views(self):
 
2752
        """True if this format supports stored views."""
 
2753
        return False
 
2754
 
2713
2755
    @classmethod
2714
2756
    def register_format(klass, format):
2715
2757
        klass._formats[format.get_format_string()] = format
2724
2766
 
2725
2767
 
2726
2768
class WorkingTreeFormat2(WorkingTreeFormat):
2727
 
    """The second working tree format. 
 
2769
    """The second working tree format.
2728
2770
 
2729
2771
    This format modified the hash cache from the format 1 hash cache.
2730
2772
    """
2735
2777
        """See WorkingTreeFormat.get_format_description()."""
2736
2778
        return "Working tree format 2"
2737
2779
 
2738
 
    def _stub_initialize_remote(self, branch):
2739
 
        """As a special workaround create critical control files for a remote working tree.
2740
 
        
 
2780
    def _stub_initialize_on_transport(self, transport, file_mode):
 
2781
        """Workaround: create control files for a remote working tree.
 
2782
 
2741
2783
        This ensures that it can later be updated and dealt with locally,
2742
 
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with 
 
2784
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with
2743
2785
        no working tree.  (See bug #43064).
2744
2786
        """
2745
2787
        sio = StringIO()
2746
2788
        inv = Inventory()
2747
2789
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
2748
2790
        sio.seek(0)
2749
 
        branch._transport.put_file('inventory', sio,
2750
 
            mode=branch.control_files._file_mode)
2751
 
        branch._transport.put_bytes('pending-merges', '',
2752
 
            mode=branch.control_files._file_mode)
2753
 
        
 
2791
        transport.put_file('inventory', sio, file_mode)
 
2792
        transport.put_bytes('pending-merges', '', file_mode)
2754
2793
 
2755
2794
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2756
2795
                   accelerator_tree=None, hardlink=False):
2819
2858
        - is new in bzr 0.8
2820
2859
        - uses a LockDir to guard access for writes.
2821
2860
    """
2822
 
    
 
2861
 
2823
2862
    upgrade_recommended = True
2824
2863
 
2825
2864
    def get_format_string(self):
2842
2881
 
2843
2882
    def _open_control_files(self, a_bzrdir):
2844
2883
        transport = a_bzrdir.get_workingtree_transport(None)
2845
 
        return LockableFiles(transport, self._lock_file_name, 
 
2884
        return LockableFiles(transport, self._lock_file_name,
2846
2885
                             self._lock_class)
2847
2886
 
2848
2887
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2849
2888
                   accelerator_tree=None, hardlink=False):
2850
2889
        """See WorkingTreeFormat.initialize().
2851
 
        
 
2890
 
2852
2891
        :param revision_id: if supplied, create a working tree at a different
2853
2892
            revision than the branch is at.
2854
2893
        :param accelerator_tree: A tree which can be used for retrieving file
2925
2964
 
2926
2965
    def _open(self, a_bzrdir, control_files):
2927
2966
        """Open the tree itself.
2928
 
        
 
2967
 
2929
2968
        :param a_bzrdir: the dir for the tree.
2930
2969
        :param control_files: the control files for the tree.
2931
2970
        """
2941
2980
 
2942
2981
__default_format = WorkingTreeFormat4()
2943
2982
WorkingTreeFormat.register_format(__default_format)
 
2983
WorkingTreeFormat.register_format(WorkingTreeFormat5())
2944
2984
WorkingTreeFormat.register_format(WorkingTreeFormat3())
2945
2985
WorkingTreeFormat.set_default_format(__default_format)
2946
2986
# formats which have no format string are not discoverable