code: def test_merge_follow_parentds_subdataset_detached(
      path=None, *, on_adjusted
  ):
      if (
          on_adjusted
          and DEFAULT_REMOTE != "origin"
          and external_versions["cmd:annex"] <= "8.20210330"
      ):
          raise SkipTest(
              "'git annex init' with adjusted branch currently fails "
              "due to hard-coded 'origin'"
          )
  
      # Note: For the adjusted case, this is not much more than a smoke test that
      # on an adjusted branch we fail sensibly. The resulting state is not easy
      # to reason about nor desirable.
      path = Path(path)
      # $path/source/s0/s1
      # The additional dataset level is to gain some confidence that this works
      # for nested datasets.
      ds_src = Dataset(path / "source").create()
      ds_src_s0 = ds_src.create("s0")
      ds_src_s1 = ds_src_s0.create("s1")
      ds_src.save(recursive=True)
      if on_adjusted:
          # Note: We adjust after creating all the datasets above to avoid a bug
          # fixed in git-annex 7.20191024, specifically bbdeb1a1a (sync: Fix
          # crash when there are submodules and an adjusted branch is checked
          # out, 2019-10-23).
          for ds in [ds_src, ds_src_s0, ds_src_s1]:
              maybe_adjust_repo(ds.repo)
          ds_src.save(recursive=True)
      assert_repo_status(ds_src.path)
  
      ds_clone = install(
          source=ds_src.path,
          path=path / "clone",
          recursive=True,
          result_xfm="datasets",
      )
      ds_clone_s1 = Dataset(ds_clone.pathobj / "s0" / "s1")
  
      ds_src_s1.repo.checkout(DEFAULT_BRANCH + "^0")
      (ds_src_s1.pathobj / "foo").write_text("foo content")
      ds_src.save(recursive=True)
      assert_repo_status(ds_src.path)
  
      res = ds_clone.update(
          merge=True,
          recursive=True,
          follow="parentds",
          on_failure="ignore",
      )
      if on_adjusted:
          # The top-level update is okay because there is no parent revision to
          # update to.
          assert_in_results(
              res, status="ok", path=ds_clone.path, action="update"
          )
          # The subdataset, on the other hand, is impossible.
          assert_in_results(
              res,
              status="impossible",
              path=ds_clone_s1.path,
              action="update",
          )
          return
      assert_repo_status(ds_clone.path)
  
      # We brought in the revision and got to the same state of the remote.
      # Blind saving here without bringing in the current subdataset revision
      # would have resulted in a new commit in ds_clone that reverting the
      # last subdataset ID recorded in ds_src.
      eq_(ds_clone.repo.get_hexsha(), ds_src.repo.get_hexsha())
  
      # Record a revision in the parent and then move HEAD away from it so that
      # the explicit revision fetch fails.
      (ds_src_s1.pathobj / "bar").write_text("bar content")
      ds_src.save(recursive=True)
      ds_src_s1.repo.checkout(DEFAULT_BRANCH)
      # This is the default, but just in case:
      ds_src_s1.repo.config.set(
          "uploadpack.allowAnySHA1InWant", "false", scope="local"
      )
      # Configure the fetcher to use v0 because Git defaults to v2 as of
      # v2.26.0, which allows fetching unadvertised objects regardless
      # of the value of uploadpack.allowAnySHA1InWant.
      ds_clone_s1.repo.config.set(
          "protocol.version", "0", scope="local"
      )
      res = ds_clone.update(
          merge=True,
          recursive=True,
          follow="parentds",
          on_failure="ignore",
      )
      # The fetch with the explicit ref fails because it isn't advertised.
      assert_in_results(
          res,
          status="impossible",
          path=ds_clone_s1.path,
          action="update",
      )
  
      # Back to the detached head.
      ds_src_s1.repo.checkout("HEAD@{1}")
      # Set up a case where update() will not resolve the sibling.
      ds_clone_s1.repo.call_git(["branch", "--unset-upstream"])
      ds_clone_s1.config.reload(force=True)
      ds_clone_s1.repo.call_git(
          ["remote", "add", "other", ds_src_s1.path]
      )
      res = ds_clone.update(
          recursive=True, follow="parentds", on_failure="ignore"
      )
      # In this case, update() won't abort if we call with merge=False, but
      # it does if the revision wasn't brought down in the `fetch(all_=True)`
      # call.
      assert_in_results(
          res,
          status="impossible",
          path=ds_clone_s1.path,
          action="update",
      )
  
imports: import os
  import os.path
  from os.path import exists
  from os.path import join
  from unittest.mock import patch
  import pytest
  from datalad import cfg
  from datalad.api import clone, install, remove, update
  from datalad.distribution.update import _process_how_args
  from datalad.support.annexrepo import AnnexRepo
  from datalad.support.external_versions import external_versions
  from datalad.support.gitrepo import GitRepo
  from datalad.tests.utils_pytest import DEFAULT_BRANCH, DEFAULT_REMOTE, SkipTest, assert_false, assert_in, assert_in_results, assert_is_instance, assert_not_in, assert_raises, assert_repo_status, assert_result_count, assert_status, create_tree, eq_, known_failure_windows, maybe_adjust_repo, neq_, ok_, ok_file_has_content, skip_if_adjusted_branch, slow, with_tempfile
  from datalad.utils import Path, chpwd, knows_annex, rmtree
  from ..dataset import Dataset
label_desc: Use image node_id 15 for calling a global function with example usage: test_merge_follow_parentds_subdataset_detached(path) without return types