~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Robert Collins
  • Date: 2007-04-23 02:29:35 UTC
  • mfrom: (2441 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2442.
  • Revision ID: robertc@robertcollins.net-20070423022935-9hhongamvk6bfdso
Resolve conflicts with bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
 
39
39
from cStringIO import StringIO
40
40
import os
 
41
import sys
41
42
 
42
43
from bzrlib.lazy_import import lazy_import
43
44
lazy_import(globals(), """
68
69
    revisiontree,
69
70
    repository,
70
71
    textui,
 
72
    trace,
71
73
    transform,
 
74
    ui,
72
75
    urlutils,
73
76
    xml5,
74
77
    xml6,
117
120
MERGE_MODIFIED_HEADER_1 = "BZR merge-modified list format 1"
118
121
CONFLICT_HEADER_1 = "BZR conflict list format 1"
119
122
 
 
123
ERROR_PATH_NOT_FOUND = 3    # WindowsError errno code, equivalent to ENOENT
 
124
 
120
125
 
121
126
@deprecated_function(zero_thirteen)
122
127
def gen_file_id(name):
208
213
                 _internal=False,
209
214
                 _format=None,
210
215
                 _bzrdir=None):
211
 
        """Construct a WorkingTree for basedir.
 
216
        """Construct a WorkingTree instance. This is not a public API.
212
217
 
213
 
        If the branch is not supplied, it is opened automatically.
214
 
        If the branch is supplied, it must be the branch for this basedir.
215
 
        (branch.base is not cross checked, because for remote branches that
216
 
        would be meaningless).
 
218
        :param branch: A branch to override probing for the branch.
217
219
        """
218
220
        self._format = _format
219
221
        self.bzrdir = _bzrdir
220
222
        if not _internal:
221
 
            # not created via open etc.
222
 
            warnings.warn("WorkingTree() is deprecated as of bzr version 0.8. "
223
 
                 "Please use bzrdir.open_workingtree or WorkingTree.open().",
224
 
                 DeprecationWarning,
225
 
                 stacklevel=2)
226
 
            wt = WorkingTree.open(basedir)
227
 
            self._branch = wt.branch
228
 
            self.basedir = wt.basedir
229
 
            self._control_files = wt._control_files
230
 
            self._hashcache = wt._hashcache
231
 
            self._set_inventory(wt._inventory, dirty=False)
232
 
            self._format = wt._format
233
 
            self.bzrdir = wt.bzrdir
 
223
            raise errors.BzrError("Please use bzrdir.open_workingtree or "
 
224
                "WorkingTree.open() to obtain a WorkingTree.")
234
225
        assert isinstance(basedir, basestring), \
235
226
            "base directory %r is not a string" % basedir
236
227
        basedir = safe_unicode(basedir)
237
228
        mutter("opening working tree %r", basedir)
238
229
        if deprecated_passed(branch):
239
 
            if not _internal:
240
 
                warnings.warn("WorkingTree(..., branch=XXX) is deprecated"
241
 
                     " as of bzr 0.8. Please use bzrdir.open_workingtree() or"
242
 
                     " WorkingTree.open().",
243
 
                     DeprecationWarning,
244
 
                     stacklevel=2
245
 
                     )
246
230
            self._branch = branch
247
231
        else:
248
232
            self._branch = self.bzrdir.open_branch()
277
261
            hc.write()
278
262
 
279
263
        if _inventory is None:
 
264
            # This will be acquired on lock_read() or lock_write()
280
265
            self._inventory_is_modified = False
281
 
            self.read_working_inventory()
 
266
            self._inventory = None
282
267
        else:
283
268
            # the caller of __init__ has provided an inventory,
284
269
            # we assume they know what they are doing - as its only
544
529
        return self.abspath(self.id2path(file_id))
545
530
 
546
531
    @needs_read_lock
547
 
    def clone(self, to_bzrdir, revision_id=None, basis=None):
 
532
    def clone(self, to_bzrdir, revision_id=None):
548
533
        """Duplicate this working tree into to_bzr, including all state.
549
534
        
550
535
        Specifically modified files are kept as modified, but
556
541
            If not None, the cloned tree will have its last revision set to 
557
542
            revision, and and difference between the source trees last revision
558
543
            and this one merged in.
559
 
 
560
 
        basis
561
 
            If not None, a closer copy of a tree which may have some files in
562
 
            common, and which file content should be preferentially copied from.
563
544
        """
564
545
        # assumes the target bzr dir format is compatible.
565
546
        result = self._format.initialize(to_bzrdir)
945
926
        
946
927
        A new branch will be created, relative to the path for this tree.
947
928
        """
 
929
        self.flush()
948
930
        def mkdirs(path):
949
931
            segments = osutils.splitpath(path)
950
932
            transport = self.branch.bzrdir.root_transport
1012
994
        self._control_files.put('inventory', sio)
1013
995
        self._inventory_is_modified = False
1014
996
 
 
997
    def _kind(self, relpath):
 
998
        return osutils.file_kind(self.abspath(relpath))
 
999
 
1015
1000
    def list_files(self, include_root=False):
1016
1001
        """Recursively list all files as (path, class, kind, id, entry).
1017
1002
 
1032
1017
            yield ('', 'V', 'directory', inv.root.file_id, inv.root)
1033
1018
        # Convert these into local objects to save lookup times
1034
1019
        pathjoin = osutils.pathjoin
1035
 
        file_kind = osutils.file_kind
 
1020
        file_kind = self._kind
1036
1021
 
1037
1022
        # transport.base ends in a slash, we want the piece
1038
1023
        # between the last two slashes
1098
1083
 
1099
1084
                fk = file_kind(fap)
1100
1085
 
1101
 
                if f_ie:
1102
 
                    if f_ie.kind != fk:
1103
 
                        raise errors.BzrCheckError(
1104
 
                            "file %r entered as kind %r id %r, now of kind %r"
1105
 
                            % (fap, f_ie.kind, f_ie.file_id, fk))
1106
 
 
1107
1086
                # make a last minute entry
1108
1087
                if f_ie:
1109
1088
                    yield fp[1:], c, fk, f_ie.file_id, f_ie
1419
1398
        # prevent race conditions with the lock
1420
1399
        return iter(
1421
1400
            [subp for subp in self.extras() if not self.is_ignored(subp)])
1422
 
    
 
1401
 
1423
1402
    @needs_tree_write_lock
1424
1403
    def unversion(self, file_ids):
1425
1404
        """Remove the file ids in file_ids from the current versioned set.
1625
1604
            mode = stat_value.st_mode
1626
1605
            kind = osutils.file_kind_from_stat_mode(mode)
1627
1606
            if not supports_executable():
1628
 
                executable = entry.executable
 
1607
                executable = entry is not None and entry.executable
1629
1608
            else:
1630
1609
                executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1631
1610
        return kind, executable, stat_value
2143
2122
            current_disk = disk_iterator.next()
2144
2123
            disk_finished = False
2145
2124
        except OSError, e:
2146
 
            if e.errno != errno.ENOENT:
 
2125
            if not (e.errno == errno.ENOENT or
 
2126
                (sys.platform == 'win32' and e.errno == ERROR_PATH_NOT_FOUND)):
2147
2127
                raise
2148
2128
            current_disk = None
2149
2129
            disk_finished = True
2289
2269
        self.set_conflicts(un_resolved)
2290
2270
        return un_resolved, resolved
2291
2271
 
 
2272
    def _validate(self):
 
2273
        """Validate internal structures.
 
2274
 
 
2275
        This is meant mostly for the test suite. To give it a chance to detect
 
2276
        corruption after actions have occurred. The default implementation is a
 
2277
        just a no-op.
 
2278
 
 
2279
        :return: None. An exception should be raised if there is an error.
 
2280
        """
 
2281
        return
 
2282
 
2292
2283
 
2293
2284
class WorkingTree2(WorkingTree):
2294
2285
    """This is the Format 2 working tree.
2298
2289
     - uses the branch last-revision.
2299
2290
    """
2300
2291
 
 
2292
    def __init__(self, *args, **kwargs):
 
2293
        super(WorkingTree2, self).__init__(*args, **kwargs)
 
2294
        # WorkingTree2 has more of a constraint that self._inventory must
 
2295
        # exist. Because this is an older format, we don't mind the overhead
 
2296
        # caused by the extra computation here.
 
2297
 
 
2298
        # Newer WorkingTree's should only have self._inventory set when they
 
2299
        # have a read lock.
 
2300
        if self._inventory is None:
 
2301
            self.read_working_inventory()
 
2302
 
2301
2303
    def lock_tree_write(self):
2302
2304
        """See WorkingTree.lock_tree_write().
2303
2305
 
2443
2445
 
2444
2446
    requires_rich_root = False
2445
2447
 
 
2448
    upgrade_recommended = False
 
2449
 
2446
2450
    @classmethod
2447
2451
    def find_format(klass, a_bzrdir):
2448
2452
        """Return the format for the working tree object in a_bzrdir."""
2497
2501
        del klass._formats[format.get_format_string()]
2498
2502
 
2499
2503
 
2500
 
 
2501
2504
class WorkingTreeFormat2(WorkingTreeFormat):
2502
2505
    """The second working tree format. 
2503
2506
 
2504
2507
    This format modified the hash cache from the format 1 hash cache.
2505
2508
    """
2506
2509
 
 
2510
    upgrade_recommended = True
 
2511
 
2507
2512
    def get_format_description(self):
2508
2513
        """See WorkingTreeFormat.get_format_description()."""
2509
2514
        return "Working tree format 2"
2572
2577
            raise NotImplementedError
2573
2578
        if not isinstance(a_bzrdir.transport, LocalTransport):
2574
2579
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
2575
 
        return WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
 
2580
        wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
2576
2581
                           _internal=True,
2577
2582
                           _format=self,
2578
2583
                           _bzrdir=a_bzrdir)
2579
 
 
 
2584
        return wt
2580
2585
 
2581
2586
class WorkingTreeFormat3(WorkingTreeFormat):
2582
2587
    """The second working tree format updated to record a format marker.
2589
2594
        - is new in bzr 0.8
2590
2595
        - uses a LockDir to guard access for writes.
2591
2596
    """
 
2597
    
 
2598
    upgrade_recommended = True
2592
2599
 
2593
2600
    def get_format_string(self):
2594
2601
        """See WorkingTreeFormat.get_format_string()."""
2679
2686
            raise NotImplementedError
2680
2687
        if not isinstance(a_bzrdir.transport, LocalTransport):
2681
2688
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
2682
 
        return self._open(a_bzrdir, self._open_control_files(a_bzrdir))
 
2689
        wt = self._open(a_bzrdir, self._open_control_files(a_bzrdir))
 
2690
        return wt
2683
2691
 
2684
2692
    def _open(self, a_bzrdir, control_files):
2685
2693
        """Open the tree itself.