~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Brad Crittenden
  • Date: 2007-02-26 20:56:10 UTC
  • mfrom: (2300 +trunk)
  • mto: (2293.1.5 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 2311.
  • Revision ID: brad.crittenden@canonical.com-20070226205610-44oatbxrjjz3ajwy
merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
452
452
        return osutils.lexists(self.abspath(filename))
453
453
 
454
454
    def get_file(self, file_id):
 
455
        file_id = osutils.safe_file_id(file_id)
455
456
        return self.get_file_byname(self.id2path(file_id))
456
457
 
457
458
    def get_file_text(self, file_id):
 
459
        file_id = osutils.safe_file_id(file_id)
458
460
        return self.get_file(file_id).read()
459
461
 
460
462
    def get_file_byname(self, filename):
470
472
        incorrectly attributed to CURRENT_REVISION (but after committing, the
471
473
        attribution will be correct).
472
474
        """
 
475
        file_id = osutils.safe_file_id(file_id)
473
476
        basis = self.basis_tree()
474
477
        changes = self._iter_changes(basis, True, [file_id]).next()
475
478
        changed_content, kind = changes[2], changes[6]
503
506
        else:
504
507
            parents = [last_rev]
505
508
        try:
506
 
            merges_file = self._control_files.get_utf8('pending-merges')
 
509
            merges_file = self._control_files.get('pending-merges')
507
510
        except errors.NoSuchFile:
508
511
            pass
509
512
        else:
510
513
            for l in merges_file.readlines():
511
 
                parents.append(l.rstrip('\n'))
 
514
                revision_id = osutils.safe_revision_id(l.rstrip('\n'))
 
515
                parents.append(revision_id)
512
516
        return parents
513
517
 
514
518
    @needs_read_lock
518
522
        
519
523
    def _get_store_filename(self, file_id):
520
524
        ## XXX: badly named; this is not in the store at all
 
525
        file_id = osutils.safe_file_id(file_id)
521
526
        return self.abspath(self.id2path(file_id))
522
527
 
523
528
    @needs_read_lock
556
561
            tree.set_parent_ids([revision_id])
557
562
 
558
563
    def id2abspath(self, file_id):
 
564
        file_id = osutils.safe_file_id(file_id)
559
565
        return self.abspath(self.id2path(file_id))
560
566
 
561
567
    def has_id(self, file_id):
562
568
        # files that have been deleted are excluded
 
569
        file_id = osutils.safe_file_id(file_id)
563
570
        inv = self._inventory
564
571
        if not inv.has_id(file_id):
565
572
            return False
567
574
        return osutils.lexists(self.abspath(path))
568
575
 
569
576
    def has_or_had_id(self, file_id):
 
577
        file_id = osutils.safe_file_id(file_id)
570
578
        if file_id == self.inventory.root.file_id:
571
579
            return True
572
580
        return self.inventory.has_id(file_id)
574
582
    __contains__ = has_id
575
583
 
576
584
    def get_file_size(self, file_id):
 
585
        file_id = osutils.safe_file_id(file_id)
577
586
        return os.path.getsize(self.id2abspath(file_id))
578
587
 
579
588
    @needs_read_lock
580
589
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
590
        file_id = osutils.safe_file_id(file_id)
581
591
        if not path:
582
592
            path = self._inventory.id2path(file_id)
583
593
        return self._hashcache.get_sha1(path, stat_value)
584
594
 
585
595
    def get_file_mtime(self, file_id, path=None):
 
596
        file_id = osutils.safe_file_id(file_id)
586
597
        if not path:
587
598
            path = self._inventory.id2path(file_id)
588
599
        return os.lstat(self.abspath(path)).st_mtime
589
600
 
590
601
    if not supports_executable():
591
602
        def is_executable(self, file_id, path=None):
 
603
            file_id = osutils.safe_file_id(file_id)
592
604
            return self._inventory[file_id].executable
593
605
    else:
594
606
        def is_executable(self, file_id, path=None):
595
607
            if not path:
 
608
                file_id = osutils.safe_file_id(file_id)
596
609
                path = self._inventory.id2path(file_id)
597
610
            mode = os.lstat(self.abspath(path)).st_mode
598
611
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
610
623
            if file_id is None:
611
624
                inv.add_path(f, kind=kind)
612
625
            else:
 
626
                file_id = osutils.safe_file_id(file_id)
613
627
                inv.add_path(f, kind=kind, file_id=file_id)
614
628
        self._write_inventory(inv)
615
629
 
704
718
 
705
719
    def _set_merges_from_parent_ids(self, parent_ids):
706
720
        merges = parent_ids[1:]
707
 
        self._control_files.put_utf8('pending-merges', '\n'.join(merges))
 
721
        self._control_files.put_bytes('pending-merges', '\n'.join(merges))
708
722
 
709
723
    @needs_tree_write_lock
710
724
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
719
733
        :param revision_ids: The revision_ids to set as the parent ids of this
720
734
            working tree. Any of these may be ghosts.
721
735
        """
 
736
        revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
722
737
        self._check_parents_for_ghosts(revision_ids,
723
738
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
724
739
 
732
747
    @needs_tree_write_lock
733
748
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
734
749
        """See MutableTree.set_parent_trees."""
735
 
        parent_ids = [rev for (rev, tree) in parents_list]
 
750
        parent_ids = [osutils.safe_revision_id(rev) for (rev, tree) in parents_list]
736
751
 
737
752
        self._check_parents_for_ghosts(parent_ids,
738
753
            allow_leftmost_as_ghost=allow_leftmost_as_ghost)
766
781
    def set_merge_modified(self, modified_hashes):
767
782
        def iter_stanzas():
768
783
            for file_id, hash in modified_hashes.iteritems():
769
 
                yield Stanza(file_id=file_id, hash=hash)
 
784
                yield Stanza(file_id=file_id.decode('utf8'), hash=hash)
770
785
        self._put_rio('merge-hashes', iter_stanzas(), MERGE_MODIFIED_HEADER_1)
771
786
 
772
 
    @needs_tree_write_lock
773
787
    def _put_rio(self, filename, stanzas, header):
 
788
        self._must_be_locked()
774
789
        my_file = rio_file(stanzas, header)
775
790
        self._control_files.put(filename, my_file)
776
791
 
795
810
            merger.check_basis(check_clean=True, require_commits=False)
796
811
            if to_revision is None:
797
812
                to_revision = branch.last_revision()
 
813
            else:
 
814
                to_revision = osutils.safe_revision_id(to_revision)
798
815
            merger.other_rev_id = to_revision
799
816
            if merger.other_rev_id is None:
800
817
                raise error.NoCommits(branch)
819
836
 
820
837
    @needs_read_lock
821
838
    def merge_modified(self):
 
839
        """Return a dictionary of files modified by a merge.
 
840
 
 
841
        The list is initialized by WorkingTree.set_merge_modified, which is 
 
842
        typically called after we make some automatic updates to the tree
 
843
        because of a merge.
 
844
 
 
845
        This returns a map of file_id->sha1, containing only files which are
 
846
        still in the working inventory and have that text hash.
 
847
        """
822
848
        try:
823
849
            hashfile = self._control_files.get('merge-hashes')
824
850
        except errors.NoSuchFile:
833
859
            file_id = s.get("file_id")
834
860
            if file_id not in self.inventory:
835
861
                continue
836
 
            hash = s.get("hash")
837
 
            if hash == self.get_file_sha1(file_id):
838
 
                merge_hashes[file_id] = hash
 
862
            text_hash = s.get("hash")
 
863
            if text_hash == self.get_file_sha1(file_id):
 
864
                merge_hashes[file_id] = text_hash
839
865
        return merge_hashes
840
866
 
841
867
    @needs_write_lock
1282
1308
        :raises: NoSuchId if any fileid is not currently versioned.
1283
1309
        """
1284
1310
        for file_id in file_ids:
 
1311
            file_id = osutils.safe_file_id(file_id)
1285
1312
            if self._inventory.has_id(file_id):
1286
1313
                self._inventory.remove_recursive_id(file_id)
1287
1314
            else:
1364
1391
    @needs_write_lock
1365
1392
    def put_file_bytes_non_atomic(self, file_id, bytes):
1366
1393
        """See MutableTree.put_file_bytes_non_atomic."""
 
1394
        file_id = osutils.safe_file_id(file_id)
1367
1395
        stream = file(self.id2abspath(file_id), 'wb')
1368
1396
        try:
1369
1397
            stream.write(bytes)
1496
1524
    def is_locked(self):
1497
1525
        return self._control_files.is_locked()
1498
1526
 
 
1527
    def _must_be_locked(self):
 
1528
        if not self.is_locked():
 
1529
            raise errors.ObjectNotLocked(self)
 
1530
 
1499
1531
    def lock_read(self):
1500
1532
        """See Branch.lock_read, and WorkingTree.unlock."""
1501
1533
        self.branch.lock_read()
1532
1564
    @needs_tree_write_lock
1533
1565
    def set_last_revision(self, new_revision):
1534
1566
        """Change the last revision in the working tree."""
 
1567
        new_revision = osutils.safe_revision_id(new_revision)
1535
1568
        if self._change_last_revision(new_revision):
1536
1569
            self._cache_basis_inventory(new_revision)
1537
1570
 
1560
1593
 
1561
1594
    def _create_basis_xml_from_inventory(self, revision_id, inventory):
1562
1595
        """Create the text that will be saved in basis-inventory"""
1563
 
        inventory.revision_id = revision_id
 
1596
        # TODO: jam 20070209 This should be redundant, as the revision_id
 
1597
        #       as all callers should have already converted the revision_id to
 
1598
        #       utf8
 
1599
        inventory.revision_id = osutils.safe_revision_id(revision_id)
1564
1600
        return xml6.serializer_v6.write_inventory_to_string(inventory)
1565
1601
 
1566
1602
    def _cache_basis_inventory(self, new_revision):
1703
1739
                DeprecationWarning,
1704
1740
                stacklevel=3)
1705
1741
            file_id = ROOT_ID
 
1742
        else:
 
1743
            file_id = osutils.safe_file_id(file_id)
1706
1744
        inv = self._inventory
1707
1745
        orig_root_id = inv.root.file_id
1708
1746
        # TODO: it might be nice to exit early if there was nothing
1953
1991
    def _last_revision(self):
1954
1992
        """See Mutable.last_revision."""
1955
1993
        try:
1956
 
            return self._control_files.get_utf8('last-revision').read()
 
1994
            return osutils.safe_revision_id(
 
1995
                        self._control_files.get('last-revision').read())
1957
1996
        except errors.NoSuchFile:
1958
1997
            return None
1959
1998
 
1966
2005
                pass
1967
2006
            return False
1968
2007
        else:
1969
 
            self._control_files.put_utf8('last-revision', revision_id)
 
2008
            self._control_files.put_bytes('last-revision', revision_id)
1970
2009
            return True
1971
2010
 
1972
2011
    @needs_tree_write_lock
2124
2163
        sio.seek(0)
2125
2164
        control_files.put('inventory', sio)
2126
2165
 
2127
 
        control_files.put_utf8('pending-merges', '')
 
2166
        control_files.put_bytes('pending-merges', '')
2128
2167
        
2129
2168
 
2130
2169
    def initialize(self, a_bzrdir, revision_id=None):
2133
2172
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
2134
2173
        branch = a_bzrdir.open_branch()
2135
2174
        if revision_id is not None:
 
2175
            revision_id = osutils.safe_revision_id(revision_id)
2136
2176
            branch.lock_write()
2137
2177
            try:
2138
2178
                revision_history = branch.revision_history()
2224
2264
        branch = a_bzrdir.open_branch()
2225
2265
        if revision_id is None:
2226
2266
            revision_id = branch.last_revision()
 
2267
        else:
 
2268
            revision_id = osutils.safe_revision_id(revision_id)
2227
2269
        # WorkingTree3 can handle an inventory which has a unique root id.
2228
2270
        # as of bzr 0.12. However, bzr 0.11 and earlier fail to handle
2229
2271
        # those trees. And because there isn't a format bump inbetween, we