How to tell git which private key to use?

702

268

ssh has the -i option to tell which private key file to use when authenticating:

-i identity_file

    Selects a file from which the identity (private key) for RSA or DSA authentication is read.  The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol version 2.  Identity files may also be specified on a per-host basis in the configuration file.  It is possible to have multiple -i options (and multiple identities specified in configuration files).

Is there a similar way to tell git which private key file to use on a system with multiple private keys in the ~/.ssh directory?

jrdioko

Posted 2011-01-12T18:20:31.147

Reputation: 8 205

3

See this question in StackOverflow as well.

– Flimm – 2015-05-08T09:46:13.603

Answers

720

In ~/.ssh/config, add:

host github.com
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github
 User git

If the config file is new, don't forget to do chmod 600 ~/.ssh/config

Now you can do git clone git@github.com:{ORG_NAME}/{REPO_NAME}.git

  • Where {ORG_NAME} is your GitHub user account (or organization account)'s GitHub URI name.
    • Note that there is a colon : after github.com instead of the slash / - as this is not a URI.
  • And {REPO_NAME} is your GitHub repo's URI name
  • For example, for the Linux kernel this would be git clone git@github.com:torvalds/linux.git).

NOTE: On Linux and macOS, verify that the permissions on your IdentityFile are 400. SSH will reject, in a not clearly explicit manner, SSH keys that are too readable. It will just look like a credential rejection. The solution, in this case, is:

chmod 400 ~/.ssh/id_rsa_github

shellholic

Posted 2011-01-12T18:20:31.147

Reputation: 8 177

1@Cliff Nop, in my manpage: "HostName: Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts." My ssh version is openssh-6.7p1. – Grissiom – 2015-01-07T02:17:14.887

1

@Grissiom That's exactly what it says. But you seem to understand the meaning backwards. Host (or Match) is required. To create a host nickname you place the nickname in the Host line and the real hostname in the HostName line. Examples: http://www.saltycrane.com/blog/2008/11/creating-remote-server-nicknames-sshconfig/

– Cliff – 2015-01-08T03:55:49.960

Why do you need to say github.com twice? – isomorphismes – 2015-11-13T03:50:17.150

13If the config file is new, don't forget to do chmod 600 ~/.ssh/config – elysch – 2016-03-15T23:02:22.787

User git perfact – Nullpointer – 2016-09-08T09:53:00.073

Note you might not need "username" in your git path. e.g. my user on our local gitlab with permission for our shared project is Alice, I'm logged onto Linux as Bob. I created the ssh keys as Bob and put the public key on gitlab associated with Alice. Now I can clone like this from Linux, logged in as Bob, without mentioning "Alice" anywhere, – lessthanideal – 2016-11-14T14:12:41.163

1@elysch Thanks, that is also very important. – dthor – 2016-12-16T22:08:44.467

OMG why wouldn't it just tell me that the rights are wrong... It said its wrong first (warned) and then I've changed it. It didn't tell me next time saying me just that permission is denied. – ivkremer – 2017-08-18T13:04:46.260

2

@ValentinKlinghammer the answer from @Flimm has the solution for this question. It is to use core.sshCommand git configuration. https://superuser.com/a/912281/162466

– VasyaNovikov – 2017-12-28T20:47:45.413

This worked for me - important to note that creating a directory inside .ssh and trying to organize keys inside directories would require to also change the permissions of that directory. – nuno – 2018-09-06T09:35:40.283

none worked for me...not sure why – Goddard – 2019-01-24T19:50:01.350

This forces git to use a specific key for an entire domain, which usually won't work. For example, if someone has a personal github account as well as a work account, this configuration will break one of them. – Cerin – 2019-08-22T20:09:25.423

136What if you need to connect to the same host with different keys? – Valentin Klinghammer – 2012-11-30T11:24:54.143

6

@Quelltextfabrik - you can add another section with a different Host: http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/

– Ben Challenor – 2012-12-04T14:17:21.007

I'm using this trick in my github-keygen tool that I built to manage SSH keys and settings for Github.

– dolmen – 2013-09-20T10:10:08.553

387

Environment variable GIT_SSH_COMMAND:

From Git version 2.3.0, you can use the environment variable GIT_SSH_COMMAND like this:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example

Note that -i can sometimes be overridden by your config file, in which case, you should give SSH an empty config file, like this:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example

Configuration core.sshCommand:

From Git version 2.10.0, you can configure this per repo or globally, so you don't have to set the environment variable any more!

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push

Flimm

Posted 2011-01-12T18:20:31.147

Reputation: 6 317

2I had to export the shell variable to an environment variable to make this work, i.e. export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example", then git clone example – Abdull – 2015-12-01T13:46:51.977

7@Abdull In Bash, doing the assignment on the same line as the command exports the environment variable for just that command. Try it: example=hello /usr/bin/env | grep example. – Flimm – 2016-01-08T09:50:04.257

3

things have become even better: as of Git 2.10, you can store the command in your Git configuration: http://stackoverflow.com/a/38474220/520162

– eckes – 2016-10-21T07:57:14.807

For me I had to remove the -F /dev/null i dont know why , otherwise it would tell me: git config core.sshCommand "ssh -i ~/.ssh/toptal_i nterview_3_rsa -f /dev/null" PS C:\Users\Mercurius\Desktop\timekeep> git push -u origin master ssh: Could not resolve hostname /dev/null: Name or service not known – Noitidart – 2017-03-06T23:55:35.110

2@Noitidart /dev/null is only a valid filename in UNIX-like operating systems, it doesn't work on Windows. – Flimm – 2017-03-07T08:19:16.307

Thanks very much @Flimm, so it is safe to do your command without the -F too? Also I don't understand in the second part, since 2.10.0 you mention we can configure it globally, but the second part only shows the local method no? – Noitidart – 2017-03-07T12:03:32.610

The core.sshCommand config setting was just the thing I needed, because it lets me use a certain key by default in most circumstances, but then specify a different key with a core.sshCommand in a repository/.git/config file for a specific repo. Thank you! – Pistos – 2017-03-17T15:01:14.947

1If you need multiple keys, the -i parameter can be repeated, and ssh will try each key in turn. git config core.sshcommand "ssh -i /path/to/keyA -i /path/to/keyB". This lets git use different keys with different remote hosts. – Mark – 2017-06-23T03:44:26.293

For git versions < 2.3, you can use GIT_SSH (see other answers). – luator – 2017-11-08T14:31:50.117

You saved my life! Been struggling with different work and private Github & Heroku credentials for hours!! – Sprachprofi – 2018-04-09T18:46:07.620

3

For me GIT_SSH_COMMAND didn't work until I used IdentitiesOnly, such as this command: GIT_SSH_COMMAND="ssh -i ~/.ssh/mysubdir/id_rsa -o 'IdentitiesOnly yes'" git push.

– Tyler Collier – 2018-10-07T07:13:28.493

This is the best answer. The use of the environment variable via export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_otherkey" is so handy and flexible. I don't like setting multiple github keys in configuration .ssh/config because I also have to alias the github url for example, github.com becomes github.com.smeagol just to differentiate and this alias URL becomes your git remote address. – typelogic – 2019-07-02T12:56:37.477

This is especially useful when debugging git ssh. I can add -vvv to increase verbose mode. – Ding-Yi Chen – 2019-11-26T08:07:52.520

Hi !! Do you know how to propagate this to a submodule? – Arka Prava Basu – 2019-12-27T13:00:51.870

122

There is no direct way to tell git which private key to use, because it relies on ssh for repository authentication. However, there are still a few ways to achieve your goal:

Option 1: ssh-agent

You can use ssh-agent to temporarily authorize your private key.

For example:

$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'

Option 2: GIT_SSH_COMMAND

Pass the ssh arguments by using the GIT_SSH_COMMAND environment variable (Git 2.3.0+).

For example:

$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
  git clone user@host

You can type this all on one line — ignore $ and leave out the \.

Option 3: GIT_SSH

Pass the ssh arguments by using the GIT_SSH environment variable to specify alternate ssh binary.

For example:

$ echo 'ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*' > ssh
$ chmod +x ssh
$ GIT_TRACE=1 GIT_SSH='./ssh' git clone user@host

Note: The above lines are shell (terminal) command lines which you should paste into your terminal. They will create a file named ssh, make it executable, and (indirectly) execute it.

Note: GIT_SSH is available since v0.99.4 (2005).

Option 4: ~/.ssh/config

Use the ~/.ssh/config file as suggested in other answers in order to specify the location of your private key, e.g.

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa

kenorb

Posted 2011-01-12T18:20:31.147

Reputation: 16 795

1

// , What if your identity in ssh-agent is forwarded, though, as in this question? http://superuser.com/questions/971732/how-do-i-undo-an-ssh-add-on-a-forwarded-identity-to-access-github

– Nathan Basanese – 2015-09-11T18:06:52.780

1I've allowed me to reformat this post: IMO this is by far the most comprehensive answer. In its original design, a quick scan suggested the post where describing a single complicated solution to the problem, so I missed it. – Alberto – 2016-01-21T10:01:13.157

3$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host' worked for me when nothing else would. Kudos. – Daniel Dewhurst – 2017-09-11T15:24:29.143

1I had to use ~/.ssh/config method, env vars didn't work for me... – Greg Dubicki – 2017-09-22T07:53:25.443

1GIT_SSH is available since v0.99.4 (August 2005), so basically since Git exists (April 2005). – Dominik – 2017-11-17T08:10:35.683

33

Write a script that calls ssh with the arguments you want, and put the filename of the script in $GIT_SSH. Or just put your configuration in ~/.ssh/config.

Ignacio Vazquez-Abrams

Posted 2011-01-12T18:20:31.147

Reputation: 100 516

1~/.ssh/config Is the way to go. – hek2mgl – 2015-05-08T13:56:50.150

I work on a machine (A) from which I git push to a server (B) that only accepts ssh key authentication. While my ~/.ssh/config setup on (A) works perfectly fine when I work directly on that machine, it does not when I login from some other location (C). Using $GIT_SSH and a script solved this problem. Thanks! – bsumirak – 2015-12-03T17:28:56.867

2Another explanation of how to do this. – Sithsu – 2014-05-12T19:44:13.973

22

Use custom host config in ~/.ssh/config, like this:

Host gitlab-as-thuc  
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa.thuc
    IdentitiesOnly yes

then use your custom hostname like this:

git remote add thuc git@gitlab-as-thuc:your-repo.git  

thucnguyen

Posted 2011-01-12T18:20:31.147

Reputation: 329

2This is the answer I was looking for, as I have separate GitHub accounts for home and work. I just had to set Host work.github.com HostName github.com IdentityFile ~/.ssh/work, and then replace "github.com" by "work.github.com" whenever I clone a work repository. It still connects to "github.com", but using a non-default key pair. – Mikkel – 2016-05-25T17:06:55.243

1

The URL for details ("http://itblog.study.land/...") doesn't work any more :(

– Carl Smotricz – 2017-09-15T08:10:08.163

@CarlSmotricz the original one was moved here: https://medium.com/@thucnc/how-to-specify-different-ssh-keys-for-git-push-for-a-given-domain-bef56639dc02

– thucnguyen – 2018-11-27T07:13:34.893

4FINALLY!!! This answer actually shows how you can utilize what you put in the ~/.ssh/config file. Every other answer misses how you can set the host when you add the origin, which automatically allows git to use the correct key file. THANK YOU!! – BrianVPS – 2018-12-04T15:17:41.740

1Nice, that was what I was looking :) – Lucas D'Avila – 2019-04-04T18:19:55.460

22

If you do not want to have to specify environment variables every time you run git, do not want another wrapper script, do not/can not run ssh-agent(1), nor want to download another package just for this, use the git-remote-ext(1) external transport:

$ git clone 'ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git'
Cloning into 'repository'
(...)
$ cd repository
$ git remote -v
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (fetch)
origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (push)

I consider this solution superior because:

  • It is repository/remote specific
  • Avoid wrapper script bloat
  • Do not need the SSH agent -- useful if you want unattended clones/push/pulls (e.g. in cron)
  • Definitely, no external tool needed

flaviovs

Posted 2011-01-12T18:20:31.147

Reputation: 349

// , Excellent solution. I wonder, though, if this would allow one to specify an identity passed through using agent forwarding. Most of my keys are not local to the servers I am using them on. I asked about this here: http://superuser.com/questions/971732/how-do-i-undo-an-ssh-add-on-a-forwarded-identity-to-access-github

– Nathan Basanese – 2015-09-11T18:09:45.533

The answer deals only with a way of specifying arbitrary command lines to be used as git repositories. IMHO, you should try to sort out your issue using ssh alone first (e.g. "ssh host" should connect using the right key). I will try to provide more info on your other question, though. – flaviovs – 2015-09-14T16:34:53.980

Re my last comment, for some reason I cannot comment in your other question -- and do not have a concrete answer. Well, you might want to checkout http://serverfault.com/questions/599560/use-a-specific-forwarded-key-from-ssh-agent and the answer from user kasperd.

– flaviovs – 2015-09-14T17:51:54.277

2This answer was exactly what I needed to force Chef's git resource to use repository-specific deployment keys to clone/fetch from private Github repositories.

The additional advantage of this method over the environment/script based ones is that since the key-path is encoded in the working-repo's config, it will use the same key on both initial clone and subsequent fetches/pushes. – Adam Franco – 2015-11-19T16:20:13.067

2WOW! This is just great, didn't know about this. Thanks for the answer, quite helpful as well in puppet environments, to prevent the extra hassle to manage .ssh/config etc. +1! – gf_ – 2016-06-10T18:36:25.760

Excellent answer! If you're using github, I made a quick guide about it: https://mattlebrun.com/use-different-git-ssh-key-per-project.html

– cr8ivecodesmith – 2016-09-15T03:11:30.413

1This solution does not work together with the --recursive flag. The submodules are not fetched using the specified key and therefor fails if they require auth. – Daniele Testa – 2016-12-21T16:05:36.610

1Each submodule is an entirely different repository, with their own set of remotes. They're glued together by Git for your convenience, but in no way remotes for a submodule are tied to the ones in the parent repository. I'm afraid that you must set the remote using the ext transport in each submodule for recursion in the parent to work. – flaviovs – 2016-12-22T19:10:21.570

2

If you encounter the following error fatal: transport 'ext' not allowed, you have to whitelist the ext protocol via the export GIT_ALLOW_PROTOCOL=ext. Basically, the git-remote-ext remote helper (which supports "ext::ssh example.com %S foo/repo" URLs) allows arbitrary command execution. This normally isn't ever a concern because user always sees and trusts the URL they pass to git. However git submodules, through the .gitmodules file, allow an attacker to request the client to fetch arbitrary git URLs. https://hackerone.com/reports/104465

– Gomino – 2018-05-13T17:21:08.610

What is "git.example.com"? How would you use this with github or bitbucket, neither of which have a git.* subdomain? – Cerin – 2018-08-03T16:32:22.773

1This doesn't work when trying it with bitbucket, git clone 'ext::ssh -i /home/myuser/.ssh/id_rsa_customkey git.bitbucket.org %S repo/project.git' => Permission denied (publickey). fatal: Could not read from remote repository. – Cerin – 2018-08-03T16:36:45.800

git.example.com is a placeholder host name. You must be able to ssh to the actual host for this to work, so I suggest you try ssh first using the specified key and get to the command line, double-check the actual path to the repository, and only then try to use the ext transport. – flaviovs – 2018-08-04T17:56:42.747

1This is probably a good way, but my Git tries my default GitHub user, which has another key (GitHub wants unique-per-user keys). How can I make it use another user for other repo? – Ondra Žižka – 2018-09-03T19:22:44.103

1@OndraŽižka, you can add -l USER to the ssh command line to log in as user USER. – flaviovs – 2018-09-04T21:44:58.173

17

After my struggle with $GIT_SSH I would like to share what worked for me.

Through my examples I will assume you have your private key located at/home/user/.ssh/jenkins

Error to avoid: GIT_SSH value includes options

$ export GIT_SSH="ssh -i /home/user/.ssh/jenkins"

or whatever similar will fails, as git will try to execute the value as a file. For that reason, you have to create a script.

Working example of $GIT_SSH script /home/user/gssh.sh

The script will be invoked as follows:

$ $GIT_SSH [username@]host [-p <port>] <command>

Sample script working could look like:

#!/bin/sh
ssh -i /home/user/.ssh/jenkins $*

Note the $* at the end, it is important part of it.

Even safer alternative, which would prevent any possible conflict with anything in your default config file (plus explicitly mentioning the port to use) would be:

#!/bin/sh
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*

Assuming the script is in /home/user/gssh.sh, you shall then:

$ export GIT_SSH=/home/user/gssh.sh

and all shall work.

Jan Vlcinsky

Posted 2011-01-12T18:20:31.147

Reputation: 451

Thanks. Just note: use "$@" instead of $* for pass-thru arguments, as the former behaves correctly when arguments contain whitespace. – Piotr Findeisen – 2016-03-31T07:39:56.237

@PiotrFindeisen Thanks for your note. However, I do not understand it completely - in zsh it helps me to keep strings with space in one piece, but in bash not. Can you tell me more or point to some explanation? I do not want to add some modification blindly. – Jan Vlcinsky – 2016-03-31T10:33:46.243

You should remove the first half of your answer. No one's interested in a solution that doesn't work, and it's wasted reading that obfuscates the correct answer at the bottom, which works wonderfully. – Cerin – 2018-08-03T16:47:04.027

@Cerin If you mean removing the "Error to avoid" I am going to keep it there. It shares common pitfall to avoid and it is very short. I am sure, someone would try optimizing the solution by providing all the things into variable (this happened to me), so I tried to shorten the path to success. – Jan Vlcinsky – 2018-08-04T20:14:39.440

7

You can just use ssh-ident instead of creating your own wrapper.

You can read more at: https://github.com/ccontavalli/ssh-ident

It loads ssh keys on demand when first needed, once, even with multiple login sessions, xterms or NFS shared homes.

With a tiny config file, it can automatically load different keys and keep them separated in different agents (for agent forwarding) depending on what you need to do.

rabexc

Posted 2011-01-12T18:20:31.147

Reputation: 191

6

I had a client that needed a separate github account. So I needed to use a separate key just for this one project.

My solution was to add this to my .zshrc / .bashrc:

alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git $@"

Whenever I want to use git for that project I replace "infogit" with git:

infogit commit -am "Some message" && infogit push

For me, it's easier to remember.

Michael Cole

Posted 2011-01-12T18:20:31.147

Reputation: 183

5

So I set the GIT_SSH env variable to $HOME/bin/git-ssh.

In order to support having my repo configuration dictate which ssh identity to use, my ~/bin/git-ssh file is this:

#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*

Then I have a global git config setting:

$ git config --global ssh.identity ~/.ssh/default_id_rsa

And within any git repository I can just set a local ssh.identity git config value:

$ git config --local ssh.identity ~/.ssh/any_other_id_rsa

Voila!

If you can have a different email address for each identity, it gets even simpler, because you can just name your keys after your email addresses and then have the git config's user.email drive the key selection in a ~/bin/git-ssh like this:

#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*

Brendan Baldwin

Posted 2011-01-12T18:20:31.147

Reputation: 51

3

My solution was this:

create a script:

#!/bin/bash
KEY=dafault_key_to_be_used
PORT=10022 #default port...
for i in $@;do
   case $i in
    --port=*)
        PORT="${i:7}";;
    --key=*)KEY="${i:6}";;
   esac
done
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/${KEY} -p ${PORT}"
echo Command: $GIT_SSH_COMMAND

then when you have to change the var run:

. ./thescript.sh [--port=] [--key=]

Don't forget the extra dot!! this makes the script set the environments vars!! --key and --port are optional.

Salsicha

Posted 2011-01-12T18:20:31.147

Reputation: 31

3

Generally, you want to use ~/.ssh/config for this. Simply pair server addresses with the keys you want to use for them as follows:

Host github.com
  IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
  IdentityFile ~/.ssh/id_rsa.heroku
Host *
  IdentityFile ~/.ssh/id_rsa

Host * denotes any server, so I use it to set ~/.ssh/id_rsa as the default key to use.

Zaz

Posted 2011-01-12T18:20:31.147

Reputation: 1 843

3

I build on @shellholic and this SO thread with a few teaks. I use GitHub as an example and assume that you have a private key in ~/.ssh/github (otherwise, see this SO thread) and that you added the public key to your GitHub profile (otherwise see GitHub's help).

If needed, create a new SSH config file at ~/.ssh/config and change permissions to 400

touch ~/.ssh/config
chmod 600 ~/.ssh/config

Add this to the ~/.ssh/config file:

Host github.com
    IdentityFile ~/.ssh/github
    IdentitiesOnly yes

If you already have a remote set up, you may want to delete it, otherwise you may still be prompted for username and password:

git remote rm origin

Then add a remote to the git repository, and notice the colon before the user name:

git remote add origin git@github.com:user_name/repo_name.git

And then git commands work normally, e.g.:

git push origin master
git pull origin 

@HeyWatchThis on this SO thread suggested adding IdentitiesOnly yes to prevent the SSH default behavior of sending the identity file matching the default filename for each protocol. See that thread for more information and references.

miguelmorin

Posted 2011-01-12T18:20:31.147

Reputation: 577

This was my mistake: "If you already have a remote set up...". Thanks a lot!!! – Allan Andrade – 2018-10-04T17:43:09.137

common mistake---this is the answer – Goddard – 2019-05-16T21:07:38.253

2

Just use ssh-agent and ssh-add commands.

# create an agent
ssh-agent

# add your default key
ssh-add ~/.ssh/id_rsa

# add your second key
ssh-add ~/.ssh/<your key name>

After executing the above commands, you can use both keys as same time. Just type

git clone git@github.com:<yourname>/<your-repo>.git

to clone your repository.

You need to execute the above command after you reboot your machine.

Jinmiao Luo

Posted 2011-01-12T18:20:31.147

Reputation: 21

Please explain the process including How can I create an agent – Srikrushna – 2019-04-06T20:20:00.283

1

While the question doesn't request it, I am including this answer for anyone else looking to solve the same problem just specifically for .

The gitlab solution

I tried using the approach, but even the git documentation recommends using ~/.ssh/config for anything more than the simple case. In my case I am pushing to a server - and I wanted to do so as a specific user - which is of course defined by the during and not the username git. Once implemented I simply perform the following:

~/myrepo> git mycommit -m "Important Stuff"
~/myrepo> git mypush
[proceed to enter passphrase for private key...]

Setup

Recall the location of your /myfolder/.ssh/my_gitlab_id_rsa in my case.

Add an entry in ~/.ssh/config:

Host gitlab-delegate
    HostName gitlab.mydomain.com
    User git
    IdentityFile /myfolder/.ssh/my_gitlab_id_rsa
    IdentitiesOnly yes

Add the in ~/.gitconfig:

mypush = "!f() { \
           path=$(git config --get remote.origin.url | cut -d':' -f2); \
           branch=$(git rev-parse --abbrev-ref HEAD); \
           git remote add gitlab_as_me git@gitlab-delegate:$path && \
           git push gitlab_as_me $branch && \
           git pull origin $branch; \
           git remote remove gitlab_as_me; \
         }; f"

As a bonus, I perform my commits on this same host as a specific user with this :

mycommit = "!f() { \
             git -c "user.name=myname" -c "user.email=myname@mysite.com" commit \"$@\"; \
           }; f"

Explanation

All of the above assumes the relevant remote is origin and the relevant branch is currently checked out. For reference I ran into several items that needed to be addressed:

  • The solution requires creating a new remote gitlab_as_me, and I didn't like seeing the extra remote hanging around in my log tree so I remove it when finished
  • In order to create the remote, there is a need to generate the remote's url on the fly - in the case of gitlab this was achieved with a simple bash
  • When performing a push to gitlab_as_me you need to be specific about what branch you are pushing
  • After performing the push your local origin pointer needs to be "updated" in order to match gitlab_as_me (the git pull origin $branch does this)

dtmland

Posted 2011-01-12T18:20:31.147

Reputation: 2 281

1

When you have multiple git account and you want different ssh key

You have to follow same step for generating the ssh key, but be sure you

ssh-keygen -t ed25519 -C "your-email-id@gmail.com" 

Enter the path you want to save(Ex: my-pc/Desktop/.ssh/ed25519)

Add the public key to your gitlab (How to adding ssh key to gitlab)

You have to new ssh identity using the below comand

ssh-add ~/my-pc/Desktop/.ssh/ed25519

Srikrushna

Posted 2011-01-12T18:20:31.147

Reputation: 111

(1) Are you quoting somebody or something? If so, please identify the source. If not, please don’t use quote formatting.  (2) What is “ed25519”? … … … … … … … … … … … Please do not respond in comments; [edit] your answer to make it clearer and more complete. – Scott – 2019-04-07T00:35:19.460

1

    # start :: how-to use different ssh identity files

    # create the company identity file
    ssh-keygen -t rsa -b 4096 -C "first.last@corp.com"
    # save private key to ~/.ssh/id_rsa.corp, 
    cat ~/.ssh/id_rsa.corp.pub # copy paste this string into your corp web ui security ssh keys

    # create your private identify file
    ssh-keygen -t rsa -b 4096 -C "me@gmail.com"
    # save private key to ~/.ssh/id_rsa.me, note the public key ~/.ssh/id_rsa.me.pub
    cat ~/.ssh/id_rsa.me.pub # copy paste this one into your githubs, private keys

    # clone company internal repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@git.in.corp.com:corp/project.git

    export git_msg="my commit msg with my corporate identity, explicitly provide author"
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@corp.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # clone public repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@github.com:acoolprojectowner/coolproject.git

    export git_msg="my commit msg with my personal identity, again author "
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@gmail.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.me -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push ; 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # stop :: how-to use different ssh identity files

Yordan Georgiev

Posted 2011-01-12T18:20:31.147

Reputation: 133

0

I'm using git version 2.16 and I don't need a single piece of script not even a config or modified commands.

  • Just copied my private key to .ssh/id_rsa
  • set permissions to 600

And git reads to key automatically. I doesn't ask anything and it doesn't throw an error. Just works fine.

akjprajapati

Posted 2011-01-12T18:20:31.147

Reputation: 29

1Did you notice that the question is about “a system with multiple private keys in the ~/.ssh directory”? – Scott – 2018-06-06T05:16:46.307

0

If you need to connect to the same host with different keys then you can achieve it by:

  1. Configure the ~/.ssh/config with different Hosts but same HostNames.
  2. Clone your repo using the appropriate host.

Example:

~/.ssh/config

Host work
 HostName bitbucket.org
 IdentityFile ~/.ssh/id_rsa_work
 User git

Host personal
 HostName bitbucket.org
 IdentityFile ~/.ssh/id_rsa_personal
 User git

Then instead cloning your repos like:

git clone git@bitbucket.org:username/my-work-project.git
git clone git@bitbucket.org:username/my-personal-project.git

you must do

git clone git@work:username/my-work-project.git
git clone git@personal:username/my-personal-project.git

Maistora

Posted 2011-01-12T18:20:31.147

Reputation: 103