/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

Merge bzr.dev r3466

Show diffs side-by-side

added added

removed removed

Lines of Context:
111
111
        deprecated_method,
112
112
        deprecated_function,
113
113
        DEPRECATED_PARAMETER,
114
 
        zero_eight,
115
 
        zero_eleven,
116
 
        zero_thirteen,
117
114
        )
118
115
 
119
116
 
123
120
ERROR_PATH_NOT_FOUND = 3    # WindowsError errno code, equivalent to ENOENT
124
121
 
125
122
 
126
 
@deprecated_function(zero_thirteen)
127
 
def gen_file_id(name):
128
 
    """Return new file id for the basename 'name'.
129
 
 
130
 
    Use bzrlib.generate_ids.gen_file_id() instead
131
 
    """
132
 
    return generate_ids.gen_file_id(name)
133
 
 
134
 
 
135
 
@deprecated_function(zero_thirteen)
136
 
def gen_root_id():
137
 
    """Return a new tree-root file id.
138
 
 
139
 
    This has been deprecated in favor of bzrlib.generate_ids.gen_root_id()
140
 
    """
141
 
    return generate_ids.gen_root_id()
142
 
 
143
 
 
144
123
class TreeEntry(object):
145
124
    """An entry that implements the minimum interface used by commands.
146
125
 
222
201
        if not _internal:
223
202
            raise errors.BzrError("Please use bzrdir.open_workingtree or "
224
203
                "WorkingTree.open() to obtain a WorkingTree.")
225
 
        assert isinstance(basedir, basestring), \
226
 
            "base directory %r is not a string" % basedir
227
204
        basedir = safe_unicode(basedir)
228
205
        mutter("opening working tree %r", basedir)
229
206
        if deprecated_passed(branch):
237
214
            self._control_files = self.branch.control_files
238
215
        else:
239
216
            # assume all other formats have their own control files.
240
 
            assert isinstance(_control_files, LockableFiles), \
241
 
                    "_control_files must be a LockableFiles, not %r" \
242
 
                    % _control_files
243
217
            self._control_files = _control_files
 
218
        self._transport = self._control_files._transport
244
219
        # update the whole cache up front and write to disk if anything changed;
245
220
        # in the future we might want to do this more selectively
246
221
        # two possible ways offer themselves : in self._unlock, write the cache
250
225
        wt_trans = self.bzrdir.get_workingtree_transport(None)
251
226
        cache_filename = wt_trans.local_abspath('stat-cache')
252
227
        self._hashcache = hashcache.HashCache(basedir, cache_filename,
253
 
                                              self._control_files._file_mode)
 
228
            self.bzrdir._get_file_mode())
254
229
        hc = self._hashcache
255
230
        hc.read()
256
231
        # is this scan needed ? it makes things kinda slow.
318
293
            False then the inventory is the same as that on disk and any
319
294
            serialisation would be unneeded overhead.
320
295
        """
321
 
        assert inv.root is not None
322
296
        self._inventory = inv
323
297
        self._inventory_is_modified = dirty
324
298
 
389
363
            if osutils.lexists(self.abspath(path)):
390
364
                yield ie.file_id
391
365
 
 
366
    def all_file_ids(self):
 
367
        """See Tree.iter_all_file_ids"""
 
368
        return set(self.inventory)
 
369
 
392
370
    def __repr__(self):
393
371
        return "<%s of %s>" % (self.__class__.__name__,
394
372
                               getattr(self, 'basedir', None))
430
408
    def _cleanup(self):
431
409
        self._flush_ignore_list_cache()
432
410
 
433
 
    @staticmethod
434
 
    @deprecated_method(zero_eight)
435
 
    def create(branch, directory):
436
 
        """Create a workingtree for branch at directory.
437
 
 
438
 
        If existing_directory already exists it must have a .bzr directory.
439
 
        If it does not exist, it will be created.
440
 
 
441
 
        This returns a new WorkingTree object for the new checkout.
442
 
 
443
 
        TODO FIXME RBC 20060124 when we have checkout formats in place this
444
 
        should accept an optional revisionid to checkout [and reject this if
445
 
        checking out into the same dir as a pre-checkout-aware branch format.]
446
 
 
447
 
        XXX: When BzrDir is present, these should be created through that 
448
 
        interface instead.
449
 
        """
450
 
        warnings.warn('delete WorkingTree.create', stacklevel=3)
451
 
        transport = get_transport(directory)
452
 
        if branch.bzrdir.root_transport.base == transport.base:
453
 
            # same dir 
454
 
            return branch.bzrdir.create_workingtree()
455
 
        # different directory, 
456
 
        # create a branch reference
457
 
        # and now a working tree.
458
 
        raise NotImplementedError
459
 
 
460
 
    @staticmethod
461
 
    @deprecated_method(zero_eight)
462
 
    def create_standalone(directory):
463
 
        """Create a checkout and a branch and a repo at directory.
464
 
 
465
 
        Directory must exist and be empty.
466
 
 
467
 
        please use BzrDir.create_standalone_workingtree
468
 
        """
469
 
        return bzrdir.BzrDir.create_standalone_workingtree(directory)
470
 
 
471
411
    def relpath(self, path):
472
412
        """Return the local path portion from a given path.
473
413
        
504
444
        basis = self.basis_tree()
505
445
        basis.lock_read()
506
446
        try:
507
 
            changes = self._iter_changes(basis, True, [self.id2path(file_id)],
 
447
            changes = self.iter_changes(basis, True, [self.id2path(file_id)],
508
448
                require_versioned=True).next()
509
449
            changed_content, kind = changes[2], changes[6]
510
450
            if not changed_content:
546
486
        else:
547
487
            parents = [last_rev]
548
488
        try:
549
 
            merges_file = self._control_files.get('pending-merges')
 
489
            merges_file = self._transport.get('pending-merges')
550
490
        except errors.NoSuchFile:
551
491
            pass
552
492
        else:
614
554
    __contains__ = has_id
615
555
 
616
556
    def get_file_size(self, file_id):
617
 
        return os.path.getsize(self.id2abspath(file_id))
 
557
        """See Tree.get_file_size"""
 
558
        try:
 
559
            return os.path.getsize(self.id2abspath(file_id))
 
560
        except OSError, e:
 
561
            if e.errno != errno.ENOENT:
 
562
                raise
 
563
            else:
 
564
                return None
618
565
 
619
566
    @needs_read_lock
620
567
    def get_file_sha1(self, file_id, path=None, stat_value=None):
660
607
        # function - they should be part of lock_write and unlock.
661
608
        inv = self.inventory
662
609
        for f, file_id, kind in zip(files, ids, kinds):
663
 
            assert kind is not None
664
610
            if file_id is None:
665
611
                inv.add_path(f, kind=kind)
666
612
            else:
761
707
        else:
762
708
            return (kind, None, None, None)
763
709
 
764
 
    @deprecated_method(zero_eleven)
765
 
    @needs_read_lock
766
 
    def pending_merges(self):
767
 
        """Return a list of pending merges.
768
 
 
769
 
        These are revisions that have been merged into the working
770
 
        directory but not yet committed.
771
 
 
772
 
        As of 0.11 this is deprecated. Please see WorkingTree.get_parent_ids()
773
 
        instead - which is available on all tree objects.
774
 
        """
775
 
        return self.get_parent_ids()[1:]
776
 
 
777
710
    def _check_parents_for_ghosts(self, revision_ids, allow_leftmost_as_ghost):
778
711
        """Common ghost checking functionality from set_parent_*.
779
712
 
788
721
 
789
722
    def _set_merges_from_parent_ids(self, parent_ids):
790
723
        merges = parent_ids[1:]
791
 
        self._control_files.put_bytes('pending-merges', '\n'.join(merges))
 
724
        self._transport.put_bytes('pending-merges', '\n'.join(merges),
 
725
            mode=self._control_files._file_mode)
792
726
 
793
727
    @needs_tree_write_lock
794
728
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
870
804
    def _put_rio(self, filename, stanzas, header):
871
805
        self._must_be_locked()
872
806
        my_file = rio_file(stanzas, header)
873
 
        self._control_files.put(filename, my_file)
 
807
        self._transport.put_file(filename, my_file,
 
808
            mode=self._control_files._file_mode)
874
809
 
875
810
    @needs_write_lock # because merge pulls data into the branch.
876
811
    def merge_from_branch(self, branch, to_revision=None, from_revision=None,
935
870
        still in the working inventory and have that text hash.
936
871
        """
937
872
        try:
938
 
            hashfile = self._control_files.get('merge-hashes')
 
873
            hashfile = self._transport.get('merge-hashes')
939
874
        except errors.NoSuchFile:
940
875
            return {}
941
876
        merge_hashes = {}
1098
1033
        sio = StringIO()
1099
1034
        self._serialize(self._inventory, sio)
1100
1035
        sio.seek(0)
1101
 
        self._control_files.put('inventory', sio)
 
1036
        self._transport.put_file('inventory', sio,
 
1037
            mode=self._control_files._file_mode)
1102
1038
        self._inventory_is_modified = False
1103
1039
 
1104
1040
    def _kind(self, relpath):
1265
1201
                                       DeprecationWarning)
1266
1202
 
1267
1203
        # check destination directory
1268
 
        assert not isinstance(from_paths, basestring)
 
1204
        if isinstance(from_paths, basestring):
 
1205
            raise ValueError()
1269
1206
        inv = self.inventory
1270
1207
        to_abs = self.abspath(to_dir)
1271
1208
        if not isdir(to_abs):
1535
1472
            # - RBC 20060907
1536
1473
            self._write_inventory(self._inventory)
1537
1474
    
1538
 
    @deprecated_method(zero_eight)
1539
 
    def iter_conflicts(self):
1540
 
        """List all files in the tree that have text or content conflicts.
1541
 
        DEPRECATED.  Use conflicts instead."""
1542
 
        return self._iter_conflicts()
1543
 
 
1544
1475
    def _iter_conflicts(self):
1545
1476
        conflicted = set()
1546
1477
        for info in self.list_files():
1698
1629
    def kind(self, file_id):
1699
1630
        return file_kind(self.id2abspath(file_id))
1700
1631
 
 
1632
    def stored_kind(self, file_id):
 
1633
        """See Tree.stored_kind"""
 
1634
        return self.inventory[file_id].kind
 
1635
 
1701
1636
    def _comparison_data(self, entry, path):
1702
1637
        abspath = self.abspath(path)
1703
1638
        try:
1785
1720
    def _reset_data(self):
1786
1721
        """Reset transient data that cannot be revalidated."""
1787
1722
        self._inventory_is_modified = False
1788
 
        result = self._deserialize(self._control_files.get('inventory'))
 
1723
        result = self._deserialize(self._transport.get('inventory'))
1789
1724
        self._set_inventory(result, dirty=False)
1790
1725
 
1791
1726
    @needs_tree_write_lock
1812
1747
 
1813
1748
    def _write_basis_inventory(self, xml):
1814
1749
        """Write the basis inventory XML to the basis-inventory file"""
1815
 
        assert isinstance(xml, str), 'serialised xml must be bytestring.'
1816
1750
        path = self._basis_inventory_name()
1817
1751
        sio = StringIO(xml)
1818
 
        self._control_files.put(path, sio)
 
1752
        self._transport.put_file(path, sio,
 
1753
            mode=self._control_files._file_mode)
1819
1754
 
1820
1755
    def _create_basis_xml_from_inventory(self, revision_id, inventory):
1821
1756
        """Create the text that will be saved in basis-inventory"""
1852
1787
    def read_basis_inventory(self):
1853
1788
        """Read the cached basis inventory."""
1854
1789
        path = self._basis_inventory_name()
1855
 
        return self._control_files.get(path).read()
 
1790
        return self._transport.get_bytes(path)
1856
1791
        
1857
1792
    @needs_read_lock
1858
1793
    def read_working_inventory(self):
1867
1802
        # binary.
1868
1803
        if self._inventory_is_modified:
1869
1804
            raise errors.InventoryModified(self)
1870
 
        result = self._deserialize(self._control_files.get('inventory'))
 
1805
        result = self._deserialize(self._transport.get('inventory'))
1871
1806
        self._set_inventory(result, dirty=False)
1872
1807
        return result
1873
1808
 
1927
1862
            has_changed_files = len(unknown_nested_files) > 0
1928
1863
            if not has_changed_files:
1929
1864
                for (file_id, path, content_change, versioned, parent_id, name,
1930
 
                     kind, executable) in self._iter_changes(self.basis_tree(),
 
1865
                     kind, executable) in self.iter_changes(self.basis_tree(),
1931
1866
                         include_unchanged=True, require_versioned=False,
1932
1867
                         want_unversioned=True, specific_files=files):
1933
1868
                    if versioned == (False, False):
1936
1871
                            # ... but not ignored
1937
1872
                            has_changed_files = True
1938
1873
                            break
1939
 
                    elif content_change and (kind[1] != None):
 
1874
                    elif content_change and (kind[1] is not None):
1940
1875
                        # Versioned and changed, but not deleted
1941
1876
                        has_changed_files = True
1942
1877
                        break
2082
2017
        """Set the root id for this tree."""
2083
2018
        # for compatability 
2084
2019
        if file_id is None:
2085
 
            symbol_versioning.warn(symbol_versioning.zero_twelve
2086
 
                % 'WorkingTree.set_root_id with fileid=None',
2087
 
                DeprecationWarning,
2088
 
                stacklevel=3)
2089
 
            file_id = ROOT_ID
2090
 
        else:
2091
 
            file_id = osutils.safe_file_id(file_id)
 
2020
            raise ValueError(
 
2021
                'WorkingTree.set_root_id with fileid=None')
 
2022
        file_id = osutils.safe_file_id(file_id)
2092
2023
        self._set_root_id(file_id)
2093
2024
 
2094
2025
    def _set_root_id(self, file_id):
2153
2084
          basis.
2154
2085
        - Do a 'normal' merge of the old branch basis if it is relevant.
2155
2086
        """
2156
 
        if self.branch.get_master_branch(possible_transports) is not None:
 
2087
        if self.branch.get_bound_location() is not None:
2157
2088
            self.lock_write()
2158
2089
            update_branch = True
2159
2090
        else:
2574
2505
    def _last_revision(self):
2575
2506
        """See Mutable.last_revision."""
2576
2507
        try:
2577
 
            return self._control_files.get('last-revision').read()
 
2508
            return self._transport.get_bytes('last-revision')
2578
2509
        except errors.NoSuchFile:
2579
2510
            return _mod_revision.NULL_REVISION
2580
2511
 
2582
2513
        """See WorkingTree._change_last_revision."""
2583
2514
        if revision_id is None or revision_id == NULL_REVISION:
2584
2515
            try:
2585
 
                self._control_files._transport.delete('last-revision')
 
2516
                self._transport.delete('last-revision')
2586
2517
            except errors.NoSuchFile:
2587
2518
                pass
2588
2519
            return False
2589
2520
        else:
2590
 
            self._control_files.put_bytes('last-revision', revision_id)
 
2521
            self._transport.put_bytes('last-revision', revision_id,
 
2522
                mode=self._control_files._file_mode)
2591
2523
            return True
2592
2524
 
2593
2525
    @needs_tree_write_lock
2605
2537
    @needs_read_lock
2606
2538
    def conflicts(self):
2607
2539
        try:
2608
 
            confile = self._control_files.get('conflicts')
 
2540
            confile = self._transport.get('conflicts')
2609
2541
        except errors.NoSuchFile:
2610
2542
            return _mod_conflicts.ConflictList()
2611
2543
        try:
2636
2568
            return path[:-len(suffix)]
2637
2569
 
2638
2570
 
2639
 
@deprecated_function(zero_eight)
2640
 
def is_control_file(filename):
2641
 
    """See WorkingTree.is_control_filename(filename)."""
2642
 
    ## FIXME: better check
2643
 
    filename = normpath(filename)
2644
 
    while filename != '':
2645
 
        head, tail = os.path.split(filename)
2646
 
        ## mutter('check %r for control file' % ((head, tail),))
2647
 
        if tail == '.bzr':
2648
 
            return True
2649
 
        if filename == head:
2650
 
            break
2651
 
        filename = head
2652
 
    return False
2653
 
 
2654
 
 
2655
2571
class WorkingTreeFormat(object):
2656
2572
    """An encapsulation of the initialization and open routines for a format.
2657
2573
 
2690
2606
        except errors.NoSuchFile:
2691
2607
            raise errors.NoWorkingTree(base=transport.base)
2692
2608
        except KeyError:
2693
 
            raise errors.UnknownFormatError(format=format_string)
 
2609
            raise errors.UnknownFormatError(format=format_string,
 
2610
                                            kind="working tree")
2694
2611
 
2695
2612
    def __eq__(self, other):
2696
2613
        return self.__class__ is other.__class__
2730
2647
 
2731
2648
    @classmethod
2732
2649
    def unregister_format(klass, format):
2733
 
        assert klass._formats[format.get_format_string()] is format
2734
2650
        del klass._formats[format.get_format_string()]
2735
2651
 
2736
2652
 
2746
2662
        """See WorkingTreeFormat.get_format_description()."""
2747
2663
        return "Working tree format 2"
2748
2664
 
2749
 
    def stub_initialize_remote(self, control_files):
2750
 
        """As a special workaround create critical control files for a remote working tree
 
2665
    def _stub_initialize_remote(self, branch):
 
2666
        """As a special workaround create critical control files for a remote working tree.
2751
2667
        
2752
2668
        This ensures that it can later be updated and dealt with locally,
2753
2669
        since BzrDirFormat6 and BzrDirFormat5 cannot represent dirs with 
2757
2673
        inv = Inventory()
2758
2674
        xml5.serializer_v5.write_inventory(inv, sio, working=True)
2759
2675
        sio.seek(0)
2760
 
        control_files.put('inventory', sio)
2761
 
 
2762
 
        control_files.put_bytes('pending-merges', '')
 
2676
        branch._transport.put_file('inventory', sio,
 
2677
            mode=branch.control_files._file_mode)
 
2678
        branch._transport.put_bytes('pending-merges', '',
 
2679
            mode=branch.control_files._file_mode)
2763
2680
        
2764
2681
 
2765
2682
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
2874
2791
        control_files = self._open_control_files(a_bzrdir)
2875
2792
        control_files.create_lock()
2876
2793
        control_files.lock_write()
2877
 
        control_files.put_utf8('format', self.get_format_string())
 
2794
        transport.put_bytes('format', self.get_format_string(),
 
2795
            mode=control_files._file_mode)
2878
2796
        if from_branch is not None:
2879
2797
            branch = from_branch
2880
2798
        else: