1567 else: |
1567 else: |
1568 return self.read() |
1568 return self.read() |
1569 |
1569 |
1570 def find(self, key): |
1570 def find(self, key): |
1571 return self.read().find(key) |
1571 return self.read().find(key) |
|
1572 |
|
1573 class excludeddir(treemanifest): |
|
1574 """Stand-in for a directory that is excluded from the repository. |
|
1575 |
|
1576 With narrowing active on a repository that uses treemanifests, |
|
1577 some of the directory revlogs will be excluded from the resulting |
|
1578 clone. This is a huge storage win for clients, but means we need |
|
1579 some sort of pseudo-manifest to surface to internals so we can |
|
1580 detect a merge conflict outside the narrowspec. That's what this |
|
1581 class is: it stands in for a directory whose node is known, but |
|
1582 whose contents are unknown. |
|
1583 """ |
|
1584 def __init__(self, dir, node): |
|
1585 super(excludeddir, self).__init__(dir) |
|
1586 self._node = node |
|
1587 # Add an empty file, which will be included by iterators and such, |
|
1588 # appearing as the directory itself (i.e. something like "dir/") |
|
1589 self._files[''] = node |
|
1590 self._flags[''] = 't' |
|
1591 |
|
1592 # Manifests outside the narrowspec should never be modified, so avoid |
|
1593 # copying. This makes a noticeable difference when there are very many |
|
1594 # directories outside the narrowspec. Also, it makes sense for the copy to |
|
1595 # be of the same type as the original, which would not happen with the |
|
1596 # super type's copy(). |
|
1597 def copy(self): |
|
1598 return self |
|
1599 |
|
1600 class excludeddirmanifestctx(treemanifestctx): |
|
1601 """context wrapper for excludeddir - see that docstring for rationale""" |
|
1602 def __init__(self, dir, node): |
|
1603 self._dir = dir |
|
1604 self._node = node |
|
1605 |
|
1606 def read(self): |
|
1607 return excludeddir(self._dir, self._node) |
|
1608 |
|
1609 def write(self, *args): |
|
1610 raise error.ProgrammingError( |
|
1611 'attempt to write manifest from excluded dir %s' % self._dir) |
|
1612 |
|
1613 class excludedmanifestrevlog(manifestrevlog): |
|
1614 """Stand-in for excluded treemanifest revlogs. |
|
1615 |
|
1616 When narrowing is active on a treemanifest repository, we'll have |
|
1617 references to directories we can't see due to the revlog being |
|
1618 skipped. This class exists to conform to the manifestrevlog |
|
1619 interface for those directories and proactively prevent writes to |
|
1620 outside the narrowspec. |
|
1621 """ |
|
1622 |
|
1623 def __init__(self, dir): |
|
1624 self._dir = dir |
|
1625 |
|
1626 def __len__(self): |
|
1627 raise error.ProgrammingError( |
|
1628 'attempt to get length of excluded dir %s' % self._dir) |
|
1629 |
|
1630 def rev(self, node): |
|
1631 raise error.ProgrammingError( |
|
1632 'attempt to get rev from excluded dir %s' % self._dir) |
|
1633 |
|
1634 def linkrev(self, node): |
|
1635 raise error.ProgrammingError( |
|
1636 'attempt to get linkrev from excluded dir %s' % self._dir) |
|
1637 |
|
1638 def node(self, rev): |
|
1639 raise error.ProgrammingError( |
|
1640 'attempt to get node from excluded dir %s' % self._dir) |
|
1641 |
|
1642 def add(self, *args, **kwargs): |
|
1643 # We should never write entries in dirlogs outside the narrow clone. |
|
1644 # However, the method still gets called from writesubtree() in |
|
1645 # _addtree(), so we need to handle it. We should possibly make that |
|
1646 # avoid calling add() with a clean manifest (_dirty is always False |
|
1647 # in excludeddir instances). |
|
1648 pass |