How can I use GitPython along with specific SSH Keys?
The documentation isn't very thorough on that subject. The only thing I've tried so far is Repo(path)
.
How can I use GitPython along with specific SSH Keys?
The documentation isn't very thorough on that subject. The only thing I've tried so far is Repo(path)
.
Please note that all of the following will only work in GitPython v0.3.6 or newer.
You can use the GIT_SSH
environment variable to provide an executable to git which will call ssh
in its place. That way, you can use any kind of ssh key whenever git tries to connect.
This works either per call using a context manager ...
ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh')
with repo.git.custom_environment(GIT_SSH=ssh_executable):
repo.remotes.origin.fetch()
... or more persistently using the set_environment(...)
method of the Git
object of your repository:
old_env = repo.git.update_environment(GIT_SSH=ssh_executable)
# If needed, restore the old environment later
repo.git.update_environment(**old_env)
As you can set any amount of environment variables, you can use some to pass information along to your ssh-script to help it pick the desired ssh key for you.
More information about the becoming of this feature (new in GitPython v0.3.6) you will find in the respective issue.
with git_project.git.custom_environment(GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa [email protected]'): git_project.remotes.origin.push(git_project.heads.master)
. If I add the -T
option and execute from the command line, I logged in as expected. Formatting issue in my Python code? –
Stowers [email protected]
after an attempt without it also failed. Desperation trial & error, I guess. :-) –
Stowers [email protected]
. –
Lentissimo Following worked for me on gitpython==2.1.1
import os
from git import Repo
from git import Git
git_ssh_identity_file = os.path.expanduser('~/.ssh/id_rsa')
git_ssh_cmd = 'ssh -i %s' % git_ssh_identity_file
with Git().custom_environment(GIT_SSH_COMMAND=git_ssh_cmd):
Repo.clone_from('git@....', '/path', branch='my-branch')
with git.custom_environment(GIT_SSH_COMMAND=git_ssh_cmd):
... what is git ? There is no variable or import that defines git in your code snippet. –
Ordinarily clone_from
. Check my answer below for a working version. –
Prentiss os.path.expanduser(...)
returns a filename, a string. add
- no, GitPython just passed it as argument to git executable. –
Player clone_from
now has the keyword env
to pass the environment: Repo.clone_from(url, dst_path, branch=branch, env=dict(GIT_SSH_COMMAND=ssh_cmd)) –
Eastman I'm on GitPython==3.0.5 and the below worked for me.
from git import Repo
from git import Git
git_ssh_identity_file = os.path.join(os.getcwd(),'ssh_key.key')
git_ssh_cmd = 'ssh -i %s' % git_ssh_identity_file
Repo.clone_from(repo_url, os.path.join(os.getcwd(), repo_name),env=dict(GIT_SSH_COMMAND=git_ssh_cmd))
Using repo.git.custom_environment to set the GIT_SSH_COMMAND won't work for the clone_from function. Reference: https://github.com/gitpython-developers/GitPython/issues/339
Please note that all of the following will only work in GitPython v0.3.6 or newer.
You can use the GIT_SSH
environment variable to provide an executable to git which will call ssh
in its place. That way, you can use any kind of ssh key whenever git tries to connect.
This works either per call using a context manager ...
ssh_executable = os.path.join(rw_dir, 'my_ssh_executable.sh')
with repo.git.custom_environment(GIT_SSH=ssh_executable):
repo.remotes.origin.fetch()
... or more persistently using the set_environment(...)
method of the Git
object of your repository:
old_env = repo.git.update_environment(GIT_SSH=ssh_executable)
# If needed, restore the old environment later
repo.git.update_environment(**old_env)
As you can set any amount of environment variables, you can use some to pass information along to your ssh-script to help it pick the desired ssh key for you.
More information about the becoming of this feature (new in GitPython v0.3.6) you will find in the respective issue.
with git_project.git.custom_environment(GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa [email protected]'): git_project.remotes.origin.push(git_project.heads.master)
. If I add the -T
option and execute from the command line, I logged in as expected. Formatting issue in my Python code? –
Stowers [email protected]
after an attempt without it also failed. Desperation trial & error, I guess. :-) –
Stowers [email protected]
. –
Lentissimo In case of a clone_from
in GitPython, the answer by Vijay doesn't work. It sets the git ssh command in a new Git()
instance but then instantiates a separate Repo
call. What does work is using the env
argument of clone_from
, as I learned from here:
Repo.clone_from(url, repo_dir, env={"GIT_SSH_COMMAND": 'ssh -i /PATH/TO/KEY'})
I've found this to make things a bit more like the way git works in the shell by itself.
import os
from git import Git, Repo
global_git = Git()
global_git.update_environment(
**{ k: os.environ[k] for k in os.environ if k.startswith('SSH') }
)
It basically is copying the SSH environment variables to GitPython's "shadow" environment. It then uses the common SSH-AGENT authentication mechanisms so you don't have to worry about specifying exactly which key it is.
For a quicker alternative which carries probably a lot of cruft with it, but it works too:
import os
from git import Git
global_git = Git()
global_git.update_environment(**os.environ)
That mirrors your entire environment, more like the way a subshell works in bash.
Either way, any future call to create a repo or clone picks up the 'adjusted' environment and does the standard git authentication.
No shim scripts necessary.
With Windows be careful where you place the quotes. Say you have
git.Repo.clone_from(bb_url, working_dir, env={"GIT_SSH_COMMAND": git_ssh_cmd})
then this works:
git_ssh_cmd = f'ssh -p 6022 -i "C:\Users\mwb\.ssh\id_rsa_mock"'
but this does not:
git_ssh_cmd = f'ssh -p 6022 -i C:\Users\mwb\.ssh\id_rsa_mock'
Reason:
Here are the steps to clone gitlab repository using GitPython
Create SSH key in Gitlab
Run the following script after adding necessary details
from git import Repo
Repo.clone_from("gitlab_ssh_url",
"path_where_you_want_to_clone_repo",
env={"GIT_SSH_COMMAND": 'ssh -i path_to_ssh_private_key'})
"""
Example
Repo.clone_from("[email protected]:some_group/some_repo.git",
"empty_dir/some_repo",
env={"GIT_SSH_COMMAND": 'ssh -i /home/some_user/.ssh/id_rsa'})
"""
This is what the latest documentation says:
ssh_cmd = 'ssh -i id_deployment_key'
with repo.git.custom_environment(GIT_SSH_COMMAND=ssh_cmd):
repo.remotes.origin.fetch()
From: https://gitpython.readthedocs.io/en/stable/tutorial.html#handling-remotes
© 2022 - 2024 — McMap. All rights reserved.