/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Robert Collins
  • Date: 2009-03-13 02:25:46 UTC
  • mfrom: (4133 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4183.
  • Revision ID: robertc@robertcollins.net-20090313022546-e7de5zsdkbay5okf
MergeĀ .dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
123
124
class TreeEntry(object):
124
125
    """An entry that implements the minimum interface used by commands.
125
126
 
126
 
    This needs further inspection, it may be better to have 
 
127
    This needs further inspection, it may be better to have
127
128
    InventoryEntries without ids - though that seems wrong. For now,
128
129
    this is a parallel hierarchy to InventoryEntry, and needs to become
129
130
    one of several things: decorates to that hierarchy, children of, or
132
133
    no InventoryEntry available - i.e. for unversioned objects.
133
134
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
134
135
    """
135
 
 
 
136
 
136
137
    def __eq__(self, other):
137
138
        # yes, this us ugly, TODO: best practice __eq__ style.
138
139
        return (isinstance(other, TreeEntry)
139
140
                and other.__class__ == self.__class__)
140
 
 
 
141
 
141
142
    def kind_character(self):
142
143
        return "???"
143
144
 
185
186
    not listed in the Inventory and vice versa.
186
187
    """
187
188
 
 
189
    # override this to set the strategy for storing views
 
190
    def _make_views(self):
 
191
        return views.DisabledViews(self)
 
192
 
188
193
    def __init__(self, basedir='.',
189
194
                 branch=DEPRECATED_PARAMETER,
190
195
                 _inventory=None,
247
252
            self._set_inventory(_inventory, dirty=False)
248
253
        self._detect_case_handling()
249
254
        self._rules_searcher = None
 
255
        self.views = self._make_views()
250
256
 
251
257
    def _detect_case_handling(self):
252
258
        wt_trans = self.bzrdir.get_workingtree_transport(None)
284
290
    def supports_tree_reference(self):
285
291
        return False
286
292
 
 
293
    def supports_content_filtering(self):
 
294
        return self._format.supports_content_filtering()
 
295
 
 
296
    def supports_views(self):
 
297
        return self.views.supports_views()
 
298
 
287
299
    def _set_inventory(self, inv, dirty):
288
300
        """Set the internal cached inventory.
289
301
 
377
389
 
378
390
    def basis_tree(self):
379
391
        """Return RevisionTree for the current last revision.
380
 
        
 
392
 
381
393
        If the left most parent is a ghost then the returned tree will be an
382
 
        empty tree - one obtained by calling 
 
394
        empty tree - one obtained by calling
383
395
        repository.revision_tree(NULL_REVISION).
384
396
        """
385
397
        try:
414
426
 
415
427
    def relpath(self, path):
416
428
        """Return the local path portion from a given path.
417
 
        
418
 
        The path may be absolute or relative. If its a relative path it is 
 
429
 
 
430
        The path may be absolute or relative. If its a relative path it is
419
431
        interpreted relative to the python current working directory.
420
432
        """
421
433
        return osutils.relpath(self.basedir, path)
433
445
        file_obj = self.get_file_byname(path)
434
446
        return (file_obj, _fstat(file_obj.fileno()))
435
447
 
436
 
    def get_file_text(self, file_id):
437
 
        return self.get_file(file_id).read()
438
 
 
439
448
    def get_file_byname(self, filename):
440
449
        return file(self.abspath(filename), 'rb')
441
450
 
 
451
    def get_file_lines(self, file_id, path=None):
 
452
        """See Tree.get_file_lines()"""
 
453
        file = self.get_file(file_id, path)
 
454
        try:
 
455
            return file.readlines()
 
456
        finally:
 
457
            file.close()
 
458
 
442
459
    @needs_read_lock
443
460
    def annotate_iter(self, file_id, default_revision=CURRENT_REVISION):
444
461
        """See Tree.annotate_iter
485
502
 
486
503
    def get_parent_ids(self):
487
504
        """See Tree.get_parent_ids.
488
 
        
 
505
 
489
506
        This implementation reads the pending merges list and last_revision
490
507
        value and uses that to decide what the parents list should be.
491
508
        """
508
525
    def get_root_id(self):
509
526
        """Return the id of this trees root"""
510
527
        return self._inventory.root.file_id
511
 
        
 
528
 
512
529
    def _get_store_filename(self, file_id):
513
530
        ## XXX: badly named; this is not in the store at all
514
531
        return self.abspath(self.id2path(file_id))
516
533
    @needs_read_lock
517
534
    def clone(self, to_bzrdir, revision_id=None):
518
535
        """Duplicate this working tree into to_bzr, including all state.
519
 
        
 
536
 
520
537
        Specifically modified files are kept as modified, but
521
538
        ignored and unknown files are discarded.
522
539
 
523
540
        If you want to make a new line of development, see bzrdir.sprout()
524
541
 
525
542
        revision
526
 
            If not None, the cloned tree will have its last revision set to 
 
543
            If not None, the cloned tree will have its last revision set to
527
544
            revision, and and difference between the source trees last revision
528
545
            and this one merged in.
529
546
        """
612
629
        """See MutableTree._add."""
613
630
        # TODO: Re-adding a file that is removed in the working copy
614
631
        # should probably put it back with the previous ID.
615
 
        # the read and write working inventory should not occur in this 
 
632
        # the read and write working inventory should not occur in this
616
633
        # function - they should be part of lock_write and unlock.
617
634
        inv = self.inventory
618
635
        for f, file_id, kind in zip(files, ids, kinds):
712
729
                kind = 'tree-reference'
713
730
            return kind, None, None, None
714
731
        elif kind == 'symlink':
715
 
            return ('symlink', None, None, os.readlink(abspath))
 
732
            return ('symlink', None, None,
 
733
                    os.readlink(abspath.encode(osutils._fs_enc)
 
734
                                ).decode(osutils._fs_enc))
716
735
        else:
717
736
            return (kind, None, None, None)
718
737
 
737
756
        """Check that all merged revisions are proper 'heads'.
738
757
 
739
758
        This will always return the first revision_id, and any merged revisions
740
 
        which are 
 
759
        which are
741
760
        """
742
761
        if len(revision_ids) == 0:
743
762
            return revision_ids
755
774
    @needs_tree_write_lock
756
775
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
757
776
        """Set the parent ids to revision_ids.
758
 
        
 
777
 
759
778
        See also set_parent_trees. This api will try to retrieve the tree data
760
779
        for each element of revision_ids from the trees repository. If you have
761
780
        tree data already available, it is more efficient to use
894
913
    def merge_modified(self):
895
914
        """Return a dictionary of files modified by a merge.
896
915
 
897
 
        The list is initialized by WorkingTree.set_merge_modified, which is 
 
916
        The list is initialized by WorkingTree.set_merge_modified, which is
898
917
        typically called after we make some automatic updates to the tree
899
918
        because of a merge.
900
919
 
934
953
        return file_id
935
954
 
936
955
    def get_symlink_target(self, file_id):
937
 
        return os.readlink(self.id2abspath(file_id))
 
956
        return os.readlink(self.id2abspath(file_id).encode(osutils._fs_enc))
938
957
 
939
958
    @needs_write_lock
940
959
    def subsume(self, other_tree):
990
1009
        return False
991
1010
 
992
1011
    def _directory_may_be_tree_reference(self, relpath):
993
 
        # as a special case, if a directory contains control files then 
 
1012
        # as a special case, if a directory contains control files then
994
1013
        # it's a tree reference, except that the root of the tree is not
995
1014
        return relpath and osutils.isdir(self.abspath(relpath) + u"/.bzr")
996
1015
        # TODO: We could ask all the control formats whether they
1007
1026
    @needs_tree_write_lock
1008
1027
    def extract(self, file_id, format=None):
1009
1028
        """Extract a subtree from this tree.
1010
 
        
 
1029
 
1011
1030
        A new branch will be created, relative to the path for this tree.
1012
1031
        """
1013
1032
        self.flush()
1018
1037
                transport = transport.clone(name)
1019
1038
                transport.ensure_base()
1020
1039
            return transport
1021
 
            
 
1040
 
1022
1041
        sub_path = self.id2path(file_id)
1023
1042
        branch_transport = mkdirs(sub_path)
1024
1043
        if format is None:
1106
1125
        # directory file_id, relative path, absolute path, reverse sorted children
1107
1126
        children = os.listdir(self.basedir)
1108
1127
        children.sort()
1109
 
        # jam 20060527 The kernel sized tree seems equivalent whether we 
 
1128
        # jam 20060527 The kernel sized tree seems equivalent whether we
1110
1129
        # use a deque and popleft to keep them sorted, or if we use a plain
1111
1130
        # list and just reverse() them.
1112
1131
        children = collections.deque(children)
1132
1151
 
1133
1152
                # absolute path
1134
1153
                fap = from_dir_abspath + '/' + f
1135
 
                
 
1154
 
1136
1155
                f_ie = inv.get_child(from_dir_id, f)
1137
1156
                if f_ie:
1138
1157
                    c = 'V'
1170
1189
                    except KeyError:
1171
1190
                        yield fp[1:], c, fk, None, TreeEntry()
1172
1191
                    continue
1173
 
                
 
1192
 
1174
1193
                if fk != 'directory':
1175
1194
                    continue
1176
1195
 
1193
1212
        to_dir must exist in the inventory.
1194
1213
 
1195
1214
        If to_dir exists and is a directory, the files are moved into
1196
 
        it, keeping their old names.  
 
1215
        it, keeping their old names.
1197
1216
 
1198
1217
        Note that to_dir is only the last component of the new name;
1199
1218
        this doesn't change the directory.
1476
1495
        These are files in the working directory that are not versioned or
1477
1496
        control files or ignored.
1478
1497
        """
1479
 
        # force the extras method to be fully executed before returning, to 
 
1498
        # force the extras method to be fully executed before returning, to
1480
1499
        # prevent race conditions with the lock
1481
1500
        return iter(
1482
1501
            [subp for subp in self.extras() if not self.is_ignored(subp)])
1497
1516
            else:
1498
1517
                raise errors.NoSuchId(self, file_id)
1499
1518
        if len(file_ids):
1500
 
            # in the future this should just set a dirty bit to wait for the 
 
1519
            # in the future this should just set a dirty bit to wait for the
1501
1520
            # final unlock. However, until all methods of workingtree start
1502
 
            # with the current in -memory inventory rather than triggering 
 
1521
            # with the current in -memory inventory rather than triggering
1503
1522
            # a read, it is more complex - we need to teach read_inventory
1504
1523
            # to know when to read, and when to not read first... and possibly
1505
1524
            # to save first when the in memory one may be corrupted.
1506
1525
            # so for now, we just only write it if it is indeed dirty.
1507
1526
            # - RBC 20060907
1508
1527
            self._write_inventory(self._inventory)
1509
 
    
 
1528
 
1510
1529
    def _iter_conflicts(self):
1511
1530
        conflicted = set()
1512
1531
        for info in self.list_files():
1555
1574
                # reuse the revisiontree we merged against to set the new
1556
1575
                # tree data.
1557
1576
                parent_trees = [(self.branch.last_revision(), new_basis_tree)]
1558
 
                # we have to pull the merge trees out again, because 
1559
 
                # merge_inner has set the ids. - this corner is not yet 
 
1577
                # we have to pull the merge trees out again, because
 
1578
                # merge_inner has set the ids. - this corner is not yet
1560
1579
                # layered well enough to prevent double handling.
1561
1580
                # XXX TODO: Fix the double handling: telling the tree about
1562
1581
                # the already known parent data is wasteful.
1616
1635
                            fl.append(subf_norm)
1617
1636
                    else:
1618
1637
                        fl.append(subf)
1619
 
            
 
1638
 
1620
1639
            fl.sort()
1621
1640
            for subf in fl:
1622
1641
                subp = pathjoin(path, subf)
1773
1792
 
1774
1793
    def _change_last_revision(self, new_revision):
1775
1794
        """Template method part of set_last_revision to perform the change.
1776
 
        
 
1795
 
1777
1796
        This is used to allow WorkingTree3 instances to not affect branch
1778
1797
        when their last revision is set.
1779
1798
        """
1805
1824
        # as commit already has that ready-to-use [while the format is the
1806
1825
        # same, that is].
1807
1826
        try:
1808
 
            # this double handles the inventory - unpack and repack - 
 
1827
            # this double handles the inventory - unpack and repack -
1809
1828
            # but is easier to understand. We can/should put a conditional
1810
1829
            # in here based on whether the inventory is in the latest format
1811
1830
            # - perhaps we should repack all inventories on a repository
1812
1831
            # upgrade ?
1813
1832
            # the fast path is to copy the raw xml from the repository. If the
1814
 
            # xml contains 'revision_id="', then we assume the right 
 
1833
            # xml contains 'revision_id="', then we assume the right
1815
1834
            # revision_id is set. We must check for this full string, because a
1816
1835
            # root node id can legitimately look like 'revision_id' but cannot
1817
1836
            # contain a '"'.
1818
1837
            xml = self.branch.repository.get_inventory_xml(new_revision)
1819
1838
            firstline = xml.split('\n', 1)[0]
1820
 
            if (not 'revision_id="' in firstline or 
 
1839
            if (not 'revision_id="' in firstline or
1821
1840
                'format="7"' not in firstline):
1822
1841
                inv = self.branch.repository.deserialise_inventory(
1823
1842
                    new_revision, xml)
1830
1849
        """Read the cached basis inventory."""
1831
1850
        path = self._basis_inventory_name()
1832
1851
        return self._transport.get_bytes(path)
1833
 
        
 
1852
 
1834
1853
    @needs_read_lock
1835
1854
    def read_working_inventory(self):
1836
1855
        """Read the working inventory.
1837
 
        
 
1856
 
1838
1857
        :raises errors.InventoryModified: read_working_inventory will fail
1839
1858
            when the current in memory inventory has been modified.
1840
1859
        """
1841
 
        # conceptually this should be an implementation detail of the tree. 
 
1860
        # conceptually this should be an implementation detail of the tree.
1842
1861
        # XXX: Deprecate this.
1843
1862
        # ElementTree does its own conversion from UTF-8, so open in
1844
1863
        # binary.
2041
2060
            name = os.path.basename(path)
2042
2061
            if name == "":
2043
2062
                continue
2044
 
            # fixme, there should be a factory function inv,add_?? 
 
2063
            # fixme, there should be a factory function inv,add_??
2045
2064
            if kind == 'directory':
2046
2065
                inv.add(InventoryDirectory(file_id, name, parent))
2047
2066
            elif kind == 'file':
2055
2074
    @needs_tree_write_lock
2056
2075
    def set_root_id(self, file_id):
2057
2076
        """Set the root id for this tree."""
2058
 
        # for compatability 
 
2077
        # for compatability
2059
2078
        if file_id is None:
2060
2079
            raise ValueError(
2061
2080
                'WorkingTree.set_root_id with fileid=None')
2065
2084
    def _set_root_id(self, file_id):
2066
2085
        """Set the root id for this tree, in a format specific manner.
2067
2086
 
2068
 
        :param file_id: The file id to assign to the root. It must not be 
 
2087
        :param file_id: The file id to assign to the root. It must not be
2069
2088
            present in the current inventory or an error will occur. It must
2070
2089
            not be None, but rather a valid file id.
2071
2090
        """
2090
2109
 
2091
2110
    def unlock(self):
2092
2111
        """See Branch.unlock.
2093
 
        
 
2112
 
2094
2113
        WorkingTree locking just uses the Branch locking facilities.
2095
2114
        This is current because all working trees have an embedded branch
2096
2115
        within them. IF in the future, we were to make branch data shareable
2097
 
        between multiple working trees, i.e. via shared storage, then we 
 
2116
        between multiple working trees, i.e. via shared storage, then we
2098
2117
        would probably want to lock both the local tree, and the branch.
2099
2118
        """
2100
2119
        raise NotImplementedError(self.unlock)
2152
2171
        # cant set that until we update the working trees last revision to be
2153
2172
        # one from the new branch, because it will just get absorbed by the
2154
2173
        # parent de-duplication logic.
2155
 
        # 
 
2174
        #
2156
2175
        # We MUST save it even if an error occurs, because otherwise the users
2157
2176
        # local work is unreferenced and will appear to have been lost.
2158
 
        # 
 
2177
        #
2159
2178
        result = 0
2160
2179
        try:
2161
2180
            last_rev = self.get_parent_ids()[0]
2504
2523
                self)._get_rules_searcher(default_searcher)
2505
2524
        return self._rules_searcher
2506
2525
 
 
2526
    def get_shelf_manager(self):
 
2527
        """Return the ShelfManager for this WorkingTree."""
 
2528
        from bzrlib.shelf import ShelfManager
 
2529
        return ShelfManager(self, self._transport)
 
2530
 
2507
2531
 
2508
2532
class WorkingTree2(WorkingTree):
2509
2533
    """This is the Format 2 working tree.
2510
2534
 
2511
 
    This was the first weave based working tree. 
 
2535
    This was the first weave based working tree.
2512
2536
     - uses os locks for locking.
2513
2537
     - uses the branch last-revision.
2514
2538
    """
2547
2571
            if self._inventory_is_modified:
2548
2572
                self.flush()
2549
2573
            self._write_hashcache_if_dirty()
2550
 
                    
 
2574
 
2551
2575
        # reverse order of locking.
2552
2576
        try:
2553
2577
            return self._control_files.unlock()
2588
2612
 
2589
2613
    @needs_tree_write_lock
2590
2614
    def set_conflicts(self, conflicts):
2591
 
        self._put_rio('conflicts', conflicts.to_stanzas(), 
 
2615
        self._put_rio('conflicts', conflicts.to_stanzas(),
2592
2616
                      CONFLICT_HEADER_1)
2593
2617
 
2594
2618
    @needs_tree_write_lock
2643
2667
     * a format string,
2644
2668
     * an open routine.
2645
2669
 
2646
 
    Formats are placed in an dict by their format string for reference 
 
2670
    Formats are placed in an dict by their format string for reference
2647
2671
    during workingtree opening. Its not required that these be instances, they
2648
 
    can be classes themselves with class methods - it simply depends on 
 
2672
    can be classes themselves with class methods - it simply depends on
2649
2673
    whether state is needed for a given format or not.
2650
2674
 
2651
2675
    Once a format is deprecated, just deprecate the initialize and open
2652
 
    methods on the format class. Do not deprecate the object, as the 
 
2676
    methods on the format class. Do not deprecate the object, as the
2653
2677
    object will be created every time regardless.
2654
2678
    """
2655
2679
 
2699
2723
        """Is this format supported?
2700
2724
 
2701
2725
        Supported formats can be initialized and opened.
2702
 
        Unsupported formats may not support initialization or committing or 
 
2726
        Unsupported formats may not support initialization or committing or
2703
2727
        some other features depending on the reason for not being supported.
2704
2728
        """
2705
2729
        return True
2706
2730
 
 
2731
    def supports_content_filtering(self):
 
2732
        """True if this format supports content filtering."""
 
2733
        return False
 
2734
 
 
2735
    def supports_views(self):
 
2736
        """True if this format supports stored views."""
 
2737
        return False
 
2738
 
2707
2739
    @classmethod
2708
2740
    def register_format(klass, format):
2709
2741
        klass._formats[format.get_format_string()] = format
2718
2750
 
2719
2751
 
2720
2752
class WorkingTreeFormat2(WorkingTreeFormat):
2721
 
    """The second working tree format. 
 
2753
    """The second working tree format.
2722
2754
 
2723
2755
    This format modified the hash cache from the format 1 hash cache.
2724
2756
    """
2810
2842
        - is new in bzr 0.8
2811
2843
        - uses a LockDir to guard access for writes.
2812
2844
    """
2813
 
    
 
2845
 
2814
2846
    upgrade_recommended = True
2815
2847
 
2816
2848
    def get_format_string(self):
2833
2865
 
2834
2866
    def _open_control_files(self, a_bzrdir):
2835
2867
        transport = a_bzrdir.get_workingtree_transport(None)
2836
 
        return LockableFiles(transport, self._lock_file_name, 
 
2868
        return LockableFiles(transport, self._lock_file_name,
2837
2869
                             self._lock_class)
2838
2870
 
2839
2871
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2840
2872
                   accelerator_tree=None, hardlink=False):
2841
2873
        """See WorkingTreeFormat.initialize().
2842
 
        
 
2874
 
2843
2875
        :param revision_id: if supplied, create a working tree at a different
2844
2876
            revision than the branch is at.
2845
2877
        :param accelerator_tree: A tree which can be used for retrieving file
2916
2948
 
2917
2949
    def _open(self, a_bzrdir, control_files):
2918
2950
        """Open the tree itself.
2919
 
        
 
2951
 
2920
2952
        :param a_bzrdir: the dir for the tree.
2921
2953
        :param control_files: the control files for the tree.
2922
2954
        """
2932
2964
 
2933
2965
__default_format = WorkingTreeFormat4()
2934
2966
WorkingTreeFormat.register_format(__default_format)
 
2967
WorkingTreeFormat.register_format(WorkingTreeFormat5())
2935
2968
WorkingTreeFormat.register_format(WorkingTreeFormat3())
2936
2969
WorkingTreeFormat.set_default_format(__default_format)
2937
2970
# formats which have no format string are not discoverable