From 7684f6bd12c6285e623cc8be8ea7eab047f84248 Mon Sep 17 00:00:00 2001 From: Evan Alter Date: Wed, 22 Jul 2026 18:12:03 -0500 Subject: [PATCH] Route git-https to the right GitHub account per org path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Xcode CLT system gitconfig hardwires the osxkeychain credential helper, which answers github.com HTTPS requests with whichever account last cached a credential. When that's the personal account, background tooling (Claude Code's plugin marketplace updater) clones private work repos as the wrong user, gets "repository not found", and tears down its cache. Fix mirrors the gh() wrapper's per-owner pinning for plain git: reset the helper list for github.com and pin usernames per org path (useHttpPath). A new ~/bin/git-credential-gh-user helper serves the pinned account's token straight from gh's keyring — gh's own helper only answers for the active account, so it can't do this — and remains the fallback for unpinned URLs. Tokens never touch disk; mac machine class only. Co-Authored-By: Claude Fable 5 --- bin/executable_git-credential-gh-user | 19 +++++++++++++++++++ dot_gitconfig.local.tmpl | 20 ++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 bin/executable_git-credential-gh-user diff --git a/bin/executable_git-credential-gh-user b/bin/executable_git-credential-gh-user new file mode 100644 index 00000000000..29ae5fa1561 --- /dev/null +++ b/bin/executable_git-credential-gh-user @@ -0,0 +1,19 @@ +#!/bin/sh +# git credential helper: serve the gh-keyring token for the username git +# asks for (pinned per URL via credential..username in gitconfig), +# regardless of which gh account is currently active. gh's own helper only +# answers for the active account, which is why this exists. Declines +# silently — no username pinned, gh missing, or account not logged in — +# so the next helper in the chain can answer. +[ "$1" = get ] || exit 0 + +user= +while IFS='=' read -r key value; do + [ "$key" = username ] && user=$value +done + +[ -n "$user" ] || exit 0 +command -v gh >/dev/null 2>&1 || exit 0 +token=$(gh auth token --user "$user" 2>/dev/null) || exit 0 +[ -n "$token" ] || exit 0 +printf 'username=%s\npassword=%s\n' "$user" "$token" diff --git a/dot_gitconfig.local.tmpl b/dot_gitconfig.local.tmpl index 7230e83f6d7..20a275df809 100644 --- a/dot_gitconfig.local.tmpl +++ b/dot_gitconfig.local.tmpl @@ -25,6 +25,26 @@ path = ~/.gitconfig-ica [commit] gpgsign = true + +# Route git-over-HTTPS to the right GitHub account (the gh() wrapper in +# ~/.functions, but for plain git). The Xcode CLT system gitconfig +# hardwires osxkeychain, which answers with whichever account last cached +# a credential — background tooling (e.g. Claude Code's plugin marketplace +# updater) then clones private work repos as the wrong user and gets +# "repository not found". Reset the helper list: git-credential-gh-user +# (~/bin) serves the pinned account's token straight from gh's keyring, +# and gh's own helper covers unpinned URLs with the active account. +[credential "https://github.com"] + helper = + helper = !$HOME/bin/git-credential-gh-user + helper = !gh auth git-credential + useHttpPath = true +[credential "https://github.com/icanalytica"] + username = icaevan +[credential "https://github.com/icarichie"] + username = icaevan +[credential "https://github.com/hadees"] + username = hadees {{- end }} {{- if eq .machineClass "wsl" }} [core]