Open ncmans opened 4 years ago
Is there currently a way to work around this by removing the current authentication? I can't seem to find it.
Reinstalling seems to work, but it's very cumbersome.
@eXamadeus GitHub CLI currently has no mechanism for switching between multiple GitHub accounts and I don't really have a workaround to suggest for you at this moment, sorry.
The only approach I could imagine, but would not recommend to anyone, would be to authenticate with 1st account, save a copy of ~/.config/gh/hosts.yml
somewhere & delete the original file, authenticate again with the 2nd account, and now you can swap the ~/.config/gh/hosts.yml
file with the backup file when you need to switch accounts.
Since this solution involves using SSH for git protocol, make sure both configuration files include the git_protocol: ssh
line.
If we can add two entries or as many entries on every gh auth login
. It might become easier with something like this:
github.com:
user: aitchkhan
oauth_token: xxx
user: haroonKhan-10p
oauth_token: xxx
git_protocol: ssh
If the cli
can somehow sense which username the current repository is associated to. It would be easy to find the user in the hosts.yml and rest would be magic.
PS: I have not gone through the codebase. These are my assumptions.
Searched and landed here. This feature would help people with two or more accounts (personal/business/others) and use both of them every day (swapping the config file would be too much for them).
It's a bit hacky, but I solved this so that I could evaluate if I want to actually use this cli by using the token auth capabilities, putting this into my dotfiles.
alias gh_cli=$(which gh)
function gh() {
if [[ $(pwd) =~ {PATH_TO_PERSONAL_CODE} ]]; then
GITHUB_TOKEN=$PERSONAL_GH_CLI_TOKEN
else
GITHUB_TOKEN=$WORK_GH_CLI_TOKEN
fi
GITHUB_TOKEN=$GITHUB_TOKEN gh_cli $@
unset GITHUB_TOKEN
}
@fdm1 Which config file did you fill that in?
@fdm1 Which config file did you fill that in?
Just in my bash dotfiles
Now that #2179 has been merged, perhaps it will be less effort to implement this feature?
Would be nice to have something like how git
handles it:
~/.gitconfig
[includeIf "gitdir:~/dev/"]
path = ~/.gitconfig.personal
[includeIf "gitdir:~/workspace/"]
path = ~/.gitconfig.work
~/.gitconfig.work
[user]
name = example-work-user
email = example@example.com
Now that I think about it some more, can gh
infer which authed account to use from the current git config user.name
or email?
Since #2444 has been merged, as an alternative solution, set the environment variable GH_CONFIG_DIR
to different directories could allow multiple accounts.
I just implemented simple multi-account support based on the remote.origin.url
config property (of course GH_HOST is on board as well): #3278
So having hosts.yml as
github.com:
user: personal-account
oauth_token: personal-token
github.com/acme:
user: work-account
oauth_token: work-token
we use work credentials for all acme repositories and personal credentials for everything else.
~Unfortunately, gh cli uses global settings for "default" host, so I postponed the implementation of gh auth status
which uses several credentials at the same time.~ Implemented.
Maybe this is a workaround if u wanna use multi credentials for a specific command. such as pr view
/usr/local/pr2
#!/usr/bin/python3
import subprocess
import json
import os
import re
with open(os.path.expanduser('~/.pr-config.json')) as f:
configs = json.load(f)
command = 'gh pr view --web'
remote_url = subprocess.check_output(['git', 'config', '--get', 'remote.origin.url']).strip().decode()
for pattern, config in configs.items():
is_match = re.match(pattern, remote_url)
if is_match:
os.system(
f'GH_HOST={config["host"]} GH_ENTERPRISE_TOKEN={config["token"]} {command}'
)
break
~/.pr-config.json
{
"git@enterprise.com": {
"host": "enterprise.com",
"token": ""
},
"git@enterprise1.com": {
"host": "enterprise1.com",
"token": ""
}
}
I am able to have multiple accounts signed in and that is nice, but one thing that I am trying to do is when I am creating a repository I would like to select my account. Doing something like gh repo create my_name/repo_name
doesn't seem to work because one of my accounts is enterprise and one is public. Passing in my enterprise name like this causes HTTP 404: Not Found (https://api.github.com/users/my_enterprise_username)
when I am logged into both my personal and enterprise GitHub but trying to create a repo for my private Github. This is not like a first-logged into account gets priority, no matter the order in which I log into my GitHub accounts I will receive this error when trying to create a repo for my enterprise account. Is there a way to force gh repo create
to use the enterprise API instead of the public one? Right now I must log out of my personal account to create an enterprise repo unless I am doing something wrong.
I've created a bash wrapper script for gh
which makes it easier to do multiple accounts. Uses personal access tokens.
¡Hello!
After having read everything, I believe it'd be more robust not to second-guess anything, and mark the user to use via Git's own configuration mechanism.
From the original submission, the work config would be expanded to specify the username to use for the server in question:
# ~/work/gitconfig
[core]
sshCommand = "ssh -i ~/.ssh/work"
[gh "github.com"]
user = workuser
That way, we'd leverage the includeIf
mechanism that everybody is already using to customize Git to their needs; hosts.yml could just have an array of stanzas for the same (or different) servers.
$ git config --get gh.github.com.user
workuser
(The hosts.yml format would have to be adjusted to be able to take multiple user stanzas, of course. A bit, but not quite, like https://github.com/cli/cli/issues/326#issuecomment-694676958.)
Edited to add: sadly, it would not work for things like gh repo clone
, because all includeIf directives only when already in a repo.
Replying now to https://github.com/cli/cli/issues/326#issuecomment-745597925:
Now that I think about it some more, can
gh
infer which authed account to use from the currentgit config user.name
or email?
I'm not sure that's a viable approach, since some users may not alter user.*
variables (see the original submission where only sshCommand
is changed).
I strongly recommend using direnv in conjunction with GH_CONFIG_DIR
to use multiple accounts.
This is by far the easiest solution. If you don't like/cannot use direnv, you can still manually prefix GH_CONFIG_DIR
. Shell wrappers above are clever, but this gets the job done just fine. @lucatpa Thanks for sharing!
I strongly recommend using direnv in conjunction with GH_CONFIG_DIR to use multiple accounts.
Similar to @lucatpa I use a tool to manage my GH_CONFIG_DIR
but I use OnDir instead. The advantage of this is that I don't have to setup multiple .envrc
files in each repo
So I have this setup in my .config/gh
folder
├── config.yml
├── org1
│ └── hosts.yml
└── org2
└── hosts.yml
and I have this setup in my ~/.ondirrc
config file
enter ~/source/org1/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org1"
leave ~/source/org1/([^/]+)
unset GH_CONFIG_DIR
enter ~/source/org2/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org2"
leave ~/source/org2/([^/]+)
unset GH_CONFIG_DIR
HTH
(Just to make it super clear, all my code is in /Users/username/source/
في خميس، 10 يونيو، 2021 في 11:01 ص، كتب Think Stack Limited < @.***>:
Similar to @lucatpa https://github.com/lucatpa I use a tool to manage my GH_CONFIG_DIR but I use OnDir https://github.com/alecthomas/ondir instead So I have this setup in my .config/gh folder
├── config.yml
├── org1
│ └── hosts.yml
└── org2
└── hosts.yml
and I have this setup in my ~/.ondirrc config file
enter ~/source/org1/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org1"
leave ~/source/org1/([^/]+)
unset GH_CONFIG_DIR
enter ~/source/org2/([^/]+)
export GH_CONFIG_DIR="/Users/username/.config/gh/org2"
leave ~/source/org2/([^/]+)
unset GH_CONFIG_DIR
HTH
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/cli/cli/issues/326#issuecomment-858404368, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOW7T7BNNBFFEE4FJEHFXCLTSBWO5ANCNFSM4KRIJKRA .
-- reda
Shingle.org.com
What about using git credential fill
to get the creds and delegate it all to git-credential-helpers? If gh
did this, it would work perfectly for my use case (two GitHub accounts with git already set up to use the right creds for various repos depending on repo org/user). It also means that gh
does not need to store tokens in plaintext on the filesystem.
I want to share my little approach that I build after reading this issue here some time ago, it does just link the hosts.yml
config to user-specific hosts-username.yml
files (which you need to create first), depending on a git repo setting (that you have to config).
However, it makes it possible to use use specific gh for specific Github users that you setup per local repo.
https://gist.github.com/ezzra/ec5a575a6cab368179bbd6a95e6f7fe6
(using git credential fill
might be worth to use here, I didn't know about this when I created my workaround)
Just linking to git credential
for easy ref.
[1] https://git-scm.com/docs/git-credential/2.35.0
[2] https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage
seriously? 2 years and github still won't listen to such an obvious feature?
@tr4g please be kind. i know it's frustrating, but there's so much work that can be done, not everything will get done. I personally want to take a crack at this, using git credential
, but time keeps ticking.
For what it's worth, I have a switchhub
script that symlinks a -<username>
file to the main config file for hub
and gh
. It's a little manual, but eases the pain a bit for now. Attached.
switchhub.txt (renamed to .txt to be able to attach)
@camh- What does caller
do here?
@eabase the last line of the script is the same as
# Only run main if executed as a script and not "sourced".
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then main "$@"; fi
I've been doing this a long time before ${BASH_SOURCE}
worked for this and caller
was the only way I found to do it. It is just inspecting the function call stack. I should update my script template.
This is a terrible Dev experience. Someone please fix this.
Too bad this did not work something like Kubectx. Just run a Kubectx command (which is pointed at all the Kube certs you have), and select which Kube cluster you want to work with. Made my life soo much easier!
https://github.com/ahmetb/kubectx
Not hating on the devs, just though I would chime in, Keep up the good work devs!
I strongly recommend using direnv in conjunction with
GH_CONFIG_DIR
to use multiple accounts.
I have never head of direnv...you have started a new rabbithole and have saved me so much work...Thank you!
I have never head of direnv...you have started a new rabbithole and have saved me so much work...Thank you!
@j33pguy if you are down a rabbithole, you might as well try ondir 😁
Similar to @lucatpa I use a tool to manage my
GH_CONFIG_DIR
but I use OnDir instead. The advantage of this is that I don't have to setup multiple.envrc
files in each repo
Until multiple accounts are not implemented in gh
, I've ended up with such aliases to switch between regular GitHub and Company's GitHub (thank God gh
supports aliases 😝): https://gist.github.com/yermulnik/017837c01879ed3c7489cc7cf749ae47
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
[includeIf` "gitdir:~/work/"]
path = ~/work/.gitconfig
@thinkstack
I haven't used any of those, but seems like direnv
supports exactly the same thing (print from their docs below), by searching parent folders for a .envrc
(or .env
) file.
So I guess you don't really need to put one file per directory if you organize your directories appropriately.
@yermulnik
Thanks! That's a very lightweight alternative if we don't want to install anything else.
How do you folks manage your credentials with those solutions?
1618365730
@marcelocra
How do you folks manage your credentials with those solutions?
Not sure this is what you're asking but I use 1password and chezmoi.
direnv
sets GH_CONFIG_DIR
, for example to ~/.config/gh/work
~/.config/gh/work/hosts.yml
looks like this:github.com:
user: leon-work
oauth_token: {{ (onepasswordItemFields "2qaegfeuivaudgbx5zmdjtcjeu").credential.v }}
git_protocol: ssh
Somewhat related: today I attempted to use gh pr create
and was rebuffed because the GITHUB_TOKEN
in my env was a token with very limited permissions. I'm using said token to authenticate with a GH package registry, so it has read-only permissions. It's loaded into my env by direnv. gh
preferred the GITHUB_TOKEN
env var over its other auth method. It would be useful to have a mechanism to ignore the environment variables. Or specify preferred ordering of auth method, i.e. first: try token negotiated with gh auth
; then: try GITHUB_TOKEN
etc.
Until this is officially supported, I have created a simple gh extension to manage multiple profiles. Check it out at gabe565/gh-profile.
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:[includeIf "gitdir:~/work/"] path = ~/work/.gitconfig
and in
~/work/.gitconfig
:[core] sshCommand = "ssh -i ~/.ssh/work"
It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
- Allow overriding
gh
config by a file in a local clone's.git
directory- Allow defining rules in the
gh
config which defines which repos/orgs should use which credential. E.g.github.com/google: - user: gemployee oauth_token: ... github.com/microsoft: - user: msemployee oauth_token: ... github.com: - user: personal oauth_token: ...
How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.
Duplicate of #
@eXamadeus GitHub CLI currently has no mechanism for switching between multiple GitHub accounts and I don't really have a workaround to suggest for you at this moment, sorry.
The only approach I could imagine, but would not recommend to anyone, would be to authenticate with 1st account, save a copy of
~/.config/gh/hosts.yml
somewhere & delete the original file, authenticate again with the 2nd account, and now you can swap the~/.config/gh/hosts.yml
file with the backup file when you need to switch accounts.Since this solution involves using SSH for git protocol, make sure both configuration files include the
git_protocol: ssh
line.
Since we can use GH_CONFIG_DIR
to specify different gh
config dir, I use direnv
to set that env var for different projects.
After logging in with gh auth login
, I copy .config/gh
to my project dir, then use direnv
to set GH_CONFIG_DIR
to that location.
Since we can use
GH_CONFIG_DIR
to specify differentgh
config dir, I usedirenv
to set that env var for different projects.After logging in with
gh auth login
, I copy.config/gh
to my project dir, then usedirenv
to setGH_CONFIG_DIR
to that location.
I did this too for a while! My gh extension actually takes advantage of direnv, but it sets up the .envrc
file for you 😊
Here to add that this is a much desired feature please. constant nightmare switching accounts
Would also love to see a purpose-built solution added to the CLI please 🙏
@leonhfr was playing around with this today along with the 1Password CLI op
. This seems to have worked for me:
gh auth setup-git
to get the helpers structure written to ~/.gitconfig
~/.gitconfig
so the helpers point instead at op
as follows: helper = !op plugin run -- gh auth git-credential
The current gh CLI command in item 1 above writes absolute paths to the gh
binary without considering aliases that op
adds.
Not sure what all the fuss is about. I got this to work fairly easily after purchasing a new computer for each Github account I have. Never had a problem since...
The issue is opened for a long time and still there is no native resolution. Maybe gh cli extension could be handy, here is one that I found https://github.com/gabe565/gh-profile.
Probably a gh cli extension that updates symlinks for the configuration files is easy to achieve. E.g.
There are many ways to solve it, but I would love to see a native support without any wrappers.
Since no one has brought it up, I would like to bring up the approach Gitlab's cli, glab
, took to allow multiple accounts. I don't know if their approach was designed for this, but I found that it works very nicely with way I have already configured ssh.
glab
allows you to define an api_host
for each host you use. The api_host
is simply the hostname of the Gitlab instance glab
communicates with. The hostname is only used to for git communication. So if you set the git_protocol as ssh, ssh is what resolves the specified hostname to the correct hostname. The following configuration might clarify what I mean.
glab-cli/config.yml
:
hosts:
work.gitlab.com:
api_host: gitlab.com
user: <work user>
token: <work_token>
git_protocol: ssh
personal.gitlab.com:
api_host: gitlab.com
user: <personal user>
token: <personal_token>
git_protocol: ssh
.ssh/config
:
Host personal.gitlab*
IdentityFile ~/.ssh/ed25519_personal
Host work.gitlab*
IdentityFile ~/.ssh/ed25519_work
Host *gitlab*
Hostname gitlab.com
User git
IdentitiesOnly yes
In your work projects you would set the remote url as:
git@work.gitlab.com:Work/work_project.git
And in your personal projects you would set the remote url as:
git@personal.gitlab.com:Persnoal/personal_project.git
If you want to define a default user for gitlab, you would then simply have to add gitlab.com
as a host into both
.ssh/config
and hosts.yml
.
As you can see, when glab
and ssh
see the domain name personal.gitlab.com
, they communicate with gitlab.com
, but they have correctly setup the authentication for the personal
user. I think gh
would benefit from implementing such a separation between the api hostname and the specified hostname.
As a bonus, if you don't want to type git@personal.gitlab.com
everytime you set a remote url and instead prefer persnoal@github.com
, add the following lines to your git/config
[url "git@personal.gitlab.com"]
insteadOf = personal@gitlab.com
This way git
auto expands the url personal@gitlab.com
to git@personal.github.com
.
Describe the feature or problem you’d like to solve
I have two accounts on github each with access to a different set of private repositories. Currently I use a combination of git's
[IncludeIf ...]
config and a custom config which overrides the SSH private key I use for certain repositories. E.g.:In
~/.gitconfig
:and in
~/work/.gitconfig
:It will be great if the credentials for
gh
can also be configured per repository as well.Proposed solution
There are a bunch of options I can think of:
gh
config by a file in a local clone's.git
directorygh
config which defines which repos/orgs should use which credential. E.g.How will it benefit CLI and its users?
It will allow Github users with multiple accounts of varying access to seamlessly work on different repositories.