/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/transform.py

  • Committer: Andrew Bennetts
  • Date: 2008-10-27 06:14:45 UTC
  • mfrom: (3793 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3795.
  • Revision ID: andrew.bennetts@canonical.com-20081027061445-eqt9lz6uw1mbvq4g
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
    has_symlinks,
42
42
    lexists,
43
43
    pathjoin,
 
44
    sha_file,
44
45
    splitpath,
45
46
    supports_executable,
46
47
)
47
48
from bzrlib.progress import DummyProgress, ProgressPhase
48
49
from bzrlib.symbol_versioning import (
49
50
        deprecated_function,
 
51
        deprecated_in,
50
52
        )
51
53
from bzrlib.trace import mutter, warning
52
54
from bzrlib import tree
280
282
            raise ValueError('None is not a valid file id')
281
283
        if file_id in self._r_new_id and self._r_new_id[file_id] is not None:
282
284
            return self._r_new_id[file_id]
283
 
        elif file_id in self._tree.inventory:
284
 
            return self.trans_id_tree_file_id(file_id)
285
 
        elif file_id in self._non_present_ids:
286
 
            return self._non_present_ids[file_id]
287
285
        else:
288
 
            trans_id = self._assign_id()
289
 
            self._non_present_ids[file_id] = trans_id
290
 
            return trans_id
 
286
            try:
 
287
                self._tree.iter_entries_by_dir([file_id]).next()
 
288
            except StopIteration:
 
289
                if file_id in self._non_present_ids:
 
290
                    return self._non_present_ids[file_id]
 
291
                else:
 
292
                    trans_id = self._assign_id()
 
293
                    self._non_present_ids[file_id] = trans_id
 
294
                    return trans_id
 
295
            else:
 
296
                return self.trans_id_tree_file_id(file_id)
291
297
 
292
298
    def canonical_path(self, path):
293
299
        """Get the canonical tree-relative path"""
549
555
        # the file is old; the old id is still valid
550
556
        if self._new_root == trans_id:
551
557
            return self._tree.get_root_id()
552
 
        return self._tree.inventory.path2id(path)
 
558
        return self._tree.path2id(path)
553
559
 
554
560
    def final_file_id(self, trans_id):
555
561
        """Determine the file id after any changes are applied, or None.
1006
1012
        from_path = self._tree_id_paths.get(from_trans_id)
1007
1013
        if from_versioned:
1008
1014
            # get data from working tree if versioned
1009
 
            from_entry = self._tree.inventory[file_id]
 
1015
            from_entry = self._tree.iter_entries_by_dir([file_id]).next()[1]
1010
1016
            from_name = from_entry.name
1011
1017
            from_parent = from_entry.parent_id
1012
1018
        else:
1438
1444
        file_id = self.tree_file_id(parent_id)
1439
1445
        if file_id is None:
1440
1446
            return
1441
 
        children = getattr(self._tree.inventory[file_id], 'children', {})
 
1447
        entry = self._tree.iter_entries_by_dir([file_id]).next()[1]
 
1448
        children = getattr(entry, 'children', {})
1442
1449
        for child in children:
1443
1450
            childpath = joinpath(path, child)
1444
1451
            yield self.trans_id_tree_path(childpath)
1452
1459
        self._final_paths = FinalPaths(transform)
1453
1460
        self.__by_parent = None
1454
1461
        self._parent_ids = []
 
1462
        self._all_children_cache = {}
 
1463
        self._path2trans_id_cache = {}
 
1464
        self._final_name_cache = {}
1455
1465
 
1456
1466
    def _changes(self, file_id):
1457
1467
        for changes in self._transform.iter_changes():
1500
1510
            self.__by_parent = self._transform.by_parent()
1501
1511
        return self.__by_parent
1502
1512
 
 
1513
    def _comparison_data(self, entry, path):
 
1514
        kind, size, executable, link_or_sha1 = self.path_content_summary(path)
 
1515
        if kind == 'missing':
 
1516
            kind = None
 
1517
            executable = False
 
1518
        else:
 
1519
            file_id = self._transform.final_file_id(self._path2trans_id(path))
 
1520
            executable = self.is_executable(file_id, path)
 
1521
        return kind, executable, None
 
1522
 
1503
1523
    def lock_read(self):
1504
1524
        # Perhaps in theory, this should lock the TreeTransform?
1505
1525
        pass
1534
1554
            return self._transform._tree.has_id(file_id)
1535
1555
 
1536
1556
    def _path2trans_id(self, path):
 
1557
        # We must not use None here, because that is a valid value to store.
 
1558
        trans_id = self._path2trans_id_cache.get(path, object)
 
1559
        if trans_id is not object:
 
1560
            return trans_id
1537
1561
        segments = splitpath(path)
1538
1562
        cur_parent = self._transform.root
1539
1563
        for cur_segment in segments:
1540
1564
            for child in self._all_children(cur_parent):
1541
 
                if self._transform.final_name(child) == cur_segment:
 
1565
                final_name = self._final_name_cache.get(child)
 
1566
                if final_name is None:
 
1567
                    final_name = self._transform.final_name(child)
 
1568
                    self._final_name_cache[child] = final_name
 
1569
                if final_name == cur_segment:
1542
1570
                    cur_parent = child
1543
1571
                    break
1544
1572
            else:
 
1573
                self._path2trans_id_cache[path] = None
1545
1574
                return None
 
1575
        self._path2trans_id_cache[path] = cur_parent
1546
1576
        return cur_parent
1547
1577
 
1548
1578
    def path2id(self, path):
1556
1586
            raise errors.NoSuchId(self, file_id)
1557
1587
 
1558
1588
    def _all_children(self, trans_id):
 
1589
        children = self._all_children_cache.get(trans_id)
 
1590
        if children is not None:
 
1591
            return children
1559
1592
        children = set(self._transform.iter_tree_children(trans_id))
1560
1593
        # children in the _new_parent set are provided by _by_parent.
1561
1594
        children.difference_update(self._transform._new_parent.keys())
1562
1595
        children.update(self._by_parent.get(trans_id, []))
 
1596
        self._all_children_cache[trans_id] = children
1563
1597
        return children
1564
1598
 
1565
1599
    def iter_children(self, file_id):
1567
1601
        for child_trans_id in self._all_children(trans_id):
1568
1602
            yield self._transform.final_file_id(child_trans_id)
1569
1603
 
 
1604
    def extras(self):
 
1605
        possible_extras = set(self._transform.trans_id_tree_path(p) for p
 
1606
                              in self._transform._tree.extras())
 
1607
        possible_extras.update(self._transform._new_contents)
 
1608
        possible_extras.update(self._transform._removed_id)
 
1609
        for trans_id in possible_extras:
 
1610
            if self._transform.final_file_id(trans_id) is None:
 
1611
                yield self._final_paths._determine_path(trans_id)
 
1612
 
1570
1613
    def _make_inv_entries(self, ordered_entries, specific_file_ids):
1571
1614
        for trans_id, parent_file_id in ordered_entries:
1572
1615
            file_id = self._transform.final_file_id(trans_id)
1636
1679
            return self._transform._tree.get_file_mtime(file_id, path)
1637
1680
        return self._stat_limbo_file(file_id).st_mtime
1638
1681
 
 
1682
    def _file_size(self, entry, stat_value):
 
1683
        return self.get_file_size(entry.file_id)
 
1684
 
1639
1685
    def get_file_size(self, file_id):
1640
1686
        """See Tree.get_file_size"""
1641
1687
        if self.kind(file_id) == 'file':
1644
1690
            return None
1645
1691
 
1646
1692
    def get_file_sha1(self, file_id, path=None, stat_value=None):
1647
 
        return self._transform._tree.get_file_sha1(file_id)
 
1693
        trans_id = self._transform.trans_id_file_id(file_id)
 
1694
        kind = self._transform._new_contents.get(trans_id)
 
1695
        if kind is None:
 
1696
            return self._transform._tree.get_file_sha1(file_id)
 
1697
        if kind == 'file':
 
1698
            fileobj = self.get_file(file_id)
 
1699
            try:
 
1700
                return sha_file(fileobj)
 
1701
            finally:
 
1702
                fileobj.close()
1648
1703
 
1649
1704
    def is_executable(self, file_id, path=None):
 
1705
        if file_id is None:
 
1706
            return False
1650
1707
        trans_id = self._transform.trans_id_file_id(file_id)
1651
1708
        try:
1652
1709
            return self._transform._new_executability[trans_id]
1653
1710
        except KeyError:
1654
 
            return self._transform._tree.is_executable(file_id, path)
 
1711
            try:
 
1712
                return self._transform._tree.is_executable(file_id, path)
 
1713
            except OSError, e:
 
1714
                if e.errno == errno.ENOENT:
 
1715
                    return False
 
1716
                raise
 
1717
            except errors.NoSuchId:
 
1718
                return False
1655
1719
 
1656
1720
    def path_content_summary(self, path):
1657
1721
        trans_id = self._path2trans_id(path)
1689
1753
                      require_versioned=True, want_unversioned=False):
1690
1754
        """See InterTree.iter_changes.
1691
1755
 
1692
 
        This implementation does not support include_unchanged, specific_files,
1693
 
        or want_unversioned.  extra_trees, require_versioned, and pb are
1694
 
        ignored.
 
1756
        This has a fast path that is only used when the from_tree matches
 
1757
        the transform tree, and no fancy options are supplied.
1695
1758
        """
1696
 
        if from_tree is not self._transform._tree:
1697
 
            raise ValueError('from_tree must be transform source tree.')
1698
 
        if include_unchanged:
1699
 
            raise ValueError('include_unchanged is not supported')
1700
 
        if specific_files is not None:
1701
 
            raise ValueError('specific_files is not supported')
 
1759
        if (from_tree is not self._transform._tree or include_unchanged or
 
1760
            specific_files or want_unversioned):
 
1761
            return tree.InterTree(from_tree, self).iter_changes(
 
1762
                include_unchanged=include_unchanged,
 
1763
                specific_files=specific_files,
 
1764
                pb=pb,
 
1765
                extra_trees=extra_trees,
 
1766
                require_versioned=require_versioned,
 
1767
                want_unversioned=want_unversioned)
1702
1768
        if want_unversioned:
1703
1769
            raise ValueError('want_unversioned is not supported')
1704
1770
        return self._transform.iter_changes()
2095
2161
        raise errors.BadFileKindError(name, kind)
2096
2162
 
2097
2163
 
 
2164
@deprecated_function(deprecated_in((1, 9, 0)))
2098
2165
def create_by_entry(tt, entry, tree, trans_id, lines=None, mode_id=None):
2099
 
    """Create new file contents according to an inventory entry."""
 
2166
    """Create new file contents according to an inventory entry.
 
2167
 
 
2168
    DEPRECATED.  Use create_from_tree instead.
 
2169
    """
2100
2170
    if entry.kind == "file":
2101
2171
        if lines is None:
2102
2172
            lines = tree.get_file(entry.file_id).readlines()
2107
2177
        tt.create_directory(trans_id)
2108
2178
 
2109
2179
 
 
2180
def create_from_tree(tt, trans_id, tree, file_id, bytes=None):
 
2181
    """Create new file contents according to tree contents."""
 
2182
    kind = tree.kind(file_id)
 
2183
    if kind == 'directory':
 
2184
        tt.create_directory(trans_id)
 
2185
    elif kind == "file":
 
2186
        if bytes is None:
 
2187
            tree_file = tree.get_file(file_id)
 
2188
            try:
 
2189
                bytes = tree_file.readlines()
 
2190
            finally:
 
2191
                tree_file.close()
 
2192
        tt.create_file(bytes, trans_id)
 
2193
    elif kind == "symlink":
 
2194
        tt.create_symlink(tree.get_symlink_target(file_id), trans_id)
 
2195
    else:
 
2196
        raise AssertionError('Unknown kind %r' % kind)
 
2197
 
 
2198
 
2110
2199
def create_entry_executability(tt, entry, trans_id):
2111
2200
    """Set the executability of a trans_id according to an inventory entry"""
2112
2201
    if entry.kind == "file":