Interface to `git-ls-remote(1)`_. Returns the upstream hash for a remote
    reference.

    cwd
        The path to the git checkout. Optional (and ignored if present) when
        ``remote`` is set to a URL instead of a remote name.

    remote : origin
        The name of the remote to query. Can be the name of a git remote
        (which exists in the git checkout defined by the ``cwd`` parameter),
        or the URL of a remote repository.

        .. versionchanged:: 2015.8.0
            Argument renamed from ``repository`` to ``remote``

    ref
        The name of the ref to query. Optional, if not specified, all refs are
        returned. Can be a branch or tag name, or the full name of the
        reference (for example, to get the hash for a Github pull request number
        1234, ``ref`` can be set to ``refs/pull/1234/head``

        .. versionchanged:: 2015.8.0
            Argument renamed from ``branch`` to ``ref``

        .. versionchanged:: 2015.8.4
            Defaults to returning all refs instead of master.

    opts
        Any additional options to add to the command line, in a single string

        .. versionadded:: 2015.8.0

    git_opts
        Any additional options to add to git command itself (not the
        ``ls-remote`` subcommand), in a single string. This is useful for
        passing ``-c`` to run git with temporary changes to the git
        configuration.

        .. versionadded:: 2017.7.0

        .. note::
            This is only supported in git 1.7.2 and newer.

    user
        User under which to run the git command. By default, the command is run
        by the user under which the minion is running.

    password
        Windows only. Required when specifying ``user``. This parameter will be
        ignored on non-Windows platforms.

      .. versionadded:: 2016.3.4

    identity
        Path to a private key to use for ssh URLs

        .. warning::

            Unless Salt is invoked from the minion using ``salt-call``, the
            key(s) must be passphraseless. For greater security with
            passphraseless private keys, see the `sshd(8)`_ manpage for
            information on securing the keypair from the remote side in the
            ``authorized_keys`` file.

            .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT

        .. versionchanged:: 2015.8.7

            Salt will no longer attempt to use passphrase-protected keys unless
            invoked from the minion using ``salt-call``, to prevent blocking
            waiting for user input.

        Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file

        .. versionchanged:: 2016.3.0

    https_user
        Set HTTP Basic Auth username. Only accepted for HTTPS URLs.

        .. versionadded:: 2015.5.0

    https_pass
        Set HTTP Basic Auth password. Only accepted for HTTPS URLs.

        .. versionadded:: 2015.5.0

    ignore_retcode : False
        If ``True``, do not log an error to the minion log if the git command
        returns a nonzero exit status.

        .. versionadded:: 2015.8.0

    saltenv
        The default salt environment to pull sls files from

        .. versionadded:: 2016.3.1

    output_encoding
        Use this option to specify which encoding to use to decode the output
        from any git commands which are run. This should not be needed in most
        cases.

        .. note::
            This should only be needed if the files in the repository were
            created with filenames using an encoding other than UTF-8 to handle
            Unicode characters.

        .. versionadded:: 2018.3.1

    .. _`git-ls-remote(1)`: http://git-scm.com/docs/git-ls-remote

    CLI Example:

    .. code-block:: bash

        salt myminion git.ls_remote /path/to/repo origin master
        salt myminion git.ls_remote remote=https://mydomain.tld/repo.git ref=mytag opts='--tags'

def ls_remote(cwd=None,
              remote='origin',
              ref=None,
              opts='',
              git_opts='',
              user=None,
              password=None,
              identity=None,
              https_user=None,
              https_pass=None,
              ignore_retcode=False,
              output_encoding=None,
              saltenv='base'):
    '''
    Interface to `git-ls-remote(1)`_. Returns the upstream hash for a remote
    reference.

    cwd
        The path to the git checkout. Optional (and ignored if present) when
        ``remote`` is set to a URL instead of a remote name.

    remote : origin
        The name of the remote to query. Can be the name of a git remote
        (which exists in the git checkout defined by the ``cwd`` parameter),
        or the URL of a remote repository.

        .. versionchanged:: 2015.8.0
            Argument renamed from ``repository`` to ``remote``

    ref
        The name of the ref to query. Optional, if not specified, all refs are
        returned. Can be a branch or tag name, or the full name of the
        reference (for example, to get the hash for a Github pull request number
        1234, ``ref`` can be set to ``refs/pull/1234/head``

        .. versionchanged:: 2015.8.0
            Argument renamed from ``branch`` to ``ref``

        .. versionchanged:: 2015.8.4
            Defaults to returning all refs instead of master.

    opts
        Any additional options to add to the command line, in a single string

        .. versionadded:: 2015.8.0

    git_opts
        Any additional options to add to git command itself (not the
        ``ls-remote`` subcommand), in a single string. This is useful for
        passing ``-c`` to run git with temporary changes to the git
        configuration.

        .. versionadded:: 2017.7.0

        .. note::
            This is only supported in git 1.7.2 and newer.

    user
        User under which to run the git command. By default, the command is run
        by the user under which the minion is running.

    password
        Windows only. Required when specifying ``user``. This parameter will be
        ignored on non-Windows platforms.

      .. versionadded:: 2016.3.4

    identity
        Path to a private key to use for ssh URLs

        .. warning::

            Unless Salt is invoked from the minion using ``salt-call``, the
            key(s) must be passphraseless. For greater security with
            passphraseless private keys, see the `sshd(8)`_ manpage for
            information on securing the keypair from the remote side in the
            ``authorized_keys`` file.

            .. _`sshd(8)`: http://www.man7.org/linux/man-pages/man8/sshd.8.html#AUTHORIZED_KEYS_FILE_FORMAT

        .. versionchanged:: 2015.8.7

            Salt will no longer attempt to use passphrase-protected keys unless
            invoked from the minion using ``salt-call``, to prevent blocking
            waiting for user input.

        Key can also be specified as a SaltStack file server URL, eg. salt://location/identity_file

        .. versionchanged:: 2016.3.0

    https_user
        Set HTTP Basic Auth username. Only accepted for HTTPS URLs.

        .. versionadded:: 2015.5.0

    https_pass
        Set HTTP Basic Auth password. Only accepted for HTTPS URLs.

        .. versionadded:: 2015.5.0

    ignore_retcode : False
        If ``True``, do not log an error to the minion log if the git command
        returns a nonzero exit status.

        .. versionadded:: 2015.8.0

    saltenv
        The default salt environment to pull sls files from

        .. versionadded:: 2016.3.1

    output_encoding
        Use this option to specify which encoding to use to decode the output
        from any git commands which are run. This should not be needed in most
        cases.

        .. note::
            This should only be needed if the files in the repository were
            created with filenames using an encoding other than UTF-8 to handle
            Unicode characters.

        .. versionadded:: 2018.3.1

    .. _`git-ls-remote(1)`: http://git-scm.com/docs/git-ls-remote

    CLI Example:

    .. code-block:: bash

        salt myminion git.ls_remote /path/to/repo origin master
        salt myminion git.ls_remote remote=https://mydomain.tld/repo.git ref=mytag opts='--tags'
    '''
    if cwd is not None:
        cwd = _expand_path(cwd, user)
    try:
        remote = salt.utils.url.add_http_basic_auth(remote,
                                                    https_user,
                                                    https_pass,
                                                    https_only=True)
    except ValueError as exc:
        raise SaltInvocationError(exc.__str__())
    command = ['git'] + _format_git_opts(git_opts)
    command.append('ls-remote')
    command.extend(_format_opts(opts))
    command.append(remote)
    if ref:
        command.append(ref)
    output = _git_run(command,
                      cwd=cwd,
                      user=user,
                      password=password,
                      identity=identity,
                      ignore_retcode=ignore_retcode,
                      saltenv=saltenv,
                      output_encoding=output_encoding)['stdout']
    ret = {}
    for line in output.splitlines():
        try:
            ref_sha1, ref_name = line.split(None, 1)
        except IndexError:
            continue
        ret[ref_name] = ref_sha1
    return ret