Hub: Support per-repo GitHub account configuration

Created on 10 Oct 2016  ·  15Comments  ·  Source: github/hub

I've just started using hub.
As a first step I wanted to open the github webpage with git browse. hub insists that I have to enter my account which I do not see why I have to do this right now.

My motivation might seem a little bit odd:
I configure for each repository I am actually working on explicitly my name and email address. I do not like to have an enforced global setting. git-2.8 (March 2016) has added an option useConfigOnly which means if it is not set globally or locally it does not guess anymore and insists that the user has to configure it before committing. However, I only do this if I actually I want to do something in the repository. Simply opening the github webpage does not mean this necessarily.

config feature

Most helpful comment

I'm not sure if others are looking for anything similar, but I thought I would share here as this issue is most relevant I feel.

My use case: distinguish between work and personal GitHub accounts for hub config

Workaround: use $HUB_CONFIG and direnv

I moved my work Github repos into a work directory and my personal GitHub repos into a play directory where those two directories each provide a .envrc file (~/work/.envrc and ~/play/.envrc, respectively).

direnv will search for the .envrc file, which include HUB_CONFIG environment variable (export HUB_CONFIG=~/.config/hub-work and export HUB_CONFIG=~/.config/hub-personal, respectively), and my hub config contain a different oauth_token for each account.

direnv is smart enough to unload the environment variables when out of those directories as well as to load the environment variables in sub-directories.

All 15 comments

Hi, thanks for writing in with a good question.

Some time ago, hub managed to pull off a lot of operations such as browse, clone, and others without ever needing your authentication info for GitHub. However, as it evolved and was expanded to handle more scenarios, such as renamed repos and detecting your own fork among git remotes, more and more commands over time required access to the GitHub API (or at least knowing your GitHub username).

Now, when it comes to browse, the command only needs your username in two scenarios. First, if you do hub browse dotfiles, it will take you to kiryph/dotfiles repo. Second, if you're browsing the currently checked out branch which is not master, browse will try to detect which is your fork, in case the branch is pushed there.

Chances are, neither of these cases apply to your usage. Therefore, theoretically we could change code in hub to only ask for credentials until absolutely necessary. But, I'm not convinced that it's worth my time to make the change. Most features of hub will need access to GitHub API, and therefore it doesn't make sense to try using hub for too many operations without giving it your credentials. You simply won't get much done with it.

If browsing repos is the only operation you meant to use hub for, and you're reluctant to give it your credentials, maybe you could skip hub and have a simple shell script that opens the homepage for a repo? Let me know if this makes sense.

Thanks for your detailed answer. Yes, it makes sense to me. I was already suspecting that the user credentials are something often used and therefore queried very early in the hub program.

For the simple task of opening only the github url one can use following bash script https://github.com/paulirish/git-open.

However, I might end up actually using hub and both commands seem to totally overlap. Therefore I do not want to install both.

I have a second question: https://hub.github.com/hub.1.html#CONFIGURATION says that the OAuth token is stored to "~/.config/hub". Is it possible to store it per git repo to use different github accounts?

Sorry, someone already has asked this: #1259

Is it possible to store it per git repo to use different github accounts?

It could be possible to make that in code, but it would lead to poor user experience since the user would be resposible to configure auth credentials for each repo, and if they forgot to do that, they would be prompted for credentials each time.

I think your best resort is to use the environment variables.

Yes, this is actually what I want: being queried for each repository explicitly. As I said git supports this since version 2.8 for the git username and email address.

Because I use several accounts/usernames, I can easily forget it to set it to the correct one. After having pushed something with the wrong name you cannot amend and change this anymore. That's the reason I do not mind the inconvenience the first time I work with a new repo.

In the case of hub, I could picture following enhanced user experience:
A user can add several OAuth tokens to ~/.config/hub (to avoid your raised argument in #1259 that someone pushes it by accident to github). When the user runs for the first time a hub command hub could simply offer a list of available options. Something like this:

$ hub browse
Which account do you want to use?
> (1) kiryph
> (0) Add a new account
Enter the number in parenthesis to make a choice [default=1]:

Multiple accounts _might_ be a feature in a future version of hub, after we sort out multiple GitHub hosts (GitHub Enterprise support already exists but it can be awkward to set up). But, I can't promise that will come soon, since it's not a priority for me. Very few people have multiple GitHub.com accounts, and those that do I consider power users, and they have the option of having dynamically configured GITHUB_TOKEN as described in my hint at https://github.com/github/hub/issues/1259#issuecomment-249947507. Do you think that could be an acceptable workaround for you right now?

I can imagine that this feature is possibly not used by the majority of the users. BTW, I consider everyone who is using hub a power user in contrast to people who are using the webpage and GUI tools. The reason for several accounts is that I use github for different things which I do not want to mix. It is similar to why people have a work email address and a private email address. I am sure that you understand that there a good reasons to do this without being an actual power user.

Regarding the environment variable GITHUB_TOKEN
Honestly, I do not like the workaround. As you say it is a workaround and it feels this way. When I take the effort to annoy :innocent: someone on the web, I usually try to do it only if there is a slight chance of improving something without relying on workarounds. No offense intended.

I totally understand that adding this is not a simple change to hub as it would be making commands which do not need the credentials working without them. That's too bad. But I certainly appreciate that there is hub after all and I am thankful for your support and discussion.

I usually try to do it only if there is a slight chance of improving something without relying on workarounds. No offense intended.

Sure, and I think your suggestion for multi-account support is completely spot-on. I could totally see that implemented in the future, after the items in this roadmap: #1232

However, I don't like the UI that you suggester for it. If you configured ~/.config/hub with multiple accounts, I wouldn't want to see “Which account do you want to use?” prompt on every hub operation on the command-line. Instead, I would want one account to be the default, with the possibility of changing to another account via either a global --user flag, or an environment variable. How does that UI sound?

Or, actually, I just realized that you would consistently want to use a single account for a specific repository. Then we could go back to your original suggestion and support some kind of hub.user <USERNAME> key in local git config, assuming that USERNAME was previously configured in ~/.config/hub.

Yes, that's right. I want to use consistently one account for one repo. The way you describe it does sound how I would do it:

Adding an entry to <repo>/.git/config hub.user = <USERNAME> which points to the correct token in ~/.config/hub.

Okay, I'm renaming this issue then with a more descriptive title and keeping it open as a feature request. Thanks for the discussion!

In the meantime, I still suggest that you make a wrapper script for hub (like I suggested in a linked comment) that reads git config hub.user and sets GITHUB_TOKEN appropriately before invoking hub. This will solve your problem while you wait for hub to natively support this.

Thank you for adding this as feature issue. And giving me the feeling of a valued user :smiley:.

A new feature of git 2.13 introduces conditional includes, which means you can have conditional configurations for git, but kept at the system level (so they don't need duplicated between each repo). https://git-scm.com/docs/git-config#_conditional_includes

If I understood this thread correctly, I'll assume the scenario is with a personal github account and perhaps a company github enterprise account.

With the new git feature, you can tell get (in your global config) to include a file iff the current path matches "my-company". So you'd clone all of your github enterpise repos into ~/code/my-company/<all_the_repos>. Then the conditional include would be:

[includeIf "gitdir:my-company/"]
    path = /path/to/my-company.gitconfig

Then in /path/to/my-company.gitconfig, you'd have:

[user]
  email = [email protected]
[hub]
  host = github.my-company.org

This feature would allow hub to just rely on getting the hub user from git-config (which could then be configured conditionally based on the repo path using the conditional includes).

I'm not sure if others are looking for anything similar, but I thought I would share here as this issue is most relevant I feel.

My use case: distinguish between work and personal GitHub accounts for hub config

Workaround: use $HUB_CONFIG and direnv

I moved my work Github repos into a work directory and my personal GitHub repos into a play directory where those two directories each provide a .envrc file (~/work/.envrc and ~/play/.envrc, respectively).

direnv will search for the .envrc file, which include HUB_CONFIG environment variable (export HUB_CONFIG=~/.config/hub-work and export HUB_CONFIG=~/.config/hub-personal, respectively), and my hub config contain a different oauth_token for each account.

direnv is smart enough to unload the environment variables when out of those directories as well as to load the environment variables in sub-directories.

@isaacaggrey Thanks for sharing this clever workaround!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jfritzbarnes picture jfritzbarnes  ·  3Comments

stsewd picture stsewd  ·  4Comments

dsifford picture dsifford  ·  4Comments

kentcdodds picture kentcdodds  ·  4Comments

technosophos picture technosophos  ·  3Comments