Example #1
0
    def test_rebase_commit_with_independent_folder(self):
        stdout = self.hg("--debug", "rebase", "-s", self._c11, "-d", self._c25)
        self.assertIn(f'rebasing 1:{self._c11[:12]} "c11"\n', stdout)
        self.assertIn(f'rebasing 2:{self._c12[:12]} "c12"\n', stdout)
        self.assertIn(f'rebasing 3:{self._c13[:12]} "c13"\n', stdout)
        self.assertIn(f'rebasing 4:{self._c14[:12]} "c14"\n', stdout)
        self.assertIn(f'rebasing 5:{self._c15[:12]} "c15"\n', stdout)
        # Note that these are empirical values, not desired values.
        # We need to figure out why this hits the slow path and fix it!
        self.assert_update_logic(stdout, num_fast_path=2, num_slow_path=5)

        # Get the hash of the new head created as a result of the rebase.
        new_head = self.repo.log(
            revset=f"successors({self._c15})-{self._c15}")[0]

        # Record the pre-update inode count.
        inspector = eden_server_inspector.EdenServerInspector(
            self.eden, self.repo.path)
        inspector.unload_inode_for_path("numbers")
        pre_update_count = inspector.get_inode_count("numbers")
        print(f"loaded inode count before `hg update`: {pre_update_count}")

        # Verify that updating to the new head that was created as a result of
        # the rebase leaves Hg in the correct state.
        self.assertEqual(
            1,
            len(self.repo.log()),
            msg=("At the base commit, `hg log` should have only one entry."),
        )
        stdout = self.hg("--debug", "update", new_head)
        self.assert_update_logic(stdout, num_fast_path=1)
        self.assertEqual(
            11,
            len(self.repo.log()),
            msg=("The new head should include all the commits."),
        )

        # Verify the post-update inode count.
        post_update_count = inspector.get_inode_count("numbers")
        print(f"loaded inode count after `hg update`: {post_update_count}")
        self.assertGreaterEqual(
            post_update_count,
            pre_update_count,
            msg=("The inode count should not decrease due to `hg update`."),
        )
        num_new_inodes = post_update_count - pre_update_count
        self.assertLessEqual(
            num_new_inodes,
            2,
            msg=
            ("There should be no more than 2 new inodes as a result of the "
             "update. At the time this test was created, num_new_inodes is 0, "
             "but if we included unloaded inodes, there would be 2: one for "
             "numbers/1 and one for numbers/2."),
        )
Example #2
0
    def test_rebase_commit_with_independent_folder(self) -> None:
        #
        # We explicitly test non-in-memory rebase here, since the in-memory code path
        # doesn't use the working directory and therefore doesn't interact with EdenFS.
        #
        # Currently all of the rebase operations hit the slow, non-EdenFS aware update
        # code path, because update is called with branchmerge=True.
        #
        # With a non-in-memory rebase the code will first do a simple update to the
        # rebase destination commit (this hits the EdenFS fast path), then do the 5
        # rebase operations (slow path), followed by a final update back to the original
        # working directory parent commit (fast path).  Since we have the destination
        # commit checked out fortunately the slow path normally isn't horribly slow.
        #
        # With in-memory rebase enabled the initial and final updates are skipped, and
        # only the 5 slow-path rebases are performed, but purely in-memory.
        #
        proc = self.repo.run_hg(
            "--debug",
            "rebase",
            "--config",
            "rebase.experimental.inmemory=False",
            "-s",
            self._c11,
            "-d",
            self._c25,
            stderr=subprocess.STDOUT,
        )
        output = proc.stdout.decode("utf-8", errors="replace")
        self.assertIn(f'rebasing {self._c11[:12]} "c11"\n', output)
        self.assertIn(f'rebasing {self._c12[:12]} "c12"\n', output)
        self.assertIn(f'rebasing {self._c13[:12]} "c13"\n', output)
        self.assertIn(f'rebasing {self._c14[:12]} "c14"\n', output)
        self.assertIn(f'rebasing {self._c15[:12]} "c15"\n', output)
        self.assert_update_logic(output, num_fast_path=2, num_slow_path=5)

        # Get the hash of the new head created as a result of the rebase.
        new_head = self.repo.log(revset=f"successors({self._c15})-{self._c15}")[0]

        # Record the pre-update inode count.
        inspector = eden_server_inspector.EdenServerInspector(self.eden, self.repo.path)
        inspector.unload_inode_for_path("numbers")
        pre_update_count = inspector.get_inode_count("numbers")
        print(f"loaded inode count before `hg update`: {pre_update_count}")

        # Verify that updating to the new head that was created as a result of
        # the rebase leaves Hg in the correct state.
        self.assertEqual(
            1,
            len(self.repo.log()),
            msg=("At the base commit, `hg log` should have only one entry."),
        )
        stdout = self.hg("--debug", "update", new_head)
        self.assert_update_logic(stdout, num_fast_path=1)
        self.assertEqual(
            11,
            len(self.repo.log()),
            msg=("The new head should include all the commits."),
        )

        # Verify the post-update inode count.
        post_update_count = inspector.get_inode_count("numbers")
        print(f"loaded inode count after `hg update`: {post_update_count}")
        self.assertGreaterEqual(
            post_update_count,
            pre_update_count,
            msg=("The inode count should not decrease due to `hg update`."),
        )
        num_new_inodes = post_update_count - pre_update_count
        self.assertLessEqual(
            num_new_inodes,
            2,
            msg=(
                "There should be no more than 2 new inodes as a result of the "
                "update. At the time this test was created, num_new_inodes is 0, "
                "but if we included unloaded inodes, there would be 2: one for "
                "numbers/1 and one for numbers/2."
            ),
        )