Пример #1
0
 def test_text_from_ghost_revision(self):
     repo = self.make_repository('text-from-ghost')
     inv = Inventory(revision_id=b'final-revid')
     inv.root.revision = b'root-revid'
     ie = inv.add_path('bla', 'file', b'myfileid')
     ie.revision = b'ghostrevid'
     ie.text_size = 42
     ie.text_sha1 = b"bee68c8acd989f5f1765b4660695275948bf5c00"
     rev = breezy.revision.Revision(timestamp=0,
                                    timezone=None,
                                    committer="Foo Bar <*****@*****.**>",
                                    message="Message",
                                    revision_id=b'final-revid')
     with repo.lock_write():
         repo.start_write_group()
         try:
             repo.add_revision(b'final-revid', rev, inv)
             try:
                 repo.texts.add_lines((b'myfileid', b'ghostrevid'),
                                      ((b'myfileid', b'ghost-text-parent'),),
                                      [b"line1\n", b"line2\n"])
             except errors.RevisionNotPresent:
                 raise TestSkipped("text ghost parents not supported")
             if repo.supports_rich_root():
                 root_id = inv.root.file_id
                 repo.texts.add_lines((inv.root.file_id, inv.root.revision),
                                      [], [])
         finally:
             repo.commit_write_group()
     repo.reconcile(thorough=True)
Пример #2
0
 def test_add_simple_rev(self):
     branch = self.make_svn_branch('d', lossy=True)  #1
     repos = branch.repository
     inv = Inventory(root_id=b'blabloe')
     mapping = repos.get_mapping()
     inventory_add_external(
         inv, b'blabloe', 'bla',
         mapping.revision_id_foreign_to_bzr(
             (repos.uuid, branch.get_branch_path(), 1)), 1, branch.base)
     expected_ie = TreeReference(
         mapping.generate_file_id((repos.uuid, branch.get_branch_path(), 1),
                                  u""),
         'bla',
         b'blabloe',
         revision=mapping.revision_id_foreign_to_bzr(
             (repos.uuid, branch.get_branch_path(), 1)),
         reference_revision=branch.last_revision())
     ie = inv.get_entry(inv.path2id('bla'))
     self.assertEqual(branch.last_revision(), ie.reference_revision)
     self.assertEquals(expected_ie.file_id, ie.file_id)
     self.assertEquals(expected_ie.revision, ie.revision)
     self.assertEquals(expected_ie.name, ie.name)
     self.assertEquals(expected_ie.reference_revision,
                       ie.reference_revision)
     self.assertEquals(expected_ie.parent_id, ie.parent_id)
     self.assertEqual(expected_ie, ie)
Пример #3
0
 def test_add_nested_norev(self):
     """Add a nested tree with no specific revision referenced."""
     branch = self.make_svn_branch('d', lossy=True)
     repos = branch.repository
     mapping = repos.get_mapping()
     inv = Inventory(root_id=b'blabloe')
     inventory_add_external(
         inv, b'blabloe', 'blie/bla',
         mapping.revision_id_foreign_to_bzr(
             (repos.uuid, branch.get_branch_path(), 1)), None, branch.base)
     expected_ie = TreeReference(
         mapping.generate_file_id((repos.uuid, branch.get_branch_path(), 1),
                                  u""),
         'bla',
         inv.path2id('blie'),
         reference_revision=CURRENT_REVISION,
         revision=mapping.revision_id_foreign_to_bzr(
             (repos.uuid, branch.get_branch_path(), 1)))
     ie = inv.get_entry(inv.path2id('blie/bla'))
     self.assertEquals(expected_ie.file_id, ie.file_id)
     self.assertEquals(expected_ie.revision, ie.revision)
     self.assertEquals(expected_ie.name, ie.name)
     self.assertEquals(expected_ie.reference_revision,
                       ie.reference_revision)
     self.assertEquals(expected_ie.parent_id, ie.parent_id)
     self.assertEqual(expected_ie, ie)
Пример #4
0
    def test_add_simple_norev(self):
        branch = self.make_svn_branch('d', lossy=True)
        repos = branch.repository
        mapping = repos.get_mapping()
        inv = Inventory(root_id='blabloe')
        inventory_add_external(inv, 'blabloe', 'bla',
            mapping.revision_id_foreign_to_bzr((repos.uuid, branch.get_branch_path(), 1)), None,
            branch.base)

        self.assertEqual(TreeReference(
            mapping.generate_file_id((repos.uuid, branch.get_branch_path(), 1), u""),
             'bla', 'blabloe',
             reference_revision=CURRENT_REVISION,
             revision=mapping.revision_id_foreign_to_bzr((repos.uuid, branch.get_branch_path(), 1))),
             inv.get_entry(inv.path2id('bla')))
Пример #5
0
    def setUp(self):
        super(TestsNeedingReweave, self).setUp()

        t = self.get_transport()
        # an empty inventory with no revision for testing with.
        repo = self.make_repository('inventory_without_revision')
        repo.lock_write()
        repo.start_write_group()
        inv = Inventory(revision_id=b'missing')
        inv.root.revision = b'missing'
        repo.add_inventory(b'missing', inv, [])
        repo.commit_write_group()
        repo.unlock()

        def add_commit(repo, revision_id, parent_ids):
            repo.lock_write()
            repo.start_write_group()
            inv = Inventory(revision_id=revision_id)
            inv.root.revision = revision_id
            root_id = inv.root.file_id
            sha1 = repo.add_inventory(revision_id, inv, parent_ids)
            repo.texts.add_lines((root_id, revision_id), [], [])
            rev = breezy.revision.Revision(
                timestamp=0,
                timezone=None,
                committer="Foo Bar <*****@*****.**>",
                message="Message",
                inventory_sha1=sha1,
                revision_id=revision_id)
            rev.parent_ids = parent_ids
            repo.add_revision(revision_id, rev)
            repo.commit_write_group()
            repo.unlock()

        # an empty inventory with no revision for testing with.
        # this is referenced by 'references_missing' to let us test
        # that all the cached data is correctly converted into ghost links
        # and the referenced inventory still cleaned.
        repo = self.make_repository('inventory_without_revision_and_ghost')
        repo.lock_write()
        repo.start_write_group()
        repo.add_inventory(b'missing', inv, [])
        repo.commit_write_group()
        repo.unlock()
        add_commit(repo, b'references_missing', [b'missing'])

        # a inventory with no parents and the revision has parents..
        # i.e. a ghost.
        repo = self.make_repository('inventory_one_ghost')
        add_commit(repo, b'ghost', [b'the_ghost'])

        # a inventory with a ghost that can be corrected now.
        t.copy_tree('inventory_one_ghost', 'inventory_ghost_present')
        bzrdir_url = self.get_url('inventory_ghost_present')
        bzrdir = BzrDir.open(bzrdir_url)
        repo = bzrdir.open_repository()
        add_commit(repo, b'the_ghost', [])
Пример #6
0
def read_inventory(inv_file):
    """Read inventory object from rio formatted inventory file"""
    from breezy.bzr.inventory import Inventory, InventoryFile
    s = read_stanza(inv_file)
    assert s['inventory_version'] == 7
    inv = Inventory()
    for s in read_stanzas(inv_file):
        kind, file_id = s.items[0]
        parent_id = None
        if 'parent_id' in s:
            parent_id = s['parent_id']
        if kind == 'file':
            ie = InventoryFile(file_id, s['name'], parent_id)
            ie.text_sha1 = s['text_sha1']
            ie.text_size = s['text_size']
        else:
            raise NotImplementedError()
        inv.add(ie)
    return inv
Пример #7
0
    def make_one_file_inventory(self,
                                repo,
                                revision,
                                parents,
                                inv_revision=None,
                                root_revision=None,
                                file_contents=None,
                                make_file_version=True):
        """Make an inventory containing a version of a file with ID 'a-file'.

        The file's ID will be 'a-file', and its filename will be 'a file name',
        stored at the tree root.

        :param repo: a repository to add the new file version to.
        :param revision: the revision ID of the new inventory.
        :param parents: the parents for this revision of 'a-file'.
        :param inv_revision: if not None, the revision ID to store in the
            inventory entry.  Otherwise, this defaults to revision.
        :param root_revision: if not None, the inventory's root.revision will
            be set to this.
        :param file_contents: if not None, the contents of this file version.
            Otherwise a unique default (based on revision ID) will be
            generated.
        """
        inv = Inventory(revision_id=revision)
        if root_revision is not None:
            inv.root.revision = root_revision
        file_id = b'a-file-id'
        entry = InventoryFile(file_id, 'a file name', b'TREE_ROOT')
        if inv_revision is not None:
            entry.revision = inv_revision
        else:
            entry.revision = revision
        entry.text_size = 0
        if file_contents is None:
            file_contents = b'%sline\n' % entry.revision
        entry.text_sha1 = osutils.sha_string(file_contents)
        inv.add(entry)
        if make_file_version:
            repo.texts.add_lines((file_id, revision),
                                 [(file_id, parent) for parent in parents],
                                 [file_contents])
        return inv
Пример #8
0
 def add_commit(repo, revision_id, parent_ids):
     repo.lock_write()
     repo.start_write_group()
     inv = Inventory(revision_id=revision_id)
     inv.root.revision = revision_id
     root_id = inv.root.file_id
     sha1 = repo.add_inventory(revision_id, inv, parent_ids)
     repo.texts.add_lines((root_id, revision_id), [], [])
     rev = breezy.revision.Revision(timestamp=0,
                                    timezone=None,
                                    committer="Foo Bar <*****@*****.**>",
                                    message="Message",
                                    inventory_sha1=sha1,
                                    revision_id=revision_id)
     rev.parent_ids = parent_ids
     repo.add_revision(revision_id, rev)
     repo.commit_write_group()
     repo.unlock()
Пример #9
0
 def root_inventory(self):
     # FIXME
     if self._bzr_inventory is not None:
         return self._bzr_inventory
     self._bzr_inventory = Inventory()
     self._bzr_inventory.revision_id = self.get_revision_id()
     root_repos = self._repository.svn_transport.get_svn_repos_root()
     editor = TreeBuildEditor(self)
     conn = self._repository.svn_transport.get_connection()
     try:
         reporter = conn.do_switch(
             self._revmeta.metarev.revnum, "", True,
             urlutils.join(root_repos, self._revmeta.metarev.branch_path).rstrip("/"), editor)
         try:
             reporter.set_path("", 0, True, None)
             reporter.finish()
         except:
             reporter.abort()
             raise
     finally:
         self._repository.svn_transport.add_connection(conn)
     return self._bzr_inventory
Пример #10
0
    def setUp(self):
        self.reduceLockdirTimeout()
        super(TestReconcileWithIncorrectRevisionCache, self).setUp()

        t = self.get_transport()
        # we need a revision with two parents in the wrong order
        # which should trigger reinsertion.
        # and another with the first one correct but the other two not
        # which should not trigger reinsertion.
        # these need to be in different repositories so that we don't
        # trigger a reconcile based on the other case.
        # there is no api to construct a broken knit repository at
        # this point. if we ever encounter a bad graph in a knit repo
        # we should add a lower level api to allow constructing such cases.

        # first off the common logic:
        self.first_tree = self.make_branch_and_tree('wrong-first-parent')
        self.second_tree = self.make_branch_and_tree(
            'reversed-secondary-parents')
        for t in [self.first_tree, self.second_tree]:
            t.commit('1', rev_id=b'1')
            uncommit(t.branch, tree=t)
            t.commit('2', rev_id=b'2')
            uncommit(t.branch, tree=t)
            t.commit('3', rev_id=b'3')
            uncommit(t.branch, tree=t)
        #second_tree = self.make_branch_and_tree('reversed-secondary-parents')
        # second_tree.pull(tree) # XXX won't copy the repo?
        repo_secondary = self.second_tree.branch.repository

        # now setup the wrong-first parent case
        repo = self.first_tree.branch.repository
        repo.lock_write()
        repo.start_write_group()
        inv = Inventory(revision_id=b'wrong-first-parent')
        inv.root.revision = b'wrong-first-parent'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, b'wrong-first-parent'), [], [])
        sha1 = repo.add_inventory(b'wrong-first-parent', inv, [b'2', b'1'])
        rev = Revision(timestamp=0,
                       timezone=None,
                       committer="Foo Bar <*****@*****.**>",
                       message="Message",
                       inventory_sha1=sha1,
                       revision_id=b'wrong-first-parent')
        rev.parent_ids = [b'1', b'2']
        repo.add_revision(b'wrong-first-parent', rev)
        repo.commit_write_group()
        repo.unlock()

        # now setup the wrong-secondary parent case
        repo = repo_secondary
        repo.lock_write()
        repo.start_write_group()
        inv = Inventory(revision_id=b'wrong-secondary-parent')
        inv.root.revision = b'wrong-secondary-parent'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, b'wrong-secondary-parent'), [], [])
        sha1 = repo.add_inventory(
            b'wrong-secondary-parent', inv, [b'1', b'3', b'2'])
        rev = Revision(timestamp=0,
                       timezone=None,
                       committer="Foo Bar <*****@*****.**>",
                       message="Message",
                       inventory_sha1=sha1,
                       revision_id=b'wrong-secondary-parent')
        rev.parent_ids = [b'1', b'2', b'3']
        repo.add_revision(b'wrong-secondary-parent', rev)
        repo.commit_write_group()
        repo.unlock()
Пример #11
0
    def root_inventory(self):
        if self._bzr_inventory is not None:
            return self._bzr_inventory
        self._bzr_inventory = Inventory(root_id=None)
        if self.get_root_id() is None:
            return self._bzr_inventory
        def add_file_to_inv(relpath, id, revid, adm):
            if not isinstance(relpath, text_type):
                raise TypeError(relpath)
            (propchanges, props) = adm.get_prop_diffs(
                self.workingtree.abspath(relpath).encode("utf-8"))
            if props.has_key(properties.PROP_SPECIAL):
                is_symlink = (self.get_file_stream_by_path(relpath).read(5) == "link ")
            else:
                is_symlink = False

            if is_symlink:
                ie = self._bzr_inventory.add_path(relpath, 'symlink', id)
                ie.symlink_target = self.get_file_stream_by_path(relpath).read()[len("link "):]
            else:
                ie = self._bzr_inventory.add_path(relpath, 'file', id)
                data = osutils.fingerprint_file(self.get_file_stream_by_path(relpath))
                ie.text_sha1 = data['sha1']
                ie.text_size = data['size']
                ie.executable = props.has_key(properties.PROP_EXECUTABLE)
            ie.revision = revid
            return ie

        def find_ids(entry):
            assert entry.url.startswith(self._repository.svn_transport.svn_url)
            relpath = urllib.unquote(entry.url[len(self._repository.svn_transport.svn_url):].strip("/"))
            assert isinstance(relpath, str)
            if entry.schedule in (wc.SCHEDULE_NORMAL,
                                  wc.SCHEDULE_DELETE,
                                  wc.SCHEDULE_REPLACE):
                return self.lookup_id(
                    self.workingtree.unprefix(relpath.decode("utf-8")))
            return (None, None)

        def add_dir_to_inv(relpath, adm, parent_id):
            if not isinstance(relpath, text_type):
                raise TypeError(relpath)
            entries = adm.entries_read(False)
            entry = entries[""]
            (id, revid) = find_ids(entry)
            if id is None:
                return

            # First handle directory itself
            ie = self._bzr_inventory.add_path(relpath, 'directory', id)
            ie.revision = revid
            if relpath == u"":
                self._bzr_inventory.revision_id = revid

            for name, entry in entries.iteritems():
                if name == "":
                    continue

                if not isinstance(relpath, text_type):
                    raise TypeError(relpath)
                if not isinstance(name, bytes):
                    raise TypeError(name)

                subrelpath = os.path.join(relpath, name.decode("utf-8"))

                assert entry

                if entry.kind == subvertpy.NODE_DIR:
                    try:
                        subwc = self.workingtree._get_wc(subrelpath)
                    except subvertpy.SubversionException as e:
                        msg, num = e.args
                        if num == subvertpy.ERR_WC_NOT_DIRECTORY:
                            raise BasisTreeIncomplete()
                        raise
                    try:
                        add_dir_to_inv(subrelpath, subwc, id)
                    finally:
                        subwc.close()
                else:
                    (subid, subrevid) = find_ids(entry)
                    if subid is not None:
                        add_file_to_inv(subrelpath, subid, subrevid, adm)

        with self.workingtree._get_wc() as adm:
            add_dir_to_inv(u"", adm, None)
        return self._bzr_inventory
Пример #12
0
class SvnBasisTree(SvnRevisionTreeCommon):
    """Optimized version of SvnRevisionTree."""

    def __repr__(self):
        return "<%s for '%r'>" % (self.__class__.__name__, self.workingtree)

    def __init__(self, workingtree):
        mutter("opening basistree for %r", workingtree)
        self.workingtree = workingtree
        self._bzr_inventory = None
        self._repository = workingtree.branch.repository
        self.id_map = self.workingtree.basis_idmap
        self.mapping = self.workingtree.branch.mapping
        self._real_tree = None

    def get_file_verifier(self, path, file_id=None, stat_value=None):
        with self.workingtree._get_wc(write_lock=False) as root_adm:
            entry = self.workingtree._get_entry(root_adm, path)
            return ("MD5", entry.checksum)

    @property
    def root_inventory(self):
        if self._bzr_inventory is not None:
            return self._bzr_inventory
        self._bzr_inventory = Inventory(root_id=None)
        if self.get_root_id() is None:
            return self._bzr_inventory
        def add_file_to_inv(relpath, id, revid, adm):
            if not isinstance(relpath, text_type):
                raise TypeError(relpath)
            (propchanges, props) = adm.get_prop_diffs(
                self.workingtree.abspath(relpath).encode("utf-8"))
            if props.has_key(properties.PROP_SPECIAL):
                is_symlink = (self.get_file_stream_by_path(relpath).read(5) == "link ")
            else:
                is_symlink = False

            if is_symlink:
                ie = self._bzr_inventory.add_path(relpath, 'symlink', id)
                ie.symlink_target = self.get_file_stream_by_path(relpath).read()[len("link "):]
            else:
                ie = self._bzr_inventory.add_path(relpath, 'file', id)
                data = osutils.fingerprint_file(self.get_file_stream_by_path(relpath))
                ie.text_sha1 = data['sha1']
                ie.text_size = data['size']
                ie.executable = props.has_key(properties.PROP_EXECUTABLE)
            ie.revision = revid
            return ie

        def find_ids(entry):
            assert entry.url.startswith(self._repository.svn_transport.svn_url)
            relpath = urllib.unquote(entry.url[len(self._repository.svn_transport.svn_url):].strip("/"))
            assert isinstance(relpath, str)
            if entry.schedule in (wc.SCHEDULE_NORMAL,
                                  wc.SCHEDULE_DELETE,
                                  wc.SCHEDULE_REPLACE):
                return self.lookup_id(
                    self.workingtree.unprefix(relpath.decode("utf-8")))
            return (None, None)

        def add_dir_to_inv(relpath, adm, parent_id):
            if not isinstance(relpath, text_type):
                raise TypeError(relpath)
            entries = adm.entries_read(False)
            entry = entries[""]
            (id, revid) = find_ids(entry)
            if id is None:
                return

            # First handle directory itself
            ie = self._bzr_inventory.add_path(relpath, 'directory', id)
            ie.revision = revid
            if relpath == u"":
                self._bzr_inventory.revision_id = revid

            for name, entry in entries.iteritems():
                if name == "":
                    continue

                if not isinstance(relpath, text_type):
                    raise TypeError(relpath)
                if not isinstance(name, bytes):
                    raise TypeError(name)

                subrelpath = os.path.join(relpath, name.decode("utf-8"))

                assert entry

                if entry.kind == subvertpy.NODE_DIR:
                    try:
                        subwc = self.workingtree._get_wc(subrelpath)
                    except subvertpy.SubversionException as e:
                        msg, num = e.args
                        if num == subvertpy.ERR_WC_NOT_DIRECTORY:
                            raise BasisTreeIncomplete()
                        raise
                    try:
                        add_dir_to_inv(subrelpath, subwc, id)
                    finally:
                        subwc.close()
                else:
                    (subid, subrevid) = find_ids(entry)
                    if subid is not None:
                        add_file_to_inv(subrelpath, subid, subrevid, adm)

        with self.workingtree._get_wc() as adm:
            add_dir_to_inv(u"", adm, None)
        return self._bzr_inventory

    def has_filename(self, path):
        try:
            self.lookup_id(path)
        except KeyError:
            return False
        else:
            return True

    def get_revision_id(self):
        """See Tree.get_revision_id()."""
        return self.workingtree.last_revision()

    def get_file_stream_by_path(self, name):
        """See Tree.get_file_stream_by_path()."""
        wt_path = self.workingtree.abspath(name)
        return wc.get_pristine_contents(wt_path)

    def kind(self, path, file_id=None):
        if file_id is None:
            file_id = self.path2id(path)
        if file_id is None:
            raise errors.NoSuchFile(path, self)
        return self.root_inventory.get_entry(file_id).kind

    def get_file_text(self, path, file_id=None):
        """See Tree.get_file_text()."""
        f = self.get_file_stream_by_path(path)
        try:
            return f.read()
        finally:
            f.close()

    def get_file(self, path, file_id=None):
        return self.get_file_stream_by_path(path)

    def get_file_properties(self, path, file_id=None):
        """See SubversionTree.get_file_properties()."""
        abspath = self.workingtree.abspath(path)
        if not os.path.isdir(abspath.encode(osutils._fs_enc)):
            wc_path = urlutils.dirname(path)
        else:
            wc_path = path
        with self.workingtree._get_wc(wc_path) as wc:
            (_, orig_props) = wc.get_prop_diffs(abspath.encode("utf-8"))
        return orig_props

    def annotate_iter(self, path, file_id=None, default_revision=CURRENT_REVISION):
        from .annotate import Annotater
        annotater = Annotater(self.workingtree.branch.repository)
        annotater.check_file_revs(
            self.get_revision_id(), self.workingtree.get_branch_path(),
            self.workingtree.base_revnum, self.mapping, path)
        return annotater.get_annotated()

    @property
    def real_tree(self):
        if self._real_tree is not None:
            return self._real_tree
        self._real_tree = self.workingtree.revision_tree(self.get_revision_id())
        return self._real_tree

    def all_file_ids(self):
        return self.real_tree.all_file_ids()

    def iter_entries_by_dir(self, specific_files=None):
        # FIXME
        if specific_files is not None:
            specific_file_ids = []
            for path in specific_files:
                file_id = self.path2id(path)
                if file_id is not None:
                    specific_file_ids.append(file_id)
        else:
            specific_file_ids = None
        try:
            return self.root_inventory.iter_entries_by_dir(
                specific_file_ids=specific_file_ids)
        except BasisTreeIncomplete:
            return self.real_tree.iter_entries_by_dir(
                specific_files=specific_files)

    def find_related_paths_across_trees(self, paths, trees=[],
            require_versioned=True):
        """Find related paths in tree corresponding to specified filenames in any
        of `lookup_trees`.

        All matches in all trees will be used, and all children of matched
        directories will be used.

        :param paths: The filenames to find related paths for (if None, returns
            None)
        :param trees: The trees to find file_ids within
        :param require_versioned: if true, all specified filenames must occur in
            at least one tree.
        :return: a set of paths for the specified filenames and their children
            in `tree`
        """
        if paths is None:
            return None;
        file_ids = self.paths2ids(
                paths, trees, require_versioned=require_versioned)
        ret = set()
        for file_id in file_ids:
            try:
                ret.add(self.id2path(file_id))
            except errors.NoSuchId:
                pass
        return ret
Пример #13
0
 def setUp(self):
     super(TestPulling, self).setUp()
     self.build_tree(['hg/', 'hg/a', 'hg/b', 'hg/dir/', 'hg/dir/c'])
     hgdir = HgControlDirFormat().initialize('hg')
     self.tree = hgdir.open_workingtree()
     mode = os.lstat('hg/b').st_mode
     os.chmod('hg/b', mode | stat.S_IEXEC)
     # do not add 'dir' to ensure that we pickup dir/c anyway : if hg
     # changes it behaviour, we want this test to start failing.
     self.tree.add(['a', 'b', 'dir/c'])
     self.tree.commit('foo')
     revone_inventory = Inventory()
     tip = self.tree.last_revision()
     revone_inventory.root.revision = tip
     entry = revone_inventory.add_path(u'a', kind='file', file_id='hg:a')
     entry.revision = tip
     entry.text_size = len('contents of hg/a\n')
     entry.text_sha1 = "72bcea9d6cba6ee7d3241bfa0c5e54506ad81a94"
     entry = revone_inventory.add_path(u'b', kind='file', file_id='hg:b')
     entry.executable = True
     entry.revision = tip
     entry.text_size = len('contents of hg/b\n')
     entry.text_sha1 = "b4d0c22d126cd0afeeeffa62961fb47c0932835a"
     entry = revone_inventory.add_path(u'dir',
                                       kind='directory',
                                       file_id='hg:dir')
     entry.revision = tip
     entry = revone_inventory.add_path(u'dir/c',
                                       kind='file',
                                       file_id='hg:dir_sc')
     entry.revision = tip
     entry.text_size = len('contents of hg/dir/c\n')
     entry.text_sha1 = "958be752affac0fee70471331b96fb3fc1809425"
     self.revone_inventory = revone_inventory
     self.revidone = tip
     #====== end revision one
     # in revisiontwo we add a new file to dir, which should not change
     # the revision_id on the inventory.
     self.build_tree(['hg/dir/d'])
     self.tree.add(['dir/d'])
     self.tree.commit('bar')
     self.revtwo_inventory = copy.deepcopy(revone_inventory)
     tip = self.tree.last_revision()
     entry = self.revtwo_inventory.add_path(u'dir/d',
                                            kind='file',
                                            file_id='hg:dir_sd')
     entry.revision = tip
     entry.text_size = len('contents of hg/dir/d\n')
     entry.text_sha1 = "f48fc342f707bfb4711790e1813c0df4d44e1a23"
     self.revidtwo = tip
     #====== end revision two
     # in revision three, we reset the exec flag on 'b'
     os.chmod('hg/b', mode)
     self.tree.commit('reset mode on b')
     self.revthree_inventory = copy.deepcopy(self.revtwo_inventory)
     tip = self.tree.last_revision()
     # should be a new file revision with exec reset
     entry = self.revthree_inventory.get_entry('hg:b')
     entry.revision = tip
     entry.executable = False
     self.revidthree = tip
     #====== end revision three
     # in revision four we change the file dir/c, which should not alter
     # the last-changed field for 'dir'.
     self.build_tree_contents([('hg/dir/c', 'new contents')])
     self.tree.commit('change dir/c')
     self.revfour_inventory = copy.deepcopy(self.revthree_inventory)
     tip = self.tree.last_revision()
     entry = self.revfour_inventory.get_entry('hg:dir_sc')
     entry.revision = tip
     entry.text_size = len('new contents')
     entry.text_sha1 = "7ffa72b76d5d66da37f4b614b7a822c01f23c183"
     self.revidfour = tip