code: def test_rerun_onto(path=None):
      ds = Dataset(path).create()
      if ds.repo.is_managed_branch():
          assert_status(
              "impossible",
              ds.rerun(onto="triggers-abort", on_failure="ignore"),
          )
          raise SkipTest("Test incompatible with adjusted branch")
  
      # Make sure we have more than one commit. The one commit case is checked
      # elsewhere.
      ds.repo.commit(msg="noop commit", options=["--allow-empty"])
  
      grow_file = op.join(path, "grows")
  
      # Make sure we can handle range-specifications that yield no results.
      for since in ["", "HEAD"]:
          assert_result_count(
              ds.rerun(
                  "HEAD", onto="", since=since, on_failure="ignore"
              ),
              1,
              status="impossible",
              action="run",
          )
  
      ds.run("echo static-content > static")
      ds.repo.tag("static")
      with swallow_outputs():
          ds.run(f"echo x$({cat_command} grows) > grows")
      ds.rerun()
      eq_("xx\n", open(grow_file).read())
  
      # If we run the "static" change on top of itself, we end up in the
      # same (but detached) place.
      ds.rerun(revision="static", onto="static")
      ok_(ds.repo.get_active_branch() is None)
      eq_(ds.repo.get_hexsha(), ds.repo.get_hexsha("static"))
  
      # If we run the "static" change from the same "base", we end up
      # with a new commit.
      ds.repo.checkout(DEFAULT_BRANCH)
      with swallow_outputs():
          ds.rerun(revision="static", onto="static^")
      ok_(ds.repo.get_active_branch() is None)
      neq_(ds.repo.get_hexsha(), ds.repo.get_hexsha("static"))
      ok_(
          all(
              r["state"] == "clean"
              for r in ds.diff(fr="HEAD", to="static")
          )
      )
      for revrange in ["..static", "static.."]:
          eq_(len(ds.repo.get_revisions(revrange)), 1)
  
      # Unlike the static change, if we run the ever-growing change on
      # top of itself, we end up with a new commit.
      ds.repo.checkout(DEFAULT_BRANCH)
      ds.rerun(onto="HEAD")
      ok_(ds.repo.get_active_branch() is None)
      neq_(ds.repo.get_hexsha(), ds.repo.get_hexsha(DEFAULT_BRANCH))
  
      # An empty `onto` means use the parent of the first revision.
      ds.repo.checkout(DEFAULT_BRANCH)
      with swallow_outputs():
          ds.rerun(since="static^", onto="")
      ok_(ds.repo.get_active_branch() is None)
      for revrange in [".." + DEFAULT_BRANCH, DEFAULT_BRANCH + ".."]:
          eq_(len(ds.repo.get_revisions(revrange)), 3)
  
      # An empty `onto` means use the parent of the first revision that
      # has a run command.
      ds.repo.checkout(DEFAULT_BRANCH)
      with swallow_outputs():
          ds.rerun(since="", onto="", branch="from-base")
      eq_(ds.repo.get_active_branch(), "from-base")
      ok_(
          all(
              r["state"] == "clean"
              for r in ds.diff(fr=DEFAULT_BRANCH, to="from-base")
          )
      )
      eq_(
          ds.repo.get_merge_base(["static", "from-base"]),
          ds.repo.get_hexsha("static^"),
      )
  
      # We abort when an explicitly specified `onto` doesn't exist.
      ds.repo.checkout(DEFAULT_BRANCH)
      assert_result_count(
          ds.rerun(
              since="",
              onto="doesnotexist",
              branch="from-base",
              on_failure="ignore",
          ),
          1,
          status="error",
          action="run",
      )
  
imports: import logging
  import os.path
  import sys
  from io import StringIO
  from os import remove
  import pytest
  from unittest.mock import patch
  from datalad.api import install, run
  from datalad.core.local.run import run_command
  from datalad.core.local.tests.test_run import last_commit_msg
  from datalad.distribution.dataset import Dataset
  from datalad.local.rerun import diff_revision, get_run_info, new_or_modified
  from datalad.support.exceptions import CommandError, IncompleteResultsError
  from datalad.support.gitrepo import GitRepo
  from datalad.tests.utils_pytest import DEFAULT_BRANCH, DEFAULT_REMOTE, SkipTest, assert_dict_equal, assert_false, assert_in, assert_in_results, assert_not_in, assert_not_in_results, assert_raises, assert_repo_status, assert_result_count, assert_status, create_tree, eq_, known_failure_windows, neq_, ok_, ok_exists, ok_file_has_content, ok_file_under_git, skip_if_adjusted_branch, slow, swallow_logs, swallow_outputs, with_tempfile, with_tree
  from datalad.utils import Path, chpwd, on_windows
label_desc: Use image node_id 3 for calling a global function with example usage: test_rerun_onto(path) without return types