How do people handle multiple git identities with github+ssh? Since you always log in as the `git` user, you can't reuse keys. I end up with an ~/.ssh/config like:<p><pre><code> Host github-client1
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa-client1
Host github-client2
Hostname github.com
User git
IdentityFile ~/.ssh/id_rsa-client2
</code></pre>
Then clone using `git clone git@github-client1:username/repo.git` Is there a better way?
I have the email address problem, but that's the only paramter that needs to vary. I use the simplest way of handling this, which is this in my .config/git/config:<p><pre><code> [user]
name = "My Name"
useConfigOnly = true
</code></pre>
Then, the first time you commit in each repo, you'll get an "Author Identity Unknown" message. Then just run `git config --local user.email hello@example.com` to set the config for that repo.
Beware that the trailing slash in the string after `gitdir` is significant! This string is a globbing pattern (it is not obvious at first sight, and seldom mentioned), and the trailing slash implies `**` [1].<p>So if you type "gitdir:~/work" instead of "gitdir:~/work/", you will lose some time wondering why your configuration is ignored.<p>[1]: <a href="https://git-scm.com/docs/git-config#_conditional_includes" rel="nofollow noreferrer">https://git-scm.com/docs/git-config#_conditional_includes</a>
I find one disadvantage of SSH key auth, in case of GitHub in particular, that SSH key grants access to all the repos independently on the organization, etc, which becomes a bigger problem when sharing the machine with other people.<p>One can set a password on the ssh key, but I still felt a bit paranoid about it. I found a way out with fine-grained personal access tokens which allow you to choose the repositories this token will have access to [1].<p>My setup consists of two ingredients:<p>1. GPG encrypted fine-grained PAT: `gpg -c --no-symkey-cache --pinentry-mode loopback my_name` ends up into `my_name.gpg` secret.<p>2. A git credential configuration which is generic across git repositories:<p><pre><code> [credential "https://oauth2@github.com"]
helper = "!f() { test \"$1\" = get && echo \"password=$(gpg -d --pinentry-mode loopback --no-symkey-cache $_GITHUB_TOKEN)\"; }; f"
</code></pre>
Now switching identities results into setting the env var `$_GITHUB_TOKEN` to the path to my gpg encrypted token, which will be decrypted by git on the fly. You can figure out a suitable way to alias this for yourself :)<p>And it only activates for git urls of the from "oauth2@github.com" which allows you to clone public repos without questions.<p>Another advantage is that you can share the same repo with other people, no need to maintain a copy.<p>Disadvantage is that you have to enter password each time you push/pull.<p>[1] <a href="https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/" rel="nofollow noreferrer">https://github.blog/2022-10-18-introducing-fine-grained-pers...</a>
I use conditional includes for this, but I also add a single letter describing which Git identity I'm currently using to my PS1 so that it appears before $ in my shell prompt. This prevents me from committing code with the wrong identity, in case I'm using a git checkout that's anywhere not covered by the conditional include rules.<p>I use Starship (<a href="https://starship.rs" rel="nofollow noreferrer">https://starship.rs</a>) to manage my prompt, and wrote a short script that only runs if I'm somewhere in a git repo, and if so finds my Git user's email and looks up the corresponding letter in an associative array declared in my ~/.config/starship-zsh/.zshenv:<p><pre><code> git_email=$(git config --get user.email | perl -pe 'chomp if eof')
letter=$STARSHIP_GIT_USERS[$git_email]
echo -n $letter
</code></pre>
It's installed like this:<p><pre><code> [custom.git_user]
command = "ZDOTDIR=~/.config/starship-zsh /path/to/the-script-above.sh" # set ZDOTDIR, makes zsh load the .zshenv file
when = "git rev-parse --git-dir >/dev/null 2>/dev/null" # only run if we're in a git repo
format = ' $output'
</code></pre>
The .zshenv file contains the STARSHIP_GIT_USERS variable and its values, with a `declare -A` since it's an associative array.
I've seen a similar trick on HN, with some basic bash aliases:<p><a href="https://news.ycombinator.com/item?id=25070300">https://news.ycombinator.com/item?id=25070300</a>
nixos solves private keys and tools switch easy.
for folders, i ended up with overlays.
just follow origin upstream remote locally so that http and file united.<p>i mean if remote is https github com slash dzmitry lahoda slash web3.nix<p>than local is /home/dz/github com slash dzmitry lahoda slash web3.nix<p>navigation is easy. forks easy. no project1 or client 1. just navigation overlay. same works for consumption of knowledge and learning.<p>one may do codespace with nix easy too or many local homes.<p>nix and path overlays is superior and easy to maintain.<p>nix makes remote, local, ci, codespace, user switch, depending on dlmany versions of same repo super easy.<p>even by unix idiots like me.<p>that not full schema so. there are tags and data properties (security, size, files count, uniquiness of copy).<p>so decide if store local or remo only, git and syncthing same time, torrent and syncthing, gdrive and git, keepass and syncthing, what devices, ipfs. any combo.<p>tags when overlays (forced hierarchy fail). when git forks, than many remotes with overlay following most active fork.<p>that approach partially fixes some of my mental issue i guess. oh, i want to install zfs to fix duplication.<p>hardware keys for security i use also. thesd days can mix same key, but held ssh, crypto, aws creds on same device.
I found this a few years ago at <a href="https://stackoverflow.com/questions/14754762/can-gitconfig-options-be-set-conditionally/59184292#59184292" rel="nofollow noreferrer">https://stackoverflow.com/questions/14754762/can-gitconfig-o...</a> and has been my preferred setup.
Check the following comment in previous discussion about git capabilities to manage multiple identities to commit, authenticate and sign based on directories or remote repository URL. <a href="https://news.ycombinator.com/item?id=36800853">https://news.ycombinator.com/item?id=36800853</a>
> This trick has simplified my project onboarding quite a bit. No more "You forgot to update your Email Address" requests from clients!<p>Does this happen in practice? Most commits on professional git repos that I work on are of the form <username>@users.noreply.github.com.
Related: my own project to handle SSH keys for GitHub:
<a href="https://github.com/dolmen/github-keygen">https://github.com/dolmen/github-keygen</a><p>The project might not look active, but that's because it just works. 12 years old now.
I use podman containers with lazydocker. <a href="https://github.com/jesseduffield/lazydocker">https://github.com/jesseduffield/lazydocker</a> That way my work is a bit more separated. Good tips.
I also want this, but on a folder level<p>I have a github.com folder with all the repos I cloned from GH but I always have to type git config user.name/email before committing. It's so annoying at this point.
Shameless plug of a tool I wrote for managing multiple git identities:<p><a href="https://github.com/cquintana92/git-switch-user">https://github.com/cquintana92/git-switch-user</a>
Recently I tried to work on two projects that required different git credentials for push/pull. I ended up using basic auth with HTTPS with one repo, and the other on SSH.
that conditional include is nice, didn't know about that.<p>i've been using direnv to set env vars, but i'll probably switch to the conditional include.