code: def _merge_info(repo, key, fs_info, dvc_info):
      from . import utils
  
      ret = {"repo": repo}
  
      if dvc_info:
          dvc_info["isout"] = any(
              (
                  len(out_key) <= len(key)
                  and key[: len(out_key)] == out_key
              )
              for out_key in repo.index.data_keys["repo"]
          )
          dvc_info["isdvc"] = dvc_info["isout"]
          ret["dvc_info"] = dvc_info
          ret["type"] = dvc_info["type"]
          ret["size"] = dvc_info["size"]
          if not fs_info and "md5" in dvc_info:
              ret["md5"] = dvc_info["md5"]
          if not fs_info and "md5-dos2unix" in dvc_info:
              ret["md5-dos2unix"] = dvc_info["md5-dos2unix"]
  
      if fs_info:
          ret["type"] = fs_info["type"]
          ret["size"] = fs_info["size"]
          ret["fs_info"] = fs_info
          isexec = False
          if fs_info["type"] == "file":
              isexec = utils.is_exec(fs_info["mode"])
          ret["isexec"] = isexec
  
      return ret
  
imports: import errno
  import functools
  import ntpath
  import os
  import posixpath
  import threading
  from collections import deque
  from contextlib import ExitStack, suppress
  from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple, Type, Union
  from fsspec.spec import AbstractFileSystem
  from funcy import wrap_with
  from dvc.log import logger
  from dvc_objects.fs.base import FileSystem
  from .data import DataFileSystem
label_desc: Use image node_id 3 for calling a global function with example usage: _merge_info(repo, key, fs_info, dvc_info) and returns: ret