I'm using GitPython but did not find a way to push to repo using username and password. Can anybody send me a working example or give me some pointer about how to do it? What I need to do is: add a file to the repository, push it using the username and password provided.
4 Answers
What worked well for me (worked with GitHub, self hosted BitBucket, most likely will work on GitLab too).
Pre-requisites
Note, that despite the name, password
here is your access token generated by GitHub and NOT your GitHub password.
from git import Repo
full_local_path = "/path/to/repo/"
username = "your-username"
password = "your-password"
remote = f"https://{username}:{password}@github.com/some-account/some-repo.git"
Clone repository
This will store your credentials in .git/config
, you won't need them later.
Repo.clone_from(remote, full_local_path)
Commit changes
repo = Repo(full_local_path)
repo.git.add("rel/path/to/dir/with/changes/")
repo.index.commit("Some commit message")
Push changes
As mentioned above, you don't need your credentials, since they are already stored in .git/config
.
repo = Repo(full_local_path)
origin = repo.remote(name="origin")
origin.push()

- 12,746
- 4
- 52
- 44
-
I think this is no longer available since Github has disabled the password login. – David Hsu Jun 24 '22 at 07:11
-
@DavidHsu: See the notes in pre-requisites. It's not the password. And I can confirm, that this approach still works well (at least, until 3 hours ago, because I see automated commits in one of my repositories). – Artur Barseghyan Jun 24 '22 at 21:26
-
Yes, sorry about that, it works well on my testing code as well. After testing, the reason I got the token/password is not allowed error is because I add quotes ("xxxxx") on my token at the URL string, and after removing it, works fine. Thanks a lot. – David Hsu Jun 25 '22 at 04:27
-
How to do this for Azure Devops? How to change the remote variable accordingly? – user19930511 Jan 18 '23 at 22:48
-
I haven't worked with Azure closely. Do they have free repositories to try out for outsiders? – Artur Barseghyan Jan 18 '23 at 23:00
-
@ArturBarseghyan Thanks for this. I am using this code to push some changes to git. However, I am facing an issue as in, the code runs fine. But once I do `origin.push()` it gives me `[
]`. But I do not see anything in the remote repo. No updates or anything. Can you please suggest what I might be doing wrong? – trougc Aug 15 '23 at 16:42
This is what I used for myself for pulling
pull.py
#! /usr/bin/env python3
import git
import os
from getpass import getpass
project_dir = os.path.dirname(os.path.abspath(__file__))
os.environ['GIT_ASKPASS'] = os.path.join(project_dir, 'askpass.py')
os.environ['GIT_USERNAME'] = username
os.environ['GIT_PASSWORD'] = getpass()
g = git.cmd.Git('/path/to/some/local/repo')
g.pull()
askpass.py (similar to this one)
This is in the same directory as pull.py
and is not limited to Github only.
#!/usr/bin/env python3
#
# Short & sweet script for use with git clone and fetch credentials.
# Requires GIT_USERNAME and GIT_PASSWORD environment variables,
# intended to be called by Git via GIT_ASKPASS.
#
from sys import argv
from os import environ
if 'username' in argv[1].lower():
print(environ['GIT_USERNAME'])
exit()
if 'password' in argv[1].lower():
print(environ['GIT_PASSWORD'])
exit()
exit(1)
-
Please see this answer to a similar question, it seems this is not the proper way to use GitPython because "if you want to parse the output, you end up looking at the result of a 'porcelain' command, which is a bad idea": https://stackoverflow.com/a/53111508/5242366 – Simon TheChain Feb 24 '21 at 22:56
Clone Private Repos Using Git Module with Username and Password
Below script uses the git
module to perform the cloning of private repositories from GitLab using HTTPS and save them in a folder with the name provided in the CSV file.
The script uses two options -u
or --username
and -p
or --password
which can be used to provide GitLab username and password.
It will clone the repositories and save them in a folder with the name provided in the CSV file.
Below is example of CSV. | Name | URL | | -------- | -------------- | | Example-Demo| github.com/example/api-repo|
Save below code in script.py
#!/usr/bin/python
import csv
import argparse
import os
from git import Repo
import urllib.parse
# Create the parser
parser = argparse.ArgumentParser(description='Clone private repositories')
# Add the arguments
parser.add_argument('csv_file', help='The CSV file containing the repository information')
parser.add_argument('local_dir', help='The local directory to clone the repositories into')
parser.add_argument('-u', '--username', help='GitLab username')
parser.add_argument('-p', '--password', help='GitLab password')
# Parse the arguments
args = parser.parse_args()
# Open the CSV file
with open(args.csv_file, newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
# Extract the repository name and URL from the CSV file
repo_name = row['Name']
repo_url = row['URL']
repo_url_added = f"https://"+args.username+":"+urllib.parse.quote(args.password, safe='')+"@"+repo_url
# Create the local directory using the repository name
repo_folder = os.path.join(args.local_dir, repo_name)
if not os.path.exists(repo_folder):
os.makedirs(repo_folder)
# Clone the repository using the git python module and
print("Clonning: "+repo_name+" From: "+repo_url)
repo = Repo.clone_from(repo_url_added, repo_folder,env={"GIT_HTTP_USERNAME": args.username, "GIT_HTTP_PASSWORD": args.password})
For script execution, use the following command.
python script.py -u touhid -p password repositories.csv /path/to/local/directory

- 128
- 1
- 1
- 8

- 91
- 1
- 4
-
I used a similar aproach, however if the password or token contain a slash, it will fail. We could add the parameter `safe=''` to replace the default value `safe='/'` It would also be better to encode the username. – Julio.G May 10 '23 at 15:01
I found this working solution:
- create a script like this: ask_pass.py
- before to execute push assign the environment vars:
os.environment['GIT_ASKPASS']= <full path to your script> os.environment['GIT_USERNAME'] = <committer username> os.environment['GIT_PASSWORD'] = <the password>
and anything works fine.

- 3,034
- 3
- 32
- 49