~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-08-09 17:04:46 UTC
  • mfrom: (6055.1.3 822571-bzr-home-unicode)
  • Revision ID: pqm@pqm.ubuntu.com-20110809170446-f1wc1a8fhgnxi4cn
(vila) Decode BZR_HOME with fs encoding to allow unicode homes. (Vincent
 Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
127
127
    def has_id(self, file_id):
128
128
        raise NotImplementedError(self.has_id)
129
129
 
 
130
    @deprecated_method(deprecated_in((2, 4, 0)))
130
131
    def __contains__(self, file_id):
131
132
        return self.has_id(file_id)
132
133
 
276
277
 
277
278
        :param file_id: The file_id of the file.
278
279
        :param path: The path of the file.
 
280
 
279
281
        If both file_id and path are supplied, an implementation may use
280
282
        either one.
 
283
 
 
284
        :returns: A single byte string for the whole file.
281
285
        """
282
286
        my_file = self.get_file(file_id, path)
283
287
        try:
296
300
        """
297
301
        return osutils.split_lines(self.get_file_text(file_id, path))
298
302
 
299
 
    def get_file_sha1(self, file_id, path=None):
 
303
    def get_file_verifier(self, file_id, path=None, stat_value=None):
 
304
        """Return a verifier for a file.
 
305
 
 
306
        The default implementation returns a sha1.
 
307
 
 
308
        :param file_id: The handle for this file.
 
309
        :param path: The path that this file can be found at.
 
310
            These must point to the same object.
 
311
        :param stat_value: Optional stat value for the object
 
312
        :return: Tuple with verifier name and verifier data
 
313
        """
 
314
        return ("SHA1", self.get_file_sha1(file_id, path=path,
 
315
            stat_value=stat_value))
 
316
 
 
317
    def get_file_sha1(self, file_id, path=None, stat_value=None):
300
318
        """Return the SHA1 file for a file.
301
319
 
 
320
        :note: callers should use get_file_verifier instead
 
321
            where possible, as the underlying repository implementation may
 
322
            have quicker access to a non-sha1 verifier.
 
323
 
302
324
        :param file_id: The handle for this file.
303
325
        :param path: The path that this file can be found at.
304
326
            These must point to the same object.
 
327
        :param stat_value: Optional stat value for the object
305
328
        """
306
329
        raise NotImplementedError(self.get_file_sha1)
307
330
 
799
822
        return self.get_file(self._inventory.path2id(path), path)
800
823
 
801
824
 
802
 
######################################################################
803
 
# diff
804
 
 
805
 
# TODO: Merge these two functions into a single one that can operate
806
 
# on either a whole tree or a set of files.
807
 
 
808
 
# TODO: Return the diff in order by filename, not by category or in
809
 
# random order.  Can probably be done by lock-stepping through the
810
 
# filenames from both trees.
811
 
 
812
 
 
813
 
def file_status(filename, old_tree, new_tree):
814
 
    """Return single-letter status, old and new names for a file.
815
 
 
816
 
    The complexity here is in deciding how to represent renames;
817
 
    many complex cases are possible.
818
 
    """
819
 
    old_inv = old_tree.inventory
820
 
    new_inv = new_tree.inventory
821
 
    new_id = new_inv.path2id(filename)
822
 
    old_id = old_inv.path2id(filename)
823
 
 
824
 
    if not new_id and not old_id:
825
 
        # easy: doesn't exist in either; not versioned at all
826
 
        if new_tree.is_ignored(filename):
827
 
            return 'I', None, None
828
 
        else:
829
 
            return '?', None, None
830
 
    elif new_id:
831
 
        # There is now a file of this name, great.
832
 
        pass
833
 
    else:
834
 
        # There is no longer a file of this name, but we can describe
835
 
        # what happened to the file that used to have
836
 
        # this name.  There are two possibilities: either it was
837
 
        # deleted entirely, or renamed.
838
 
        if new_inv.has_id(old_id):
839
 
            return 'X', old_inv.id2path(old_id), new_inv.id2path(old_id)
840
 
        else:
841
 
            return 'D', old_inv.id2path(old_id), None
842
 
 
843
 
    # if the file_id is new in this revision, it is added
844
 
    if new_id and not old_inv.has_id(new_id):
845
 
        return 'A'
846
 
 
847
 
    # if there used to be a file of this name, but that ID has now
848
 
    # disappeared, it is deleted
849
 
    if old_id and not new_inv.has_id(old_id):
850
 
        return 'D'
851
 
 
852
 
    return 'wtf?'
853
 
 
854
 
 
855
825
def find_ids_across_trees(filenames, trees, require_versioned=True):
856
826
    """Find the ids corresponding to specified filenames.
857
827
 
1003
973
        if source_kind != target_kind:
1004
974
            changed_content = True
1005
975
        elif source_kind == 'file':
1006
 
            if (self.source.get_file_sha1(file_id, source_path, source_stat) !=
1007
 
                self.target.get_file_sha1(file_id, target_path, target_stat)):
 
976
            if not self.file_content_matches(file_id, file_id, source_path,
 
977
                    target_path, source_stat, target_stat):
1008
978
                changed_content = True
1009
979
        elif source_kind == 'symlink':
1010
980
            if (self.source.get_symlink_target(file_id) !=
1323
1293
                    changed_file_ids.add(result[0])
1324
1294
                    yield result
1325
1295
 
 
1296
    @needs_read_lock
 
1297
    def file_content_matches(self, source_file_id, target_file_id,
 
1298
            source_path=None, target_path=None, source_stat=None, target_stat=None):
 
1299
        """Check if two files are the same in the source and target trees.
 
1300
 
 
1301
        This only checks that the contents of the files are the same,
 
1302
        it does not touch anything else.
 
1303
 
 
1304
        :param source_file_id: File id of the file in the source tree
 
1305
        :param target_file_id: File id of the file in the target tree
 
1306
        :param source_path: Path of the file in the source tree
 
1307
        :param target_path: Path of the file in the target tree
 
1308
        :param source_stat: Optional stat value of the file in the source tree
 
1309
        :param target_stat: Optional stat value of the file in the target tree
 
1310
        :return: Boolean indicating whether the files have the same contents
 
1311
        """
 
1312
        source_verifier_kind, source_verifier_data = self.source.get_file_verifier(
 
1313
            source_file_id, source_path, source_stat)
 
1314
        target_verifier_kind, target_verifier_data = self.target.get_file_verifier(
 
1315
            target_file_id, target_path, target_stat)
 
1316
        if source_verifier_kind == target_verifier_kind:
 
1317
            return (source_verifier_data == target_verifier_data)
 
1318
        # Fall back to SHA1 for now
 
1319
        if source_verifier_kind != "SHA1":
 
1320
            source_sha1 = self.source.get_file_sha1(source_file_id,
 
1321
                    source_path, source_stat)
 
1322
        else:
 
1323
            source_sha1 = source_verifier_data
 
1324
        if target_verifier_kind != "SHA1":
 
1325
            target_sha1 = self.target.get_file_sha1(target_file_id,
 
1326
                    target_path, target_stat)
 
1327
        else:
 
1328
            target_sha1 = target_verifier_data
 
1329
        return (source_sha1 == target_sha1)
1326
1330
 
1327
1331
InterTree.register_optimiser(InterTree)
1328
1332