searchConfigs = async (
  { configObject, configPath, cwd = process.cwd(), topLevelDir = cwd },
  logger
) => {
  debugLog('Searching for configuration files...')

  // Return explicit config object from js API
  if (configObject) {
    debugLog('Using single direct configuration object...')

    return { '': validateConfig(configObject, 'config object', logger) }
  }

  // Use only explicit config path instead of discovering multiple
  if (configPath) {
    debugLog('Using single configuration path...')

    const { config, filepath } = await loadConfig({ configPath }, logger)

    if (!config) return {}
    return { [configPath]: validateConfig(config, filepath, logger) }
  }

  const [cachedFilesWithStatus, otherFilesWithStatus] = await Promise.all([
    /** Get all possible config files known to git */
    execGit(EXEC_GIT, { cwd: topLevelDir }).then(parseGitZOutput),
    /** Get all possible config files from uncommitted files */
    execGit([...EXEC_GIT, '--others', '--exclude-standard'], { cwd: topLevelDir }).then(
      parseGitZOutput
    ),
  ])

  /** Sort possible config files so that deepest is first */
  const possibleConfigFiles = [...cachedFilesWithStatus, ...otherFilesWithStatus]
    .flatMap(
      /**
       * Leave out lines starting with "S " to ignore not-checked-out files in a sparse repo.
       * The "S" status means a tracked file that is "skip-worktree"
       * @see https://git-scm.com/docs/git-ls-files#Documentation/git-ls-files.txt--t
       */ (line) => (line.startsWith('S ') ? [] : [line.replace(/^[HSMRCK?U] /, '')])
    )
    .filter(filterPossibleConfigFiles)
    .map((file) => normalizePath(path.join(topLevelDir, file)))
    .filter(isInsideDirectory(cwd))
    .sort(sortDeepestParth)

  debugLog('Found possible config files:', possibleConfigFiles)

  /** Create object with key as config file, and value as null */
  const configs = possibleConfigFiles.reduce(
    (acc, configPath) => Object.assign(acc, { [configPath]: null }),
    {}
  )

  /** Load and validate all configs to the above object */
  await Promise.all(
    Object.keys(configs).map((configPath) =>
      loadConfig({ configPath }, logger).then(({ config, filepath }) => {
        if (config) {
          if (configPath !== filepath) {
            debugLog('Config file "%s" resolved to "%s"', configPath, filepath)
          }

          configs[configPath] = validateConfig(config, filepath, logger)
        }
      })
    )
  )

  /** Get validated configs from the above object, without any `null` values (not found) */
  const foundConfigs = Object.entries(configs)
    .filter(([, value]) => !!value)
    .reduce((acc, [key, value]) => Object.assign(acc, { [key]: value }), {})

  /**
   * Try to find a single config from parent directories
   * to match old behavior before monorepo support
   */
  if (!Object.keys(foundConfigs).length) {
    debugLog('Could not find config files inside "%s"', cwd)

    const { config, filepath } = await loadConfig({ cwd }, logger)
    if (config) {
      debugLog('Found parent configuration file from "%s"', filepath)

      foundConfigs[filepath] = validateConfig(config, filepath, logger)
    } else {
      debugLog('Could not find parent configuration files from "%s"', cwd)
    }
  }

  debugLog('Found %d config files', Object.keys(foundConfigs).length)

  return foundConfigs
}
Search all config files from the git repository, preferring those inside `cwd`.

@param {object} options
@param {Object} [options.configObject] - Explicit config object from the js API
@param {string} [options.configPath] - Explicit path to a config file
@param {string} [options.cwd] - Current working directory
@param {Logger} logger

@returns {Promise<{ [key: string]: { config: *, files: string[] } }>} found configs with filepath as key, and config as value