/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 breezy/workingtree.py

  • Committer: Jelmer Vernooij
  • Date: 2018-03-24 17:48:04 UTC
  • mfrom: (6921 work)
  • mto: This revision was merged to the branch mainline in revision 6923.
  • Revision ID: jelmer@jelmer.uk-20180324174804-xf22o05byoj12x1q
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
81
81
    _fmt = "This format does not support shelving changes."
82
82
 
83
83
 
84
 
class TreeEntry(object):
85
 
    """An entry that implements the minimum interface used by commands.
86
 
 
87
 
    This needs further inspection, it may be better to have
88
 
    InventoryEntries without ids - though that seems wrong. For now,
89
 
    this is a parallel hierarchy to InventoryEntry, and needs to become
90
 
    one of several things: decorates to that hierarchy, children of, or
91
 
    parents of it.
92
 
    Another note is that these objects are currently only used when there is
93
 
    no InventoryEntry available - i.e. for unversioned objects.
94
 
    Perhaps they should be UnversionedEntry et al. ? - RBC 20051003
95
 
    """
96
 
 
97
 
    def __eq__(self, other):
98
 
        # yes, this us ugly, TODO: best practice __eq__ style.
99
 
        return (isinstance(other, TreeEntry)
100
 
                and other.__class__ == self.__class__)
101
 
 
102
 
    def kind_character(self):
103
 
        return "???"
104
 
 
105
 
 
106
 
class TreeDirectory(TreeEntry):
107
 
    """See TreeEntry. This is a directory in a working tree."""
108
 
 
109
 
    def __eq__(self, other):
110
 
        return (isinstance(other, TreeDirectory)
111
 
                and other.__class__ == self.__class__)
112
 
 
113
 
    def kind_character(self):
114
 
        return "/"
115
 
 
116
 
 
117
 
class TreeFile(TreeEntry):
118
 
    """See TreeEntry. This is a regular file in a working tree."""
119
 
 
120
 
    def __eq__(self, other):
121
 
        return (isinstance(other, TreeFile)
122
 
                and other.__class__ == self.__class__)
123
 
 
124
 
    def kind_character(self):
125
 
        return ''
126
 
 
127
 
 
128
 
class TreeLink(TreeEntry):
129
 
    """See TreeEntry. This is a symlink in a working tree."""
130
 
 
131
 
    def __eq__(self, other):
132
 
        return (isinstance(other, TreeLink)
133
 
                and other.__class__ == self.__class__)
134
 
 
135
 
    def kind_character(self):
136
 
        return ''
137
 
 
138
 
 
139
84
class WorkingTree(mutabletree.MutableTree,
140
85
    controldir.ControlComponent):
141
86
    """Working copy tree.
206
151
        """See `Tree.has_versioned_directories`."""
207
152
        return self._format.supports_versioned_directories
208
153
 
 
154
    def supports_merge_modified(self):
 
155
        """Indicate whether this workingtree supports storing merge_modified.
 
156
        """
 
157
        return self._format.supports_merge_modified
 
158
 
209
159
    def _supports_executable(self):
210
160
        if sys.platform == 'win32':
211
161
            return False
423
373
                           _fstat=osutils.fstat):
424
374
        """See Tree.get_file_with_stat."""
425
375
        abspath = self.abspath(path)
426
 
        file_obj = open(abspath, 'rb')
 
376
        try:
 
377
            file_obj = open(abspath, 'rb')
 
378
        except EnvironmentError as e:
 
379
            if e.errno == errno.ENOENT:
 
380
                raise errors.NoSuchFile(path)
 
381
            raise
427
382
        stat_value = _fstat(file_obj.fileno())
428
383
        if filtered and self.supports_content_filtering():
429
384
            filters = self._content_filter_stack(path)
511
466
                    new_parents = [revision_id]
512
467
                tree.set_parent_ids(new_parents)
513
468
 
514
 
    def id2abspath(self, file_id):
515
 
        return self.abspath(self.id2path(file_id))
516
 
 
517
469
    def get_file_size(self, path, file_id=None):
518
470
        """See Tree.get_file_size"""
519
471
        # XXX: this returns the on-disk size; it should probably return the
778
730
            return file_id
779
731
 
780
732
    def get_symlink_target(self, path, file_id=None):
781
 
        if path is not None:
782
 
            abspath = self.abspath(path)
783
 
        else:
784
 
            abspath = self.id2abspath(file_id)
 
733
        abspath = self.abspath(path)
785
734
        target = osutils.readlink(abspath)
786
735
        return target
787
736
 
814
763
        # checkout in a subdirectory.  This can be avoided by not adding
815
764
        # it.  mbp 20070306
816
765
 
817
 
    def extract(self, file_id, format=None):
 
766
    def extract(self, path, file_id=None, format=None):
818
767
        """Extract a subtree from this tree.
819
768
 
820
769
        A new branch will be created, relative to the path for this tree.
826
775
        raise NotImplementedError(self.flush)
827
776
 
828
777
    def kind(self, relpath, file_id=None):
829
 
        if file_id is not None:
830
 
            return osutils.file_kind(self.id2abspath(file_id))
831
778
        return osutils.file_kind(self.abspath(relpath))
832
779
 
833
780
    def list_files(self, include_root=False, from_dir=None, recursive=True):
966
913
    def put_file_bytes_non_atomic(self, path, bytes, file_id=None):
967
914
        """See MutableTree.put_file_bytes_non_atomic."""
968
915
        with self.lock_write():
969
 
            stream = file(self.abspath(path), 'wb')
 
916
            stream = open(self.abspath(path), 'wb')
970
917
            try:
971
918
                stream.write(bytes)
972
919
            finally:
1020
967
                executable = bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
1021
968
        return kind, executable, stat_value
1022
969
 
1023
 
    def _file_size(self, entry, stat_value):
1024
 
        return stat_value.st_size
1025
 
 
1026
970
    def last_revision(self):
1027
971
        """Return the last revision of the branch for this tree.
1028
972
 
1353
1297
            resolved = _mod_conflicts.ConflictList()
1354
1298
            conflict_re = re.compile('^(<{7}|={7}|>{7})')
1355
1299
            for conflict in self.conflicts():
 
1300
                path = self.id2path(conflict.file_id)
1356
1301
                if (conflict.typestring != 'text conflict' or
1357
 
                    self.kind(self.id2path(conflict.file_id), conflict.file_id) != 'file'):
 
1302
                    self.kind(path, conflict.file_id) != 'file'):
1358
1303
                    un_resolved.append(conflict)
1359
1304
                    continue
1360
 
                my_file = open(self.id2abspath(conflict.file_id), 'rb')
 
1305
                my_file = open(self.abspath(path), 'rb')
1361
1306
                try:
1362
1307
                    for line in my_file:
1363
1308
                        if conflict_re.search(line):
1466
1411
 
1467
1412
    supports_versioned_directories = None
1468
1413
 
 
1414
    supports_merge_modified = True
 
1415
    """If this format supports storing merge modified hashes."""
 
1416
 
1469
1417
    supports_setting_file_ids = True
1470
1418
    """If this format allows setting the file id."""
1471
1419
 
1474
1422
 
1475
1423
    supports_leftmost_parent_id_as_ghost = True
1476
1424
 
 
1425
    supports_righthand_parent_id_as_ghost = True
 
1426
 
 
1427
    ignore_filename = None
 
1428
    """Name of file with ignore patterns, if any. """
 
1429
 
1477
1430
    def initialize(self, controldir, revision_id=None, from_branch=None,
1478
1431
                   accelerator_tree=None, hardlink=False):
1479
1432
        """Initialize a new working tree in controldir.