Skip to content

gh should auto-select account based on repo remote / git config #13529

Description

@davidlovas

Problem

gh supports multiple authenticated accounts but requires manual gh auth switch every time you move between repos owned by different accounts. This is a constant source of friction — 404s, PRs attributed to the wrong account, CI triggered under the wrong identity.

Anyone managing separate personal and work GitHub accounts (which is extremely common) hits this daily.

Expected Behavior

gh should automatically select the correct authenticated account based on the current repo context. Two natural resolution strategies:

  1. git config github.account — works with git's existing includeIf / conditional includes, zero new config surface
  2. Remote origin org matching — map orgs to accounts in gh config, zero per-repo setup

Either way: cd into a repo, run gh pr create, correct account is used. No manual switching.

Current Workaround

A shell wrapper that calls gh auth switch before every invocation. It works but:

  • Mutates global state (not safe for concurrent terminal sessions)
  • Adds latency to every gh command
  • Shouldn't be necessary for something this fundamental

Prior Art

The implementation is trivial — a single check in ActiveUser() before falling back to the stored active user. A working PR already exists. This should be a priority for the multi-account experience.

Activity

  1. davidlovas commented on May 27, 2026

    @davidlovas
    Author

    Shell wrapper workaround

    For anyone who needs this today, here's what I'm using. Same concept as @jayproulx's wrapper in #12459 but uses the JSON output instead of grepping stderr:

    # ~/.zsh_aliases (or .bashrc, .zshrc, etc.)
    
    # gh CLI — auto-switch account based on git config github.account
    # Uses includeIf in ~/.gitconfig to set github.account per directory.
    # Workaround until this is implemented upstream.
    gh() {
        local target active
        target=$(git config github.account 2>/dev/null)
        if [[ -n "$target" ]]; then
            active=$(command gh auth status --active --json hosts -q '.hosts["github.com"][0].login' 2>/dev/null)
            if [[ "$target" != "$active" ]]; then
                command gh auth switch --user "$target" &>/dev/null
            fi
        fi
        command gh "$@"
    }

    Git config setup:

    # ~/.gitconfig
    [github]
        account = personal-username        # default
    [includeIf "gitdir:~/projects/work/"]
        path = ~/.gitconfig-work
    
    # ~/.gitconfig-work
    [github]
        account = work-username            # overrides default for repos under ~/projects/work/

    The default [github] section must come before the includeIf so conditional includes can override it (git config is last-wins).

    Works, but mutates global auth state on every invocation — not safe across concurrent terminal sessions. Native support would fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions